eb9da598fb6c8006a42ec652b6a12627f72bbd3f
[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):
29 self.reg_dep = dep
30 # inputs
31 self.fu_vecs = fu_vecs
32 for v in fu_vecs:
33 assert len(v) == dep, "FU Vector must be same width as regfile"
34
35 self.g_pend_o = Signal(dep, reset_less=True) # global pending vector
36
37 def elaborate(self, platform):
38 m = Module()
39
40 pend_l = []
41 for i in range(self.reg_dep): # per-register
42 vec_bit_l = []
43 for v in self.fu_vecs:
44 vec_bit_l.append(v[i]) # fu bit for same register
45 pend_l.append(Cat(*vec_bit_l).bool()) # OR all bits for same reg
46 m.d.comb += self.g_pend_o.eq(Cat(*pend_l)) # merge all OR'd bits
47
48 return m
49
50 def __iter__(self):
51 yield from self.fu_vecs
52 yield self.g_pend_o
53
54 def ports(self):
55 return list(self)
56
57
58 def g_vec_sim(dut):
59 yield dut.dest_i.eq(1)
60 yield dut.issue_i.eq(1)
61 yield
62 yield dut.issue_i.eq(0)
63 yield
64 yield dut.src1_i.eq(1)
65 yield dut.issue_i.eq(1)
66 yield
67 yield
68 yield
69 yield dut.issue_i.eq(0)
70 yield
71 yield dut.go_rd_i.eq(1)
72 yield
73 yield dut.go_rd_i.eq(0)
74 yield
75 yield dut.go_wr_i.eq(1)
76 yield
77 yield dut.go_wr_i.eq(0)
78 yield
79
80 def test_g_vec():
81 vecs = []
82 for i in range(3):
83 vecs.append(Signal(32, name="fu%d" % i))
84 dut = GlobalPending(32, vecs)
85 vl = rtlil.convert(dut, ports=dut.ports())
86 with open("test_global_pending.il", "w") as f:
87 f.write(vl)
88
89 run_simulation(dut, g_vec_sim(dut), vcd_name='test_global_pending.vcd')
90
91 if __name__ == '__main__':
92 test_g_vec()