wire up FU-FU matrix using inverted row/col
[soc.git] / src / scoreboard / fu_dep_cell.py
1 from nmigen.compat.sim import run_simulation
2 from nmigen.cli import verilog, rtlil
3 from nmigen import Module, Signal, Const, Elaboratable
4 from nmutil.latch import SRLatch
5
6
7 class DepCell(Elaboratable):
8 """ FU Dependency Cell
9 """
10 def __init__(self, llen=1):
11 self.llen = llen
12 # inputs
13 self.pend_i = Signal(llen, reset_less=True) # pending bit in (left)
14 self.issue_i = Signal(llen, reset_less=True) # Issue in (top)
15 self.go_i = Signal(llen, reset_less=True) # Go read/write in (left)
16 self.die_i = Signal(llen, reset_less=True) # Go die in (left)
17
18 # wait
19 self.wait_o = Signal(llen, reset_less=True) # wait out (right)
20
21 def elaborate(self, platform):
22 m = Module()
23 m.submodules.l = l = SRLatch(sync=False, llen=self.llen) # async latch
24
25 # reset on go HI, set on dest and issue
26 m.d.comb += l.s.eq(self.issue_i & self.pend_i)
27 m.d.comb += l.r.eq(self.go_i | self.die_i)
28
29 # wait out
30 m.d.comb += self.wait_o.eq(l.qlq & ~self.issue_i)
31
32 return m
33
34 def __iter__(self):
35 yield self.pend_i
36 yield self.issue_i
37 yield self.go_i
38 yield self.die_i
39 yield self.wait_o
40
41 def ports(self):
42 return list(self)
43
44
45 class FUDependenceCell(Elaboratable):
46 """ implements 11.4.7 mitch alsup dependence cell, p27
47 """
48 def __init__(self, dummy, n_fu=1):
49 self.n_fu = n_fu
50 self.dummy = Const(~(1<<dummy), n_fu)
51 # inputs
52 self.rd_pend_i = Signal(n_fu, reset_less=True) # read pend in (left)
53 self.wr_pend_i = Signal(n_fu, reset_less=True) # write pend in (left)
54 self.issue_i = Signal(n_fu, reset_less=True) # Issue in (top)
55
56 self.go_wr_i = Signal(n_fu, reset_less=True) # Go Write in (left)
57 self.go_rd_i = Signal(n_fu, reset_less=True) # Go Read in (left)
58 self.go_die_i = Signal(n_fu, reset_less=True) # Go Die in (left)
59
60 # outputs (latched rd/wr wait)
61 self.rd_wait_o = Signal(n_fu, reset_less=True) # read wait out (right)
62 self.wr_wait_o = Signal(n_fu, reset_less=True) # write wait out (right)
63
64 def elaborate(self, platform):
65 m = Module()
66 m.submodules.rd_c = rd_c = DepCell(self.n_fu)
67 m.submodules.wr_c = wr_c = DepCell(self.n_fu)
68
69 # connect issue
70 for c in [rd_c, wr_c]:
71 m.d.comb += c.issue_i.eq(self.issue_i)
72 m.d.comb += c.die_i.eq(self.go_die_i)
73
74 # connect go_rd / go_wr
75 m.d.comb += wr_c.go_i.eq(self.go_wr_i)
76 m.d.comb += rd_c.go_i.eq(self.go_rd_i)
77
78 # connect pend_i
79 m.d.comb += wr_c.pend_i.eq(self.wr_pend_i & self.dummy)
80 m.d.comb += rd_c.pend_i.eq(self.rd_pend_i & self.dummy)
81
82 # connect output
83 m.d.comb += self.wr_wait_o.eq(wr_c.wait_o)
84 m.d.comb += self.rd_wait_o.eq(rd_c.wait_o)
85
86 return m
87
88 def __iter__(self):
89 yield self.rd_pend_i
90 yield self.wr_pend_i
91 yield self.issue_i
92 yield self.go_wr_i
93 yield self.go_rd_i
94 yield self.go_die_i
95 yield self.rd_wait_o
96 yield self.wr_wait_o
97
98 def ports(self):
99 return list(self)
100
101
102 def dcell_sim(dut):
103 yield dut.dest_i.eq(1)
104 yield dut.issue_i.eq(1)
105 yield
106 yield dut.issue_i.eq(0)
107 yield
108 yield dut.src1_i.eq(1)
109 yield dut.issue_i.eq(1)
110 yield
111 yield dut.issue_i.eq(0)
112 yield
113 yield dut.go_rd_i.eq(1)
114 yield
115 yield dut.go_rd_i.eq(0)
116 yield
117 yield dut.go_wr_i.eq(1)
118 yield
119 yield dut.go_wr_i.eq(0)
120 yield
121
122 def test_dcell():
123 dut = FUDependenceCell()
124 vl = rtlil.convert(dut, ports=dut.ports())
125 with open("test_fu_dcell.il", "w") as f:
126 f.write(vl)
127
128 run_simulation(dut, dcell_sim(dut), vcd_name='test_fu_dcell.vcd')
129
130 if __name__ == '__main__':
131 test_dcell()