scoreboard 6600 experimentation
[soc.git] / src / scoreboard / global_pending.py
1 from nmigen.compat.sim import run_simulation
2 from nmigen.cli import verilog, rtlil
3 from nmigen import Module, Signal, Cat, Elaboratable
4 from nmutil.latch import SRLatch
5
6
7 class GlobalPending(Elaboratable):
8 """ implements Global Pending Vector, basically ORs all incoming Function
9 Unit vectors together. Can be used for creating Read or Write Global
10 Pending. Can be used for INT or FP Global Pending.
11
12 Inputs:
13 * :dep: register file depth
14 * :fu_vecs: a python list of function unit "pending" vectors, each
15 vector being a Signal of width equal to the reg file.
16
17 Notes:
18
19 * the regfile may be Int or FP, this code doesn't care which.
20 obviously do not try to put in a mixture of regfiles into fu_vecs.
21 * this code also doesn't care if it's used for Read Pending or Write
22 pending, it can be used for both: again, obviously, do not try to
23 put in a mixture of read *and* write pending vectors in.
24 * if some Function Units happen not to be uniform (don't operate
25 on a particular register (extremely unusual), they must set a Const
26 zero bit in the vector.
27 """
28 def __init__(self, dep, fu_vecs, sync=False):
29 self.reg_dep = dep
30 # inputs
31 self.fu_vecs = fu_vecs
32 self.sync = sync
33 for v in fu_vecs:
34 assert len(v) == dep, "FU Vector must be same width as regfile"
35
36 self.g_pend_o = Signal(dep, reset_less=True) # global pending vector
37
38 def elaborate(self, platform):
39 m = Module()
40
41 pend_l = []
42 for i in range(self.reg_dep): # per-register
43 vec_bit_l = []
44 for v in self.fu_vecs:
45 vec_bit_l.append(v[i]) # fu bit for same register
46 pend_l.append(Cat(*vec_bit_l).bool()) # OR all bits for same reg
47 if self.sync:
48 m.d.sync += self.g_pend_o.eq(Cat(*pend_l)) # merge all OR'd bits
49 else:
50 m.d.comb += self.g_pend_o.eq(Cat(*pend_l)) # merge all OR'd bits
51
52 return m
53
54 def __iter__(self):
55 yield from self.fu_vecs
56 yield self.g_pend_o
57
58 def ports(self):
59 return list(self)
60
61
62 def g_vec_sim(dut):
63 yield dut.dest_i.eq(1)
64 yield dut.issue_i.eq(1)
65 yield
66 yield dut.issue_i.eq(0)
67 yield
68 yield dut.src1_i.eq(1)
69 yield dut.issue_i.eq(1)
70 yield
71 yield
72 yield
73 yield dut.issue_i.eq(0)
74 yield
75 yield dut.go_rd_i.eq(1)
76 yield
77 yield dut.go_rd_i.eq(0)
78 yield
79 yield dut.go_wr_i.eq(1)
80 yield
81 yield dut.go_wr_i.eq(0)
82 yield
83
84 def test_g_vec():
85 vecs = []
86 for i in range(3):
87 vecs.append(Signal(32, name="fu%d" % i))
88 dut = GlobalPending(32, vecs)
89 vl = rtlil.convert(dut, ports=dut.ports())
90 with open("test_global_pending.il", "w") as f:
91 f.write(vl)
92
93 run_simulation(dut, g_vec_sim(dut), vcd_name='test_global_pending.vcd')
94
95 if __name__ == '__main__':
96 test_g_vec()