1 from nmigen
.compat
.sim
import run_simulation
2 from nmigen
.cli
import verilog
, rtlil
3 from nmigen
import Module
, Signal
, Elaboratable
, Cat
5 from soc
.scoreboard
.mem_dependence_cell
import MemDepRow
6 from soc
.scoreboard
.mem_fu_pending
import MemFU_Pend
7 from soc
.scoreboard
.mem_select
import Mem_Rsv
8 from soc
.scoreboard
.global_pending
import GlobalPending
14 class MemFUDepMatrix(Elaboratable
):
15 """ implements 1st phase Memory-to-FU Dependency Matrix
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)
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)
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)
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)
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)
42 def elaborate(self
, platform
):
46 # matrix of dependency cells
48 dm
= tuple(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
])
53 # array of Function Unit Pending vectors
55 fupend
= tuple(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
])
60 # array of Register Reservation vectors
62 regrsv
= tuple(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
])
67 # connect Function Unit vector
71 for fu
in range(self
.n_fu_row
):
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
)),
84 # accumulate FU Vector outputs
85 ld_pend
.append(fup
.reg_ld_pend_o
)
86 st_pend
.append(fup
.reg_st_pend_o
)
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
))
93 # connect Reg Selection vector
97 for rn
in range(self
.n_reg_col
):
101 for fu
in range(self
.n_fu_row
):
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
)),
110 # accumulate Reg-Sel Vector outputs
111 ld_rsel
.append(rsv
.ld_rsel_o
)
112 st_rsel
.append(rsv
.st_rsel_o
)
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
))
119 # connect Dependency Matrix dest/src1/issue to module d/s/s/i
121 for fu
in range(self
.n_fu_row
):
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
),
130 # accumulate rsel bits into read/write pending vectors.
133 for fu
in range(self
.n_fu_row
):
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
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
)
146 # connect Dep issue_i/go_st_i/go_ld_i to module issue_i/go_rd/go_wr
152 for fu
in range(self
.n_fu_row
):
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
),
187 def d_matrix_sim(dut
):
191 yield dut
.issue_i
.eq(1)
193 yield dut
.issue_i
.eq(0)
196 yield dut
.issue_i
.eq(1)
198 yield dut
.issue_i
.eq(0)
200 yield dut
.go_st_i
.eq(1)
202 yield dut
.go_st_i
.eq(0)
204 yield dut
.go_ld_i
.eq(1)
206 yield dut
.go_ld_i
.eq(0)
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
:
215 run_simulation(dut
, d_matrix_sim(dut
), vcd_name
='test_fu_mem_matrix.vcd')
217 if __name__
== '__main__':