move scoreboard multi rd/wr to new folder
[soc.git] / src / soc / 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 FUDependenceCell(Elaboratable):
8 """ implements 11.4.7 mitch alsup dependence cell, p27
9 """
10 def __init__(self, dummy, n_fu=1):
11 self.n_fu = n_fu
12 self.dummy = Const(~(1<<dummy), n_fu)
13 # inputs
14 self.rd_pend_i = Signal(n_fu, reset_less=True) # read pend in (left)
15 self.wr_pend_i = Signal(n_fu, reset_less=True) # write pend in (left)
16 self.issue_i = Signal(n_fu, reset_less=True) # Issue in (top)
17
18 self.go_wr_i = Signal(n_fu, reset_less=True) # Go Write in (left)
19 self.go_rd_i = Signal(n_fu, reset_less=True) # Go Read in (left)
20 self.go_die_i = Signal(n_fu, reset_less=True) # Go Die in (left)
21
22 # outputs (latched rd/wr wait)
23 self.rd_wait_o = Signal(n_fu, reset_less=True) # read wait out (right)
24 self.wr_wait_o = Signal(n_fu, reset_less=True) # write wait out (right)
25
26 def elaborate(self, platform):
27 m = Module()
28 m.submodules.rd_c = rd_c = SRLatch(sync=False, llen=self.n_fu)
29 m.submodules.wr_c = wr_c = SRLatch(sync=False, llen=self.n_fu)
30
31 # reset on go HI, set on dest and issue
32 m.d.comb += rd_c.s.eq(self.issue_i & self.rd_pend_i)
33 m.d.comb += wr_c.s.eq(self.issue_i & self.wr_pend_i)
34
35 # connect go_rd / go_wr
36 m.d.comb += wr_c.r.eq(self.go_wr_i | self.go_die_i)
37 m.d.comb += rd_c.r.eq(self.go_rd_i | self.go_die_i)
38
39 # connect pend_i
40 m.d.comb += rd_c.s.eq(self.issue_i & self.rd_pend_i & self.dummy)
41 m.d.comb += wr_c.s.eq(self.issue_i & self.wr_pend_i & self.dummy)
42
43 # connect output
44 m.d.comb += self.rd_wait_o.eq(rd_c.qlq & ~self.issue_i)
45 m.d.comb += self.wr_wait_o.eq(wr_c.qlq & ~self.issue_i)
46
47 return m
48
49 def __iter__(self):
50 yield self.rd_pend_i
51 yield self.wr_pend_i
52 yield self.issue_i
53 yield self.go_wr_i
54 yield self.go_rd_i
55 yield self.go_die_i
56 yield self.rd_wait_o
57 yield self.wr_wait_o
58
59 def ports(self):
60 return list(self)
61
62
63 def dcell_sim(dut):
64 yield dut.dest_i.eq(1)
65 yield dut.issue_i.eq(1)
66 yield
67 yield dut.issue_i.eq(0)
68 yield
69 yield dut.src1_i.eq(1)
70 yield dut.issue_i.eq(1)
71 yield
72 yield dut.issue_i.eq(0)
73 yield
74 yield dut.go_rd_i.eq(1)
75 yield
76 yield dut.go_rd_i.eq(0)
77 yield
78 yield dut.go_wr_i.eq(1)
79 yield
80 yield dut.go_wr_i.eq(0)
81 yield
82
83 def test_dcell():
84 dut = FUDependenceCell(dummy=0, n_fu=4)
85 vl = rtlil.convert(dut, ports=dut.ports())
86 with open("test_fu_dcell.il", "w") as f:
87 f.write(vl)
88
89 run_simulation(dut, dcell_sim(dut), vcd_name='test_fu_dcell.vcd')
90
91 if __name__ == '__main__':
92 test_dcell()