rename rsel vectors in mem dep cell
[soc.git] / src / scoreboard / mem_fu_matrix.py
1 from nmigen.compat.sim import run_simulation
2 from nmigen.cli import verilog, rtlil
3 from nmigen import Module, Signal, Elaboratable, Array, Cat
4
5 from scoreboard.mem_dependence_cell import MemDepRow
6 from scoreboard.mem_fu_pending import MemFU_Pend
7 from scoreboard.mem_select import Mem_Rsv
8 from scoreboard.global_pending import GlobalPending
9
10 """
11
12 """
13
14 class MemFUDepMatrix(Elaboratable):
15 """ implements 1st phase Memory-to-FU Dependency Matrix
16 """
17 def __init__(self, n_fu_row, n_reg_col):
18 self.n_fu_row = n_fu_row # Y (FUs) ^v
19 self.n_reg_col = n_reg_col # X (Regs) <>
20 self.ld_i = Signal(n_reg_col, reset_less=True) # LD in (top)
21 self.st_i = Signal(n_reg_col, reset_less=True) # ST in (top)
22
23 # Register "Global" vectors for determining RaW and WaR hazards
24 self.ld_pend_i = Signal(n_reg_col, reset_less=True) # ld pending (top)
25 self.st_pend_i = Signal(n_reg_col, reset_less=True) # st pending (top)
26 self.v_ld_rsel_o = Signal(n_reg_col, reset_less=True) # ld pending (bot)
27 self.v_st_rsel_o = Signal(n_reg_col, reset_less=True) # st pending (bot)
28
29 self.issue_i = Signal(n_fu_row, reset_less=True) # Issue in (top)
30 self.go_ld_i = Signal(n_fu_row, reset_less=True) # Go LOAD in (left)
31 self.go_st_i = Signal(n_fu_row, reset_less=True) # Go STOR in (left)
32 self.go_die_i = Signal(n_fu_row, reset_less=True) # Go Die in (left)
33
34 # for Register File Select Lines (horizontal), per-reg
35 self.ld_rsel_o = Signal(n_reg_col, reset_less=True) # ld reg (bot)
36 self.st_rsel_o = Signal(n_reg_col, reset_less=True) # st reg (bot)
37
38 # for Function Unit "forward progress" (vertical), per-FU
39 self.ld_pend_o = Signal(n_fu_row, reset_less=True) # ld pending (right)
40 self.st_pend_o = Signal(n_fu_row, reset_less=True) # st pending (right)
41
42 def elaborate(self, platform):
43 m = Module()
44
45 # ---
46 # matrix of dependency cells
47 # ---
48 dm = Array(MemDepRow(self.n_reg_col) for r in range(self.n_fu_row))
49 for fu in range(self.n_fu_row):
50 setattr(m.submodules, "dr_fu%d" % fu, dm[fu])
51
52 # ---
53 # array of Function Unit Pending vectors
54 # ---
55 fupend = Array(MemFU_Pend(self.n_reg_col) for f in range(self.n_fu_row))
56 for fu in range(self.n_fu_row):
57 setattr(m.submodules, "fu_fu%d" % (fu), fupend[fu])
58
59 # ---
60 # array of Register Reservation vectors
61 # ---
62 regrsv = Array(Mem_Rsv(self.n_fu_row) for r in range(self.n_reg_col))
63 for rn in range(self.n_reg_col):
64 setattr(m.submodules, "rr_r%d" % (rn), regrsv[rn])
65
66 # ---
67 # connect Function Unit vector
68 # ---
69 ld_pend = []
70 st_pend = []
71 for fu in range(self.n_fu_row):
72 dc = dm[fu]
73 fup = fupend[fu]
74 ld_fwd_o = []
75 st_fwd_o = []
76 for rn in range(self.n_reg_col):
77 # accumulate cell fwd outputs for dest/src1
78 ld_fwd_o.append(dc.ld_fwd_o[rn])
79 st_fwd_o.append(dc.st_fwd_o[rn])
80 # connect cell fwd outputs to FU Vector in [Cat is gooood]
81 m.d.comb += [fup.ld_fwd_i.eq(Cat(*ld_fwd_o)),
82 fup.st_fwd_i.eq(Cat(*st_fwd_o)),
83 ]
84 # accumulate FU Vector outputs
85 ld_pend.append(fup.reg_ld_pend_o)
86 st_pend.append(fup.reg_st_pend_o)
87
88 # ... and output them from this module (vertical, width=FUs)
89 m.d.comb += self.ld_pend_o.eq(Cat(*ld_pend))
90 m.d.comb += self.st_pend_o.eq(Cat(*st_pend))
91
92 # ---
93 # connect Reg Selection vector
94 # ---
95 ld_rsel = []
96 st_rsel = []
97 for rn in range(self.n_reg_col):
98 rsv = regrsv[rn]
99 ld_rsel_o = []
100 st_rsel_o = []
101 for fu in range(self.n_fu_row):
102 dc = dm[fu]
103 # accumulate cell reg-select outputs dest/src1
104 ld_rsel_o.append(dc.ld_rsel_o[rn])
105 st_rsel_o.append(dc.st_rsel_o[rn])
106 # connect cell reg-select outputs to Reg Vector In
107 m.d.comb += [rsv.ld_rsel_i.eq(Cat(*ld_rsel_o)),
108 rsv.st_rsel_i.eq(Cat(*st_rsel_o)),
109 ]
110 # accumulate Reg-Sel Vector outputs
111 ld_rsel.append(rsv.ld_rsel_o)
112 st_rsel.append(rsv.st_rsel_o)
113
114 # ... and output them from this module (horizontal, width=REGs)
115 m.d.comb += self.ld_rsel_o.eq(Cat(*ld_rsel))
116 m.d.comb += self.st_rsel_o.eq(Cat(*st_rsel))
117
118 # ---
119 # connect Dependency Matrix dest/src1/issue to module d/s/s/i
120 # ---
121 for fu in range(self.n_fu_row):
122 dc = dm[fu]
123 # wire up inputs from module to row cell inputs (Cat is gooood)
124 m.d.comb += [dc.ld_i.eq(self.ld_i),
125 dc.st_i.eq(self.st_i),
126 dc.st_pend_i.eq(self.st_pend_i),
127 dc.ld_pend_i.eq(self.ld_pend_i),
128 ]
129
130 # accumulate rsel bits into read/write pending vectors.
131 st_pend_v = []
132 ld_pend_v = []
133 for fu in range(self.n_fu_row):
134 dc = dm[fu]
135 st_pend_v.append(dc.v_st_rsel_o)
136 ld_pend_v.append(dc.v_ld_rsel_o)
137 st_v = GlobalPending(self.n_reg_col, st_pend_v)
138 ld_v = GlobalPending(self.n_reg_col, ld_pend_v)
139 m.submodules.st_v = st_v
140 m.submodules.ld_v = ld_v
141
142 m.d.comb += self.v_st_rsel_o.eq(st_v.g_pend_o)
143 m.d.comb += self.v_ld_rsel_o.eq(ld_v.g_pend_o)
144
145 # ---
146 # connect Dep issue_i/go_st_i/go_ld_i to module issue_i/go_rd/go_wr
147 # ---
148 go_st_i = []
149 go_ld_i = []
150 go_die_i = []
151 issue_i = []
152 for fu in range(self.n_fu_row):
153 dc = dm[fu]
154 # accumulate cell fwd outputs for dest/src1
155 go_st_i.append(dc.go_st_i)
156 go_ld_i.append(dc.go_ld_i)
157 go_die_i.append(dc.go_die_i)
158 issue_i.append(dc.issue_i)
159 # wire up inputs from module to row cell inputs (Cat is gooood)
160 m.d.comb += [Cat(*go_st_i).eq(self.go_st_i),
161 Cat(*go_ld_i).eq(self.go_ld_i),
162 Cat(*go_die_i).eq(self.go_die_i),
163 Cat(*issue_i).eq(self.issue_i),
164 ]
165
166 return m
167
168 def __iter__(self):
169 yield self.ld_i
170 yield self.st_i
171 yield self.issue_i
172 yield self.go_ld_i
173 yield self.go_st_i
174 yield self.go_die_i
175 yield self.ld_rsel_o
176 yield self.st_rsel_o
177 yield self.ld_pend_o
178 yield self.st_pend_o
179 yield self.ld_pend_i
180 yield self.st_pend_i
181 yield self.ld_rsel_o
182 yield self.st_rsel_o
183
184 def ports(self):
185 return list(self)
186
187 def d_matrix_sim(dut):
188 """ XXX TODO
189 """
190 yield dut.ld_i.eq(1)
191 yield dut.issue_i.eq(1)
192 yield
193 yield dut.issue_i.eq(0)
194 yield
195 yield dut.st_i.eq(1)
196 yield dut.issue_i.eq(1)
197 yield
198 yield dut.issue_i.eq(0)
199 yield
200 yield dut.go_st_i.eq(1)
201 yield
202 yield dut.go_st_i.eq(0)
203 yield
204 yield dut.go_ld_i.eq(1)
205 yield
206 yield dut.go_ld_i.eq(0)
207 yield
208
209 def test_d_matrix():
210 dut = MemFUDepMatrix(n_fu_row=3, n_reg_col=3)
211 vl = rtlil.convert(dut, ports=dut.ports())
212 with open("test_fu_mem_matrix.il", "w") as f:
213 f.write(vl)
214
215 run_simulation(dut, d_matrix_sim(dut), vcd_name='test_fu_mem_matrix.vcd')
216
217 if __name__ == '__main__':
218 test_d_matrix()