1 """ Mitch Alsup 6600-style LD/ST scoreboard Dependency Cell
4 * http://bugs.libre-riscv.org/show_bug.cgi?id=81
8 from nmigen
.compat
.sim
import run_simulation
9 from nmigen
.cli
import verilog
, rtlil
10 from nmigen
import Module
, Signal
, Elaboratable
11 from nmutil
.latch
import SRLatch
14 class LDSTDepCell(Elaboratable
):
15 """ implements 11.4.12 mitch alsup load/store dependence cell, p45
17 note: the load-hold-store / store-hold-load both come through from
18 the previous cell and accumulate using ORing to create priority
19 picking (in the sparse-matrix, which is where the cells are wired up)
23 self
.load_i
= Signal(reset_less
=True) # load pending in (top)
24 self
.stor_i
= Signal(reset_less
=True) # store pending in (top)
25 self
.issue_i
= Signal(reset_less
=True) # Issue in (top)
27 self
.load_hit_i
= Signal(reset_less
=True) # load hit in (right)
28 self
.stwd_hit_i
= Signal(reset_less
=True) # store w/ data hit in (right)
29 self
.ld_hold_st_i
= Signal(reset_less
=True) # load holds st in (right)
30 self
.st_hold_ld_i
= Signal(reset_less
=True) # st holds load in (right)
32 # outputs (latched rd/wr pend)
33 self
.ld_hold_st_o
= Signal(reset_less
=True) # load holds st out (left)
34 self
.st_hold_ld_o
= Signal(reset_less
=True) # st holds load out (left)
36 def elaborate(self
, platform
):
38 m
.submodules
.war_l
= war_l
= SRLatch(sync
=False) # WriteAfterRead Latch
39 m
.submodules
.raw_l
= raw_l
= SRLatch(sync
=False) # ReadAfterWrite Latch
41 # issue & store & load - used for both WAR and RAW Setting
42 i_s_l
= Signal(reset_less
=True)
43 m
.d
.comb
+= i_s_l
.eq(self
.issue_i
& self
.stor_i
& self
.load_i
)
45 # write after read latch: loads block stores
46 m
.d
.comb
+= war_l
.s
.eq(i_s_l
)
47 m
.d
.comb
+= war_l
.r
.eq(self
.load_i
) # reset on LD
49 # read after write latch: stores block loads
50 m
.d
.comb
+= raw_l
.s
.eq(i_s_l
)
51 m
.d
.comb
+= raw_l
.r
.eq(self
.stor_i
) # reset on ST
53 # Hold results (read out horizontally, accumulate in OR fashion)
54 lhs
= war_l
.qn
& self
.load_hit_i
55 shl
= raw_l
.qn
& self
.stwd_hit_i
56 m
.d
.comb
+= self
.ld_hold_st_o
.eq(self
.ld_hold_st_i | lhs
)
57 m
.d
.comb
+= self
.st_hold_ld_o
.eq(self
.st_hold_ld_i | shl
)
67 yield self
.ld_hold_st_i
68 yield self
.st_hold_ld_i
69 yield self
.ld_hold_st_o
70 yield self
.st_hold_ld_o
77 yield dut
.dest_i
.eq(1)
78 yield dut
.issue_i
.eq(1)
80 yield dut
.issue_i
.eq(0)
82 yield dut
.src1_i
.eq(1)
83 yield dut
.issue_i
.eq(1)
85 yield dut
.issue_i
.eq(0)
87 yield dut
.go_read_i
.eq(1)
89 yield dut
.go_read_i
.eq(0)
91 yield dut
.go_write_i
.eq(1)
93 yield dut
.go_write_i
.eq(0)
98 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
99 with
open("test_ldst_dcell.il", "w") as f
:
102 run_simulation(dut
, dcell_sim(dut
), vcd_name
='test_ldst_dcell.vcd')
104 if __name__
== '__main__':