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
7 class LDSTDepCell(Elaboratable
):
8 """ implements 11.4.12 mitch alsup load/store dependence cell, p45
10 note: the load-hold-store / store-hold-load both come through from
11 the previous cell and accumulate using ORing to create priority
12 picking (in the sparse-matrix, which is where the cells are wired up)
16 self
.load_i
= Signal(reset_less
=True) # load pending in (top)
17 self
.stor_i
= Signal(reset_less
=True) # store pending in (top)
18 self
.issue_i
= Signal(reset_less
=True) # Issue in (top)
20 self
.load_hit_i
= Signal(reset_less
=True) # load hit in (right)
21 self
.stwd_hit_i
= Signal(reset_less
=True) # store w/ data hit in (right)
22 self
.ld_hold_st_i
= Signal(reset_less
=True) # load holds st in (right)
23 self
.st_hold_ld_i
= Signal(reset_less
=True) # st holds load in (right)
25 # outputs (latched rd/wr pend)
26 self
.ld_hold_st_o
= Signal(reset_less
=True) # load holds st out (left)
27 self
.st_hold_ld_o
= Signal(reset_less
=True) # st holds load out (left)
29 def elaborate(self
, platform
):
31 m
.submodules
.war_l
= war_l
= SRLatch() # Write After Read Latch
32 m
.submodules
.raw_l
= raw_l
= SRLatch() # Read After Write Latch
34 # issue & store & load - used for both WAR and RAW Setting
35 i_s_l
= Signal(reset_less
=True)
36 m
.d
.comb
+= i_s_l
.eq(self
.issue_i
& self
.stor_i
& self
.load_i
)
38 # write after read latch: loads block stores
39 m
.d
.comb
+= war_l
.s
.eq(i_s_l
)
40 m
.d
.comb
+= war_l
.r
.eq(self
.load_i
) # reset on LD
42 # read after write latch: stores block loads
43 m
.d
.comb
+= raw_l
.s
.eq(i_s_l
)
44 m
.d
.comb
+= raw_l
.r
.eq(self
.stor_i
) # reset on ST
46 # Hold results (read out horizontally, accumulate in OR fashion)
47 lhs
= war_l
.qn
& self
.load_hit_i
48 shl
= raw_l
.qn
& self
.stwd_hit_i
49 m
.d
.comb
+= self
.ld_hold_st_o
.eq(self
.ld_hold_st_i | lhs
)
50 m
.d
.comb
+= self
.st_hold_ld_o
.eq(self
.st_hold_ld_i | shl
)
60 yield self
.ld_hold_st_i
61 yield self
.st_hold_ld_i
62 yield self
.ld_hold_st_o
63 yield self
.st_hold_ld_o
70 yield dut
.dest_i
.eq(1)
71 yield dut
.issue_i
.eq(1)
73 yield dut
.issue_i
.eq(0)
75 yield dut
.src1_i
.eq(1)
76 yield dut
.issue_i
.eq(1)
78 yield dut
.issue_i
.eq(0)
80 yield dut
.go_read_i
.eq(1)
82 yield dut
.go_read_i
.eq(0)
84 yield dut
.go_write_i
.eq(1)
86 yield dut
.go_write_i
.eq(0)
91 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
92 with
open("test_ldst_dcell.il", "w") as f
:
95 run_simulation(dut
, dcell_sim(dut
), vcd_name
='test_ldst_dcell.vcd')
97 if __name__
== '__main__':