add LD/ST dependency cell
[ieee754fpu.git] / src / scoreboard / ldst_dep_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
7 class LDSTDepCell(Elaboratable):
8 """ implements 11.4.12 mitch alsup load/store dependence cell, p45
9 """
10 def __init__(self):
11 # inputs
12 self.load_i = Signal(reset_less=True) # load pending in (top)
13 self.stor_i = Signal(reset_less=True) # store pending in (top)
14 self.issue_i = Signal(reset_less=True) # Issue in (top)
15
16 self.load_hit_i = Signal(reset_less=True) # load hit in (right)
17 self.stwd_hit_i = Signal(reset_less=True) # store w/ data hit in (right)
18
19 # outputs (latched rd/wr pend)
20 self.ld_hold_st_o = Signal(reset_less=True) # load holds st out (left)
21 self.st_hold_ld_o = Signal(reset_less=True) # st holds load out (left)
22
23 def elaborate(self, platform):
24 m = Module()
25 m.submodules.war_l = war_l = SRLatch() # Write After Read Latch
26 m.submodules.raw_l = raw_l = SRLatch() # Read After Write Latch
27
28 i_s_l = Signal(reset_less=True)
29
30 m.d.comb += i_s_l.eq(self.issue_i & self.stor_i & self.load_i)
31 # write after read latch: loads block stores
32 m.d.comb += war_l.s.eq(i_s_l)
33 m.d.comb += war_l.r.eq(self.load_i)
34
35 # read after write latch: stores block loads
36 m.d.comb += raw_l.s.eq(i_s_l)
37 m.d.comb += raw_l.r.eq(self.stor_i)
38
39 # Hold results (read out horizontally)
40 m.d.comb += self.ld_hold_st_o.eq(war_l.qn | self.load_hit_i)
41 m.d.comb += self.st_hold_ld_o.eq(raw_l.qn | self.stwd_hit_i)
42
43 return m
44
45 def __iter__(self):
46 yield self.load_i
47 yield self.stor_i
48 yield self.issue_i
49 yield self.load_hit_i
50 yield self.stwd_hit_i
51 yield self.ld_hold_st_o
52 yield self.st_hold_ld_o
53
54 def ports(self):
55 return list(self)
56
57
58 def dcell_sim(dut):
59 yield dut.dest_i.eq(1)
60 yield dut.issue_i.eq(1)
61 yield
62 yield dut.issue_i.eq(0)
63 yield
64 yield dut.src1_i.eq(1)
65 yield dut.issue_i.eq(1)
66 yield
67 yield dut.issue_i.eq(0)
68 yield
69 yield dut.go_read_i.eq(1)
70 yield
71 yield dut.go_read_i.eq(0)
72 yield
73 yield dut.go_write_i.eq(1)
74 yield
75 yield dut.go_write_i.eq(0)
76 yield
77
78 def test_dcell():
79 dut = LDSTDepCell()
80 vl = rtlil.convert(dut, ports=dut.ports())
81 with open("test_ldst_dcell.il", "w") as f:
82 f.write(vl)
83
84 run_simulation(dut, dcell_sim(dut), vcd_name='test_ldst_dcell.vcd')
85
86 if __name__ == '__main__':
87 test_dcell()