be10578aa3d56e0552cd2756a67e22834a884127
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
, Repl
, Elaboratable
11 from nmutil
.latch
import SRLatch
14 class LDSTDepCell(Elaboratable
):
15 """ implements 11.4.12 mitch alsup load/store dependence cell, p45
17 def __init__(self
, n_ls
=1):
20 self
.load_i
= Signal(n_ls
, reset_less
=True) # load pend in (top)
21 self
.stor_i
= Signal(n_ls
, reset_less
=True) # store pend in (top)
22 self
.issue_i
= Signal(reset_less
=True) # Issue in (top)
23 self
.go_die_i
= Signal(reset_less
=True) # Issue in (top)
25 # load / store hit - basically connect these to go_wr from LD/STCompUnit
26 # LD.go_wr -> load_hit_i, ST.go_wr -> stwd_hit_i.
27 self
.load_hit_i
= Signal(n_ls
, reset_less
=True) # ld hit in (right)
28 self
.stwd_hit_i
= Signal(n_ls
, reset_less
=True) # st w/ hit in (right)
30 # outputs (latched rd/wr pend)
31 self
.ld_hold_st_o
= Signal(n_ls
, reset_less
=True) # ld holds st out (l)
32 self
.st_hold_ld_o
= Signal(n_ls
, reset_less
=True) # st holds ld out (l)
34 def elaborate(self
, platform
):
36 m
.submodules
.war_l
= war_l
= SRLatch(sync
=False, llen
=self
.n_ls
) # WaR
37 m
.submodules
.raw_l
= raw_l
= SRLatch(sync
=False, llen
=self
.n_ls
) # RaW
39 # temporaries (repeat-extend)
40 issue
= Repl(self
.issue_i
, self
.n_ls
)
41 die
= Repl(self
.go_die_i
, self
.n_ls
)
43 # issue & store & load - used for both WAR and RAW Setting
44 i_s_l
= Signal(reset_less
=True)
45 m
.d
.comb
+= i_s_l
.eq(issue
& self
.stor_i
& self
.load_i
)
47 # write after read latch: loads block stores
48 m
.d
.comb
+= war_l
.s
.eq(i_s_l
)
49 m
.d
.comb
+= war_l
.r
.eq(die | self
.load_i
) # reset on LD
51 # read after write latch: stores block loads
52 m
.d
.comb
+= raw_l
.s
.eq(i_s_l
)
53 m
.d
.comb
+= raw_l
.r
.eq(die | self
.stor_i
) # reset on ST
55 # Hold results (read out horizontally, accumulate in OR fashion)
56 m
.d
.comb
+= self
.ld_hold_st_o
.eq(war_l
.qn
& self
.load_hit_i
)
57 m
.d
.comb
+= self
.st_hold_ld_o
.eq(raw_l
.qn
& self
.stwd_hit_i
)
67 yield self
.ld_hold_st_o
68 yield self
.st_hold_ld_o
75 yield dut
.dest_i
.eq(1)
76 yield dut
.issue_i
.eq(1)
78 yield dut
.issue_i
.eq(0)
80 yield dut
.src1_i
.eq(1)
81 yield dut
.issue_i
.eq(1)
83 yield dut
.issue_i
.eq(0)
85 yield dut
.go_rd_i
.eq(1)
87 yield dut
.go_rd_i
.eq(0)
89 yield dut
.go_wr_i
.eq(1)
91 yield dut
.go_wr_i
.eq(0)
96 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
97 with
open("test_ldst_dcell.il", "w") as f
:
100 run_simulation(dut
, dcell_sim(dut
), vcd_name
='test_ldst_dcell.vcd')
102 if __name__
== '__main__':