3506b9e33093c8ba5f50bf3f30026b69799bb7d9
[ieee754fpu.git] / src / scoreboard / issue_unit.py
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
6
7 from shadow_fn import ShadowFn
8
9
10 class IssueUnit(Elaboratable):
11 """ implements 11.4.14 issue unit, p50
12
13 Inputs
14
15 * :wid: register file width
16 """
17 def __init__(self, wid, n_insns):
18 self.reg_width = wid
19 self.n_insns = n_insns
20
21 # inputs
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
26
27 self.g_wr_pend_i = Signal(wid, reset_less=True) # write pending vector
28
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))
33
34 # outputs
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)
38
39 def elaborate(self, platform):
40 m = Module()
41 m.submodules.dest_d = dest_d = Decoder(self.reg_width)
42
43 # temporaries
44 waw_stall = Signal(reset_less=True)
45 fu_stall = Signal(reset_less=True)
46 pend = Signal(self.reg_width, reset_less=True)
47
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())
53
54 ib_l = []
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])
61
62 return m
63
64 def __iter__(self):
65 yield self.store_i
66 yield self.dest_i
67 yield self.src1_i
68 yield self.src2_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
73 yield self.g_issue_o
74
75 def ports(self):
76 return list(self)
77
78
79 def issue_unit_sim(dut):
80 yield dut.dest_i.eq(1)
81 yield dut.issue_i.eq(1)
82 yield
83 yield dut.issue_i.eq(0)
84 yield
85 yield dut.src1_i.eq(1)
86 yield dut.issue_i.eq(1)
87 yield
88 yield
89 yield
90 yield dut.issue_i.eq(0)
91 yield
92 yield dut.go_read_i.eq(1)
93 yield
94 yield dut.go_read_i.eq(0)
95 yield
96 yield dut.go_write_i.eq(1)
97 yield
98 yield dut.go_write_i.eq(0)
99 yield
100
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:
105 f.write(vl)
106
107 run_simulation(dut, issue_unit_sim(dut), vcd_name='test_issue_unit.vcd')
108
109 if __name__ == '__main__':
110 test_issue_unit()