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