1 """ Mitch Alsup 6600-style LD/ST Memory Scoreboard Matrix (sparse vector)
3 6600 LD/ST Dependency Table Matrix inputs / outputs
4 ---------------------------------------------------
6 Relevant comments (p45-46):
8 * If there are no WAR dependencies on a Load instruction with a computed
9 address it can assert Bank_Addressable and Translate_Addressable.
11 * If there are no RAW dependencies on a Store instruction with both a
12 write permission and store data present it can assert Bank_Addressable
15 * http://bugs.libre-riscv.org/show_bug.cgi?id=81
19 from nmigen
.compat
.sim
import run_simulation
20 from nmigen
.cli
import verilog
, rtlil
21 from nmigen
import Module
, Signal
, Elaboratable
, Array
, Cat
, Const
23 from ldst_dep_cell
import LDSTDepCell
26 class LDSTDepMatrix(Elaboratable
):
27 """ implements 11.4.12 mitch alsup LD/ST Dependency Matrix, p46
28 actually a sparse matrix along the diagonal.
30 load-hold-store and store-hold-load accumulate in a priority-picking
31 fashion, ORing together. the OR gate from the dependency cell is
34 def __init__(self
, n_ldst
):
35 self
.n_ldst
= n_ldst
# X and Y (FUs)
36 self
.load_i
= Signal(n_ldst
, reset_less
=True) # load pending in
37 self
.stor_i
= Signal(n_ldst
, reset_less
=True) # store pending in
38 self
.issue_i
= Signal(n_ldst
, reset_less
=True) # Issue in
40 self
.load_hit_i
= Signal(n_ldst
, reset_less
=True) # load hit in
41 self
.stwd_hit_i
= Signal(n_ldst
, reset_less
=True) # store w/data hit in
44 self
.ld_hold_st_o
= Signal(n_ldst
, reset_less
=True) # load holds st out
45 self
.st_hold_ld_o
= Signal(n_ldst
, reset_less
=True) # st holds load out
47 def elaborate(self
, platform
):
51 # matrix of dependency cells
53 dm
= Array(LDSTDepCell() for f
in range(self
.n_ldst
))
54 for fu
in range(self
.n_ldst
):
55 setattr(m
.submodules
, "dm_fu%d" % (fu
), dm
[fu
])
58 # connect Function Unit vector
60 lhs
= Const(0) # start at const 0
61 shl
= Const(0) # (does no harm)
69 for fu
in range(self
.n_ldst
):
71 # connect up the load/hold/store cell in/out (starts as a const)
72 m
.d
.comb
+= [dc
.ld_hold_st_i
.eq(lhs
),
73 dc
.st_hold_ld_i
.eq(shl
)
77 # accumulate load-hold-store / store-hold-load bits
80 # accumulate inputs (for Cat'ing later) - TODO: must be a better way
81 load_l
.append(dc
.load_i
)
82 stor_l
.append(dc
.stor_i
)
83 issue_l
.append(dc
.issue_i
)
84 lh_l
.append(dc
.load_hit_i
)
85 sh_l
.append(dc
.stwd_hit_i
)
87 # connect cell inputs using Cat(*list_of_stuff)
88 m
.d
.comb
+= [Cat(*load_l
).eq(self
.load_i
),
89 Cat(*stor_l
).eq(self
.stor_i
),
90 Cat(*issue_l
).eq(self
.issue_i
),
91 Cat(*lh_l
).eq(self
.load_hit_i
),
92 Cat(*sh_l
).eq(self
.stwd_hit_i
),
94 # set the load-hold-store / store-hold-load OR-accumulated outputs
95 m
.d
.comb
+= self
.ld_hold_st_o
.eq(Cat(*lhs_l
))
96 m
.d
.comb
+= self
.st_hold_ld_o
.eq(Cat(*shl_l
))
104 yield self
.load_hit_i
105 yield self
.stwd_hit_i
106 yield self
.ld_hold_st_o
107 yield self
.st_hold_ld_o
112 def d_matrix_sim(dut
):
115 yield dut
.dest_i
.eq(1)
116 yield dut
.issue_i
.eq(1)
118 yield dut
.issue_i
.eq(0)
120 yield dut
.src1_i
.eq(1)
121 yield dut
.issue_i
.eq(1)
123 yield dut
.issue_i
.eq(0)
125 yield dut
.go_read_i
.eq(1)
127 yield dut
.go_read_i
.eq(0)
129 yield dut
.go_write_i
.eq(1)
131 yield dut
.go_write_i
.eq(0)
135 dut
= LDSTDepMatrix(n_ldst
=4)
136 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
137 with
open("test_ld_st_matrix.il", "w") as f
:
140 run_simulation(dut
, d_matrix_sim(dut
), vcd_name
='test_ld_st_matrix.vcd')
142 if __name__
== '__main__':