1 from nmigen
.compat
.sim
import run_simulation
2 from nmigen
.cli
import verilog
, rtlil
3 from nmigen
import Module
, Signal
, Cat
, Array
, Const
, Record
, Elaboratable
4 from nmutil
.latch
import SRLatch
5 from nmigen
.lib
.coding
import Decoder
7 from shadow_fn
import ShadowFn
10 class IssueUnit(Elaboratable
):
11 """ implements 11.4.14 issue unit, p50
15 * :wid: register file width
17 def __init__(self
, wid
, n_insns
):
19 self
.n_insns
= n_insns
22 self
.store_i
= Signal(reset_less
=True) # instruction is a store
23 self
.dest_i
= Signal(max=wid
, reset_less
=True) # Dest R# in
24 self
.src1_i
= Signal(max=wid
, reset_less
=True) # oper1 R# in
25 self
.src2_i
= Signal(max=wid
, reset_less
=True) # oper2 R# in
27 self
.g_wr_pend_i
= Signal(wid
, reset_less
=True) # write pending vector
29 self
.insn_i
= Array(Signal(reset_less
=True, name
="insn_i") \
30 for i
in range(n_insns
))
31 self
.busy_i
= Array(Signal(reset_less
=True, name
="busy_i") \
32 for i
in range(n_insns
))
35 self
.fn_issue_o
= Array(Signal(reset_less
=True, name
="fn_issue_o") \
36 for i
in range(n_insns
))
37 self
.g_issue_o
= Signal(reset_less
=True)
39 def elaborate(self
, platform
):
41 m
.submodules
.dest_d
= dest_d
= Decoder(self
.reg_width
)
44 waw_stall
= Signal(reset_less
=True)
45 fu_stall
= Signal(reset_less
=True)
46 pend
= Signal(self
.reg_width
, reset_less
=True)
48 # dest decoder: write-pending
49 m
.d
.comb
+= dest_d
.i
.eq(self
.dest_i
)
50 m
.d
.comb
+= dest_d
.n
.eq(~self
.store_i
) # decode is inverted
51 m
.d
.comb
+= pend
.eq(dest_d
.o
& self
.g_wr_pend_i
)
52 m
.d
.comb
+= waw_stall
.eq(pend
.bool())
55 for i
in range(self
.n_insns
):
56 ib_l
.append(self
.insn_i
[i
] & self
.busy_i
[i
])
57 m
.d
.comb
+= fu_stall
.eq(Cat(*ib_l
).bool())
58 m
.d
.comb
+= self
.g_issue_o
.eq(~
(waw_stall | fu_stall
))
59 for i
in range(self
.n_insns
):
60 m
.d
.comb
+= self
.fn_issue_o
[i
].eq(self
.g_issue_o
& self
.insn_i
[i
])
69 yield self
.g_wr_pend_i
70 yield from self
.insn_i
71 yield from self
.busy_i
72 yield from self
.fn_issue_o
79 def issue_unit_sim(dut
):
80 yield dut
.dest_i
.eq(1)
81 yield dut
.issue_i
.eq(1)
83 yield dut
.issue_i
.eq(0)
85 yield dut
.src1_i
.eq(1)
86 yield dut
.issue_i
.eq(1)
90 yield dut
.issue_i
.eq(0)
92 yield dut
.go_read_i
.eq(1)
94 yield dut
.go_read_i
.eq(0)
96 yield dut
.go_write_i
.eq(1)
98 yield dut
.go_write_i
.eq(0)
101 def test_issue_unit():
102 dut
= IssueUnit(32, 3)
103 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
104 with
open("test_issue_unit.il", "w") as f
:
107 run_simulation(dut
, issue_unit_sim(dut
), vcd_name
='test_issue_unit.vcd')
109 if __name__
== '__main__':