add dependence cell scoreboard from 11.4.7
[ieee754fpu.git] / src / scoreboard / dependence_cell.py
1 from nmigen.compat.sim import run_simulation
2 from nmigen.cli import verilog, rtlil
3 from nmigen import Module, Signal, Elaboratable
4 from nmutil.latch import SRLatch
5
6 class DepencenceCell(Elaboratable):
7 """ implements 11.4.7 mitch alsup dependence cell, p27
8 """
9 def __init__(self):
10 # inputs
11 self.dest_i = Signal(reset_less=True) # Dest in (top)
12 self.src1_i = Signal(reset_less=True) # oper1 in (top)
13 self.src2_i = Signal(reset_less=True) # oper2 in (top)
14 self.issue_i = Signal(reset_less=True) # Issue in (top)
15
16 self.go_write_i = Signal(reset_less=True) # Go Write in (left)
17 self.go_read_i = Signal(reset_less=True) # Go Read in (left)
18
19 # for Register File Select Lines (vertical)
20 self.dest_rsel_o = Signal(reset_less=True) # dest reg sel (bottom)
21 self.src1_rsel_o = Signal(reset_less=True) # src1 reg sel (bottom)
22 self.src2_rsel_o = Signal(reset_less=True) # src2 reg sel (bottom)
23
24 # for Function Unit "forward progress" (horizontal)
25 self.dest_fwd_o = Signal(reset_less=True) # dest FU fw (right)
26 self.src1_fwd_o = Signal(reset_less=True) # src1 FU fw (right)
27 self.src2_fwd_o = Signal(reset_less=True) # src2 FU fw (right)
28
29 def elaborate(self, platform):
30 m = Module()
31 m.submodules.dest_l = dest_l = SRLatch()
32 m.submodules.src1_l = src1_l = SRLatch()
33 m.submodules.src2_l = src2_l = SRLatch()
34
35 # destination latch: reset on go_write HI, set on dest and issue
36 m.d.sync += dest_l.s.eq(self.issue_i & self.dest_i)
37 m.d.sync += dest_l.r.eq(self.go_write_i)
38
39 # src1 latch: reset on go_read HI, set on src1_i and issue
40 m.d.sync += src1_l.s.eq(self.issue_i & self.src1_i)
41 m.d.sync += src1_l.r.eq(self.go_read_i)
42
43 # src2 latch: reset on go_read HI, set on op2_i and issue
44 m.d.sync += src2_l.s.eq(self.issue_i & self.src2_i)
45 m.d.sync += src2_l.r.eq(self.go_read_i)
46
47 # FU "Forward Progress" (read out horizontally)
48 m.d.comb += self.dest_rsel_o.eq(dest_l.q & self.go_write_i)
49 m.d.comb += self.src1_rsel_o.eq(src1_l.q & self.go_read_i)
50 m.d.comb += self.src2_rsel_o.eq(src2_l.q & self.go_read_i)
51
52 # Register File Select (read out vertically)
53 m.d.comb += self.dest_fwd_o.eq(dest_l.q & self.dest_i)
54 m.d.comb += self.src1_fwd_o.eq(src1_l.q & self.src1_i)
55 m.d.comb += self.src2_fwd_o.eq(src2_l.q & self.src2_i)
56
57 return m
58
59 def __iter__(self):
60 yield self.dest_i
61 yield self.src1_i
62 yield self.src2_i
63 yield self.issue_i
64 yield self.go_write_i
65 yield self.go_read_i
66 yield self.dest_rsel_o
67 yield self.src1_rsel_o
68 yield self.src2_rsel_o
69 yield self.dest_fwd_o
70 yield self.src1_fwd_o
71 yield self.src2_fwd_o
72
73 def ports(self):
74 return list(self)
75
76 def dcell_sim(dut):
77 yield dut.s.eq(0)
78 yield dut.r.eq(0)
79 yield
80 yield dut.s.eq(1)
81 yield
82 yield dut.s.eq(0)
83 yield
84 yield dut.r.eq(1)
85 yield
86 yield dut.r.eq(0)
87 yield
88 yield
89
90 def test_dcell():
91 dut = DepencenceCell()
92 vl = rtlil.convert(dut, ports=dut.ports())
93 with open("test_dcell.il", "w") as f:
94 f.write(vl)
95
96 run_simulation(dut, dcell_sim(dut), vcd_name='test_dcell.vcd')
97
98 if __name__ == '__main__':
99 test_dcell()