use FU-FU matrix, seems to be working, still have to resolve dependencies
[soc.git] / src / scoreboard / group_picker.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
5
6 class PriorityPicker(Elaboratable):
7 """ implements a priority-picker. input: N bits, output: N bits
8 """
9 def __init__(self, wid):
10 self.wid = wid
11 # inputs
12 self.i = Signal(wid, reset_less=True)
13 self.o = Signal(wid, reset_less=True)
14
15 def elaborate(self, platform):
16 m = Module()
17
18 res = []
19 ni = Signal(self.wid, reset_less = True)
20 m.d.comb += ni.eq(~self.i)
21 for i in range(0, self.wid):
22 t = Signal(reset_less = True)
23 res.append(t)
24 if i == 0:
25 m.d.comb += t.eq(self.i[i])
26 else:
27 m.d.comb += t.eq(~Cat(ni[i], *self.i[:i]).bool())
28
29 # we like Cat(*xxx). turn lists into concatenated bits
30 m.d.comb += self.o.eq(Cat(*res))
31
32 return m
33
34 def __iter__(self):
35 yield self.i
36 yield self.o
37
38 def ports(self):
39 return list(self)
40
41
42 class GroupPicker(Elaboratable):
43 """ implements 10.5 mitch alsup group picker, p27
44 """
45 def __init__(self, wid):
46 self.gp_wid = wid
47 # inputs
48 self.readable_i = Signal(wid, reset_less=True) # readable in (top)
49 self.writable_i = Signal(wid, reset_less=True) # writable in (top)
50 self.go_rd_i = Signal(wid, reset_less=True) # go read in (top)
51 self.req_rel_i = Signal(wid, reset_less=True) # release request in (top)
52
53 # outputs
54 self.go_rd_o = Signal(wid, reset_less=True) # go read (bottom)
55 self.go_wr_o = Signal(wid, reset_less=True) # go write (bottom)
56
57 def elaborate(self, platform):
58 m = Module()
59
60 m.submodules.rpick = rpick = PriorityPicker(self.gp_wid)
61 m.submodules.wpick = wpick = PriorityPicker(self.gp_wid)
62
63 # combine release (output ready signal) with writeable
64 m.d.comb += wpick.i.eq(self.writable_i & self.req_rel_i)
65 m.d.comb += self.go_wr_o.eq(wpick.o)
66
67 m.d.comb += rpick.i.eq(self.readable_i) #& self.go_rd_i)
68 m.d.comb += self.go_rd_o.eq(rpick.o)
69
70 return m
71
72 def __iter__(self):
73 yield self.readable_i
74 yield self.writable_i
75 yield self.req_rel_i
76 yield self.go_rd_o
77 yield self.go_wr_o
78
79 def ports(self):
80 return list(self)
81
82
83 def grp_pick_sim(dut):
84 yield dut.dest_i.eq(1)
85 yield dut.issue_i.eq(1)
86 yield
87 yield dut.issue_i.eq(0)
88 yield
89 yield dut.src1_i.eq(1)
90 yield dut.issue_i.eq(1)
91 yield
92 yield
93 yield
94 yield dut.issue_i.eq(0)
95 yield
96 yield dut.go_rd_i.eq(1)
97 yield
98 yield dut.go_rd_i.eq(0)
99 yield
100 yield dut.go_wr_i.eq(1)
101 yield
102 yield dut.go_wr_i.eq(0)
103 yield
104
105 def test_grp_pick():
106 dut = GroupPicker(4)
107 vl = rtlil.convert(dut, ports=dut.ports())
108 with open("test_grp_pick.il", "w") as f:
109 f.write(vl)
110
111 run_simulation(dut, grp_pick_sim(dut), vcd_name='test_grp_pick.vcd')
112
113 if __name__ == '__main__':
114 test_grp_pick()