add comments
[ieee754fpu.git] / src / scoreboard / ldst_matrix.py
1 """ Mitch Alsup 6600-style LD/ST Memory Scoreboard Matrix (sparse vector)
2
3 6600 LD/ST Dependency Table Matrix inputs / outputs
4 ---------------------------------------------------
5
6 Relevant comments (p45-46):
7
8 * If there are no WAR dependencies on a Load instruction with a computed
9 address it can assert Bank_Addressable and Translate_Addressable.
10
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
13
14 Relevant bugreports:
15 * http://bugs.libre-riscv.org/show_bug.cgi?id=81
16
17 """
18
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
22
23 from ldst_dep_cell import LDSTDepCell
24
25
26 class LDSTDepMatrix(Elaboratable):
27 """ implements 11.4.12 mitch alsup LD/ST Dependency Matrix, p46
28 actually a sparse matrix along the diagonal.
29
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
32 here.
33 """
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
39
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
42
43 # outputs
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
46
47 def elaborate(self, platform):
48 m = Module()
49
50 # ---
51 # matrix of dependency cells
52 # ---
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])
56
57 # ---
58 # connect Function Unit vector
59 # ---
60 lhs = Const(0) # start at const 0
61 shl = Const(0) # (does no harm)
62 lhs_l = []
63 shl_l = []
64 load_l = []
65 stor_l = []
66 issue_l = []
67 lh_l = []
68 sh_l = []
69 for fu in range(self.n_ldst):
70 dc = dm[fu]
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)
74 ]
75 lhs = dc.ld_hold_st_o
76 shl = dc.st_hold_ld_o
77 # accumulate load-hold-store / store-hold-load bits
78 lhs_l.append(lhs)
79 shl_l.append(shl)
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)
86
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),
93 ]
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))
97
98 return m
99
100 def __iter__(self):
101 yield self.load_i
102 yield self.stor_i
103 yield self.issue_i
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
108
109 def ports(self):
110 return list(self)
111
112 def d_matrix_sim(dut):
113 """ XXX TODO
114 """
115 yield dut.dest_i.eq(1)
116 yield dut.issue_i.eq(1)
117 yield
118 yield dut.issue_i.eq(0)
119 yield
120 yield dut.src1_i.eq(1)
121 yield dut.issue_i.eq(1)
122 yield
123 yield dut.issue_i.eq(0)
124 yield
125 yield dut.go_read_i.eq(1)
126 yield
127 yield dut.go_read_i.eq(0)
128 yield
129 yield dut.go_write_i.eq(1)
130 yield
131 yield dut.go_write_i.eq(0)
132 yield
133
134 def test_d_matrix():
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:
138 f.write(vl)
139
140 run_simulation(dut, d_matrix_sim(dut), vcd_name='test_ld_st_matrix.vcd')
141
142 if __name__ == '__main__':
143 test_d_matrix()