m.d.sync += self.counter.eq(5)
with m.Elif(self.op == 3): # SHIFT to take 7
m.d.sync += self.counter.eq(7)
- with m.Elif(self.op == 1): # SUB to take 2
- m.d.sync += self.counter.eq(2)
- with m.Else(): # ADD to take 1, straight away
+ with m.Elif(self.op == 1): # SUB to take 1, straight away
m.d.sync += self.counter.eq(1)
+ with m.Else(): # ADD to take 2
+ m.d.sync += self.counter.eq(2)
m.d.comb += go_now.eq(1)
with m.Else():
# input says no longer valid, so drop ready as well.
self.go_die_i = Signal(n_units, reset_less=True)
if ldstmode:
self.go_ad_i = Signal(n_units, reset_less=True)
+ self.go_st_i = Signal(n_units, reset_less=True)
# outputs
self.busy_o = Signal(n_units, reset_less=True)
ldmem_l = []
stmem_l = []
go_ad_l = []
+ go_st_l = []
adr_rel_l = []
sto_rel_l = []
for alu in self.units:
ldmem_l.append(alu.load_mem_o)
stmem_l.append(alu.stwd_mem_o)
go_ad_l.append(alu.go_ad_i)
+ go_st_l.append(alu.go_st_i)
comb += self.adr_rel_o.eq(Cat(*adr_rel_l))
comb += self.sto_rel_o.eq(Cat(*sto_rel_l))
comb += self.load_mem_o.eq(Cat(*ldmem_l))
comb += self.stwd_mem_o.eq(Cat(*stmem_l))
comb += Cat(*go_ad_l).eq(self.go_ad_i)
+ comb += Cat(*go_st_l).eq(self.go_st_i)
return m
#---------
comb += memfus.fn_issue_i.eq(cul.issue_i) # Comp Unit Issue -> Mem FUs
comb += memfus.addr_we_i.eq(cul.adr_rel_o) # Match enable on adr rel
+ comb += memfus.addr_rs_i.eq(~cul.busy_o) # Match disable on busy off
+ # 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!
+
+ #comb += cul.go_wr_i.eq(memfus.loadable_o & memfus.addr_match_o)
+ #comb += cul.go_st_i.eq(memfus.storable_o & memfus.addr_match_o)
+
#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])
if False:
instrs = create_random_ops(dut, 15, True, 4)
- if True: # LD test (with immediate)
- instrs.append( (1, 2, 2, 0x10, 1, 20, (0, 0)) )
+ if True: # LD/ST test (with immediate)
+ instrs.append( (1, 2, 2, 0x10, 1, 1, (0, 0)) )
+ #instrs.append( (5, 6, 7, 0x10, 1, 1, (0, 0)) )
if False:
instrs.append( (1, 2, 2, 1, 1, 20, (0, 0)) )
from nmigen.cli import verilog, rtlil
from nmigen import Module, Signal, Const, Array, Cat, Elaboratable
-from nmutil.latch import latchregister
+from nmutil.latch import latchregister, SRLatch
class PartialAddrMatch(Elaboratable):
# inputs
self.addrs_i = Array(Signal(bitwid, name="addr") for i in range(n_adr))
self.addr_we_i = Signal(n_adr) # write-enable for incoming address
- self.addr_en_i = Signal(n_adr) # address activated (0 == ignore)
+ self.addr_en_i = Signal(n_adr) # address latched in
+ self.addr_rs_i = Signal(n_adr) # address deactivated
# output
self.addr_match_o = Array(Signal(n_adr, name="match_o") \
comb = m.d.comb
sync = m.d.sync
+ m.submodules.l = l = SRLatch(llen=self.n_adr, sync=False)
addrs_r = Array(Signal(self.bitwid, "a_r") for i in range(self.n_adr))
- ae_r = Signal(self.n_adr)
+
+ # latch set/reset
+ comb += l.s.eq(self.addr_en_i)
+ comb += l.r.eq(self.addr_rs_i)
# copy in addresses (and "enable" signals)
for i in range(self.n_adr):
- latchregister(m, self.addrs_i[i], addrs_r[i], self.addr_we_i[i])
- latchregister(m, self.addr_en_i[i], ae_r[i], self.addr_we_i[i])
+ latchregister(m, self.addrs_i[i], addrs_r[i], l.q[i])
# is there a clash, yes/no
for i in range(self.n_adr):
- match = []
+ nomatch = []
for j in range(self.n_adr):
if i == j:
- match.append(Const(0)) # don't match against self!
+ nomatch.append(Const(1)) # don't match against self!
else:
- match.append(addrs_r[i] == addrs_r[j])
- comb += self.addr_match_o[i].eq(Cat(*match) & ae_r)
+ nomatch.append(addrs_r[i] != addrs_r[j])
+ comb += self.addr_match_o[i].eq(Cat(*nomatch) & l.q)
return m
self.loadable_o = Signal(n_ldsts, reset_less=True)
self.storable_o = Signal(n_ldsts, reset_less=True)
+ #self.addr_match_o = Signal(n_ldsts, reset_less=True)
self.go_ld_i = Signal(n_ldsts, reset_less=True)
self.go_st_i = Signal(n_ldsts, reset_less=True)
self.addrs_i = Array(Signal(self.bitwid, name="addrs_i%d" % i) \
for i in range(n_ldsts))
self.addr_we_i = Signal(n_ldsts) # write-enable for incoming address
- self.addr_en_i = Signal(n_ldsts) # address activated (0 == ignore)
+ self.addr_en_i = Signal(n_ldsts) # address latched in
+ self.addr_rs_i = Signal(n_ldsts) # address deactivated
# Note: FURegs st_pend_o is also outputted from here, for use in WaWGrid
comb += intfudeps.go_die_i.eq(self.go_die_i)
comb += self.loadable_o.eq(intfudeps.readable_o)
comb += self.storable_o.eq(intfudeps.writable_o)
+ #comb += self.addr_match_o.eq(intregdeps.addr_match_o)
# Connect function issue / arrays, and dest/src1/src2
comb += intregdeps.dest_i.eq(self.st_i)
comb += intregdeps.addrs_i[i].eq(self.addrs_i[i])
comb += intregdeps.addr_we_i.eq(self.addr_we_i)
comb += intregdeps.addr_en_i.eq(self.addr_en_i)
+ comb += intregdeps.addr_rs_i.eq(self.addr_rs_i)
return m