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