rename variable wid -> dep
[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 from nmigen.lib.coding import Decoder
6
7
8 class GlobalPending(Elaboratable):
9 """ implements Global Pending Vector, basically ORs all incoming Function
10 Unit vectors together. Can be used for creating Read or Write Global
11 Pending. Can be used for INT or FP Global Pending.
12
13 Inputs:
14 * :dep: register file depth
15 * :fu_vecs: a python list of function unit "pending" vectors, each
16 vector being a Signal of width equal to the reg file.
17
18 Notes:
19
20 * the regfile may be Int or FP, this code doesn't care which.
21 obviously do not try to put in a mixture of regfiles into fu_vecs.
22 * this code also doesn't care if it's used for Read Pending or Write
23 pending, it can be used for both: again, obviously, do not try to
24 put in a mixture of read *and* write pending vectors in.
25 * if some Function Units happen not to be uniform (don't operate
26 on a particular register (extremely unusual), they must set a Const
27 zero bit in the vector.
28 """
29 def __init__(self, dep, fu_vecs):
30 self.reg_dep = dep
31 # inputs
32 self.fu_vecs = fu_vecs
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 m.d.comb += self.g_pend_o.eq(Cat(*pend_l)) # merge all OR'd bits
48
49 return m
50
51 def __iter__(self):
52 yield from self.fu_vecs
53 yield self.g_pend_o
54
55 def ports(self):
56 return list(self)
57
58
59 def g_vec_sim(dut):
60 yield dut.dest_i.eq(1)
61 yield dut.issue_i.eq(1)
62 yield
63 yield dut.issue_i.eq(0)
64 yield
65 yield dut.src1_i.eq(1)
66 yield dut.issue_i.eq(1)
67 yield
68 yield
69 yield
70 yield dut.issue_i.eq(0)
71 yield
72 yield dut.go_rd_i.eq(1)
73 yield
74 yield dut.go_rd_i.eq(0)
75 yield
76 yield dut.go_wr_i.eq(1)
77 yield
78 yield dut.go_wr_i.eq(0)
79 yield
80
81 def test_g_vec():
82 vecs = []
83 for i in range(3):
84 vecs.append(Signal(32, name="fu%d" % i))
85 dut = GlobalPending(32, vecs)
86 vl = rtlil.convert(dut, ports=dut.ports())
87 with open("test_global_pending.il", "w") as f:
88 f.write(vl)
89
90 run_simulation(dut, g_vec_sim(dut), vcd_name='test_global_pending.vcd')
91
92 if __name__ == '__main__':
93 test_g_vec()