1 from nmigen
.compat
.sim
import run_simulation
2 from nmigen
.cli
import verilog
, rtlil
3 from nmigen
import Module
, Signal
, Array
, Elaboratable
5 from soc
.scoremulti
.fu_fu_matrix
import FUFUDepMatrix
6 from soc
.scoreboard
.mdm
import FUMemMatchMatrix
9 class MemFunctionUnits(Elaboratable
):
11 def __init__(self
, n_ldsts
, addrbitwid
):
12 self
.n_ldsts
= n_ldsts
13 self
.bitwid
= addrbitwid
15 self
.st_i
= Signal(n_ldsts
, reset_less
=True) # Dest R# in
16 self
.ld_i
= Signal(n_ldsts
, reset_less
=True) # oper1 R# in
18 self
.g_int_ld_pend_o
= Signal(n_ldsts
, reset_less
=True)
19 self
.g_int_st_pend_o
= Signal(n_ldsts
, reset_less
=True)
21 self
.st_rsel_o
= Signal(n_ldsts
, reset_less
=True) # dest reg (bot)
22 self
.ld_rsel_o
= Signal(n_ldsts
, reset_less
=True) # src1 reg (bot)
24 self
.loadable_o
= Signal(n_ldsts
, reset_less
=True)
25 self
.storable_o
= Signal(n_ldsts
, reset_less
=True)
26 self
.addr_nomatch_o
= Signal(n_ldsts
, reset_less
=True)
28 self
.go_ld_i
= Signal(n_ldsts
, reset_less
=True)
29 self
.go_st_i
= Signal(n_ldsts
, reset_less
=True)
30 self
.go_die_i
= Signal(n_ldsts
, reset_less
=True)
31 self
.fn_issue_i
= Signal(n_ldsts
, reset_less
=True)
34 self
.addrs_i
= Array(Signal(self
.bitwid
, name
="addrs_i%d" % i
) \
35 for i
in range(n_ldsts
))
36 #self.addr_we_i = Signal(n_ldsts) # write-enable for incoming address
37 self
.addr_en_i
= Signal(n_ldsts
) # address latched in
38 self
.addr_rs_i
= Signal(n_ldsts
) # address deactivated
40 # Note: FURegs st_pend_o is also outputted from here, for use in WaWGrid
42 def elaborate(self
, platform
):
49 # Integer FU-FU Dep Matrix
50 intfudeps
= FUFUDepMatrix(n_fus
, n_fus
, 1, 1)
51 m
.submodules
.intfudeps
= intfudeps
52 # Integer FU-Reg Dep Matrix
53 intregdeps
= FUMemMatchMatrix(n_fus
, self
.bitwid
)
54 m
.submodules
.intregdeps
= intregdeps
56 # ok, because we do not know in advance what the AGEN (address gen)
57 # is, we have to make a transitive dependency set. i.e. the LD
58 # (or ST) being requested now must depend on ALL prior LDs *AND* STs.
59 # these get dropped very rapidly once AGEN is carried out.
62 # connect fureg matrix as a mem system
63 comb
+= self
.g_int_ld_pend_o
.eq(intregdeps
.v_rd_rsel_o
)
64 comb
+= self
.g_int_st_pend_o
.eq(intregdeps
.v_wr_rsel_o
)
66 comb
+= intregdeps
.rd_pend_i
.eq(intregdeps
.v_rd_rsel_o
)
67 comb
+= intregdeps
.wr_pend_i
.eq(intregdeps
.v_wr_rsel_o
)
69 comb
+= intfudeps
.rd_pend_i
.eq(intregdeps
.rd_pend_o
)
70 comb
+= intfudeps
.wr_pend_i
.eq(intregdeps
.wr_pend_o
)
71 self
.st_pend_o
= intregdeps
.wr_pend_o
# also output for use in WaWGrid
73 comb
+= intfudeps
.issue_i
.eq(self
.fn_issue_i
)
74 comb
+= intfudeps
.go_rd_i
[0].eq(self
.go_ld_i
)
75 comb
+= intfudeps
.go_wr_i
[0].eq(self
.go_st_i
)
76 comb
+= intfudeps
.go_die_i
.eq(self
.go_die_i
)
77 comb
+= self
.loadable_o
.eq(intfudeps
.readable_o
)
78 comb
+= self
.storable_o
.eq(intfudeps
.writable_o
)
79 comb
+= self
.addr_nomatch_o
.eq(intregdeps
.addr_nomatch_o
)
81 # Connect function issue / arrays, and dest/src1/src2
82 comb
+= intregdeps
.dest_i
.eq(self
.st_i
)
83 comb
+= intregdeps
.src_i
[0].eq(self
.ld_i
)
85 comb
+= intregdeps
.go_rd_i
.eq(self
.go_ld_i
)
86 comb
+= intregdeps
.go_wr_i
.eq(self
.go_st_i
)
87 comb
+= intregdeps
.go_die_i
.eq(self
.go_die_i
)
88 comb
+= intregdeps
.issue_i
.eq(self
.fn_issue_i
)
90 comb
+= self
.st_rsel_o
.eq(intregdeps
.dest_rsel_o
)
91 comb
+= self
.ld_rsel_o
.eq(intregdeps
.src_rsel_o
[0])
93 # connect address matching: these get connected to the Addr CUs
94 for i
in range(self
.n_ldsts
):
95 comb
+= intregdeps
.addrs_i
[i
].eq(self
.addrs_i
[i
])
96 #comb += intregdeps.addr_we_i.eq(self.addr_we_i)
97 comb
+= intregdeps
.addr_en_i
.eq(self
.addr_en_i
)
98 comb
+= intregdeps
.addr_rs_i
.eq(self
.addr_rs_i
)
105 yield self
.g_int_st_pend_o
106 yield self
.g_int_ld_pend_o
109 yield self
.loadable_o
110 yield self
.storable_o
114 yield self
.fn_issue_i
115 yield from self
.addrs_i
116 #yield self.addr_we_i
123 dut
= MemFunctionUnits(n_ldsts
=4, addrbitwid
=5)
124 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
125 with
open("test_memfu_matrix.il", "w") as f
:
128 #run_simulation(dut, dcell_sim(dut), vcd_name='test_fu_dcell.vcd')
130 if __name__
== '__main__':