+ #---------
+ # Memory Function Unit
+ #---------
+ reset_b = Signal(cul.n_units, reset_less=True)
+ sync += reset_b.eq(cul.go_st_i | cul.go_wr_i | cul.go_die_i)
+
+
+ comb += memfus.fn_issue_i.eq(cul.issue_i) # Comp Unit Issue -> Mem FUs
+ comb += memfus.addr_en_i.eq(cul.adr_rel_o) # Match enable on adr rel
+ comb += memfus.addr_rs_i.eq(reset_b) # reset same as LDSTCompUnit
+
+ # LD/STs have to accumulate prior LD/STs (TODO: multi-issue as well,
+ # in a transitive fashion). This cycle activates based on LDSTCompUnit
+ # issue_i. multi-issue gets a bit more complex but not a lot.
+ prior_ldsts = Signal(cul.n_units, reset_less=True)
+ sync += prior_ldsts.eq(memfus.g_int_ld_pend_o | memfus.g_int_st_pend_o)
+ with m.If(self.ls_oper_i[2]): # LD bit of operand
+ comb += memfus.ld_i.eq(cul.issue_i | prior_ldsts)
+ with m.If(self.ls_oper_i[3]): # ST bit of operand
+ comb += memfus.st_i.eq(cul.issue_i | prior_ldsts)
+
+ # TODO: adr_rel_o needs to go into L1 Cache. for now,
+ # just immediately activate go_adr
+ comb += cul.go_ad_i.eq(cul.adr_rel_o)
+
+ # connect up address data
+ comb += memfus.addrs_i[0].eq(cul.units[0].data_o)
+ comb += memfus.addrs_i[1].eq(cul.units[1].data_o)
+
+ # connect loadable / storable to go_ld/go_st.
+ # XXX should only be done when the memory ld/st has actually happened!
+ go_st_i = Signal(cul.n_units, reset_less=True)
+ go_ld_i = Signal(cul.n_units, reset_less=True)
+ comb += go_ld_i.eq(memfus.storable_o & memfus.addr_nomatch_o &\
+ cul.req_rel_o & cul.ld_o)
+ comb += go_st_i.eq(memfus.storable_o & memfus.addr_nomatch_o &\
+ cul.sto_rel_o & cul.st_o)
+ comb += memfus.go_ld_i.eq(go_ld_i)
+ comb += memfus.go_st_i.eq(go_st_i)
+ #comb += cul.go_wr_i.eq(memfus.loadable_o & memfus.addr_nomatch_o)
+ comb += cul.go_st_i.eq(go_st_i)
+
+ #comb += cu.go_rd_i[0:n_intfus].eq(go_rd_o[0:n_intfus])
+ #comb += cu.go_wr_i[0:n_intfus].eq(go_wr_o[0:n_intfus])
+ #comb += cu.issue_i[0:n_intfus].eq(fn_issue_o[0:n_intfus])
+