ca8bc1a28ad44447ad09c31614cd5f397569fed7
1 from nmigen
.compat
.sim
import run_simulation
2 from nmigen
.cli
import verilog
, rtlil
3 from nmigen
import Module
, Signal
, Elaboratable
4 from nmutil
.latch
import SRLatch
5 from nmigen
.lib
.coding
import Decoder
8 class IntFnUnit(Elaboratable
):
9 """ implements 11.4.8 integer function unit, p31
13 * req_rel_i (request release) is the direct equivalent of pipeline
16 def __init__(self
, wid
):
20 self
.dest_i
= Signal(wid
, reset_less
=True) # Dest in (top)
21 self
.src1_i
= Signal(wid
, reset_less
=True) # oper1 in (top)
22 self
.src2_i
= Signal(wid
, reset_less
=True) # oper2 in (top)
23 self
.issue_i
= Signal(reset_less
=True) # Issue in (top)
25 self
.go_write_i
= Signal(reset_less
=True) # Go Write in (left)
26 self
.go_read_i
= Signal(reset_less
=True) # Go Read in (left)
27 self
.req_rel_i
= Signal(wid
, reset_less
=True) # request release (left)
29 self
.g_rd_pend_i
= Signal(wid
, reset_less
=True) # global rd (right)
30 self
.g_wr_pend_i
= Signal(wid
, reset_less
=True) # global wr (right)
33 self
.readable_o
= Signal(reset_less
=True) # Readable out (right)
34 self
.writable_o
= Signal(reset_less
=True) # Writable out (right)
36 self
.rd_pend_o
= Signal(wid
, reset_less
=True) # rd pending (right)
37 self
.wr_pend_o
= Signal(wid
, reset_less
=True) # wr pending (right)
39 def elaborate(self
, platform
):
41 m
.submodules
.rd_l
= rd_l
= SRLatch(sync
=False)
42 m
.submodules
.wr_l
= wr_l
= SRLatch(sync
=False)
43 m
.submodules
.dest_d
= dest_d
= Decoder(self
.reg_width
)
44 m
.submodules
.src1_d
= src1_d
= Decoder(self
.reg_width
)
45 m
.submodules
.src2_d
= src2_d
= Decoder(self
.reg_width
)
47 # go_write latch: reset on go_write HI, set on issue
48 m
.d
.comb
+= wr_l
.s
.eq(self
.issue_i
)
49 m
.d
.comb
+= wr_l
.r
.eq(self
.go_write_i
)
51 # src1 latch: reset on go_read HI, set on issue
52 m
.d
.comb
+= rd_l
.s
.eq(self
.issue_i
)
53 m
.d
.comb
+= rd_l
.r
.eq(self
.go_read_i
)
55 # dest decoder: write-pending out
56 m
.d
.comb
+= dest_d
.i
.eq(self
.dest_i
)
57 m
.d
.comb
+= dest_d
.n
.eq(wr_l
.q
) # FIXME this is sync-delayed!
58 m
.d
.comb
+= self
.wr_pend_o
.eq(dest_d
.o
)
60 # src1/src2 decoder: read-pending out
61 m
.d
.comb
+= src1_d
.i
.eq(self
.src1_i
)
62 m
.d
.comb
+= src1_d
.n
.eq(rd_l
.q
) # FIXME this is sync-delayed!
63 m
.d
.comb
+= src2_d
.i
.eq(self
.src2_i
)
64 m
.d
.comb
+= src2_d
.n
.eq(rd_l
.q
) # FIXME this is sync-delayed!
65 m
.d
.comb
+= self
.rd_pend_o
.eq(src1_d
.o | src2_d
.o
)
67 # readable output signal
68 int_g_wr
= Signal(self
.reg_width
, reset_less
=True)
69 m
.d
.comb
+= int_g_wr
.eq(self
.g_wr_pend_i
& self
.rd_pend_o
)
70 m
.d
.comb
+= self
.readable_o
.eq(int_g_wr
.bool())
72 # writable output signal
73 int_g_rw
= Signal(self
.reg_width
, reset_less
=True)
74 g_rw
= Signal(reset_less
=True)
75 m
.d
.comb
+= int_g_rw
.eq(self
.g_rd_pend_i
& self
.wr_pend_o
)
76 m
.d
.comb
+= g_rw
.eq(~int_g_rw
.bool())
77 m
.d
.comb
+= self
.writable_o
.eq(g_rw
& rd_l
.q
& self
.req_rel_i
)
89 yield self
.g_rd_pend_i
90 yield self
.g_wr_pend_i
100 def int_fn_unit_sim(dut
):
101 yield dut
.dest_i
.eq(1)
102 yield dut
.issue_i
.eq(1)
104 yield dut
.issue_i
.eq(0)
106 yield dut
.src1_i
.eq(1)
107 yield dut
.issue_i
.eq(1)
111 yield dut
.issue_i
.eq(0)
113 yield dut
.go_read_i
.eq(1)
115 yield dut
.go_read_i
.eq(0)
117 yield dut
.go_write_i
.eq(1)
119 yield dut
.go_write_i
.eq(0)
122 def test_int_fn_unit():
124 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
125 with
open("test_int_fn_unit.il", "w") as f
:
128 run_simulation(dut
, int_fn_unit_sim(dut
), vcd_name
='test_int_fn_unit.vcd')
130 if __name__
== '__main__':