from nmigen.compat.sim import run_simulation
from nmigen.cli import verilog, rtlil
+from nmigen.hdl.ast import unsigned
from nmigen import Module, Const, Signal, Array, Cat, Elaboratable, Memory
from regfile.regfile import RegFileArray, treereduce
def __init__(self, regwid, addrw):
self.ddepth = 1 # regwid //8
depth = (1<<addrw) // self.ddepth
- self.adr = Signal(addrw)
- self.dat_r = Signal(regwid)
- self.dat_w = Signal(regwid)
- self.we = Signal()
self.mem = Memory(width=regwid, depth=depth, init=range(0, depth))
def elaborate(self, platform):
m = Module()
- m.submodules.rdport = rdport = self.mem.read_port()
- m.submodules.wrport = wrport = self.mem.write_port()
- m.d.comb += [
- rdport.addr.eq(self.adr[self.ddepth:]), # ignore low bits
- self.dat_r.eq(rdport.data),
- wrport.addr.eq(self.adr),
- wrport.data.eq(self.dat_w),
- wrport.en.eq(self.we),
- ]
+ m.submodules.rdport = self.rdport = self.mem.read_port()
+ m.submodules.wrport = self.wrport = self.mem.write_port()
return m
self.req_rel_o = Signal(n_units, reset_less=True)
self.load_mem_o = Signal(n_units, reset_less=True)
self.stwd_mem_o = Signal(n_units, reset_less=True)
+ self.addr_o = Signal(rwid, reset_less=True)
# in/out register data (note: not register#, actual data)
self.data_o = Signal(rwid, reset_less=True)
# connect data register input/output
# merge (OR) all integer FU / ALU outputs to a single value
- # bit of a hack: treereduce needs a list with an item named "data_o"
if self.units:
- data_o = treereduce(self.units)
+ data_o = treereduce(self.units, "data_o")
comb += self.data_o.eq(data_o)
+ if self.ldstmode:
+ addr_o = treereduce(self.units, "addr_o")
+ comb += self.addr_o.eq(addr_o)
for i, alu in enumerate(self.units):
comb += alu.src1_i.eq(self.src1_i)
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.ld_o.eq(Cat(*ld_l))
+ comb += self.st_o.eq(Cat(*st_l))
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))
self.intregs = RegFileArray(rwid, n_regs)
self.fpregs = RegFileArray(rwid, n_regs)
+ # Memory (test for now)
+ self.mem = TestMemory(self.rwid, 8) # not too big, takes too long
+
# issue q needs to get at these
self.aluissue = IssueUnitGroup(2)
self.lsissue = IssueUnitGroup(2)
self.ls_imm_i = Signal(rwid, reset_less=True)
# inputs
- self.int_dest_i = Signal(max=n_regs, reset_less=True) # Dest R# in
- self.int_src1_i = Signal(max=n_regs, reset_less=True) # oper1 R# in
- self.int_src2_i = Signal(max=n_regs, reset_less=True) # oper2 R# in
+ self.int_dest_i = Signal(range(n_regs), reset_less=True) # Dest R# in
+ self.int_src1_i = Signal(range(n_regs), reset_less=True) # oper1 R# in
+ self.int_src2_i = Signal(range(n_regs), reset_less=True) # oper2 R# in
self.reg_enable_i = Signal(reset_less=True) # enable reg decode
# outputs
m.submodules.intregs = self.intregs
m.submodules.fpregs = self.fpregs
+ m.submodules.mem = mem = self.mem
# register ports
int_dest = self.intregs.write_port("dest")
# Memory FUs
m.submodules.memfus = memfus = MemFunctionUnits(n_ldsts, 5)
+ # Memory Priority Picker 1: one gateway per memory port
+ mempick1 = GroupPicker(n_ldsts) # picks 1 reader and 1 writer to intreg
+ m.submodules.mempick1 = mempick1
+
# Count of number of FUs
n_intfus = n_int_alus
n_fp_fus = 0 # for now
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
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)
+ comb += memfus.addrs_i[0].eq(cul.units[0].addr_o)
+ comb += memfus.addrs_i[1].eq(cul.units[1].addr_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 &\
+ comb += go_ld_i.eq(memfus.loadable_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_wr_i.eq(go_ld_i)
comb += cul.go_st_i.eq(go_st_i)
#comb += cu.go_rd_i[0:n_intfus].eq(go_rd_o[0:n_intfus])
self.opw = opwid
self.n_regs = n_regs
- mqbits = (int(log(qlen) / log(2))+2, False)
+ mqbits = unsigned(int(log(qlen) / log(2))+2)
self.p_add_i = Signal(mqbits) # instructions to add (from data_i)
self.p_ready_o = Signal() # instructions were added
self.data_i = Instruction.nq(n_in, "data_i", rwid, opwid)
iq = InstructionQ(self.rwid, self.opw, self.qlen, self.n_in, self.n_out)
sc = Scoreboard(self.rwid, self.n_regs)
- mem = TestMemory(self.rwid, 8) # not too big, takes too long
m.submodules.iq = iq
m.submodules.sc = sc
- m.submodules.mem = mem
# get at the regfile for testing
self.intregs = sc.intregs
if False:
instrs = create_random_ops(dut, 15, True, 4)
- if True: # LD/ST test (with immediate)
- instrs.append( (1, 2, 2, 0x10, 1, 1, (0, 0)) )
- instrs.append( (1, 2, 7, 0x12, 1, 1, (0, 0)) )
+ if False: # LD/ST test (with immediate)
+ instrs.append( (1, 2, 0, 0x10, 1, 1, (0, 0)) )
+ #instrs.append( (1, 2, 0, 0x10, 1, 1, (0, 0)) )
- if False:
+ if True:
instrs.append( (1, 2, 2, 1, 1, 20, (0, 0)) )
- if False:
- instrs.append( (7, 3, 2, 4, (0, 0)) )
- instrs.append( (7, 6, 6, 2, (0, 0)) )
- instrs.append( (1, 7, 2, 2, (0, 0)) )
+ if True:
+ instrs.append( (7, 3, 2, 4, 0, 0, (0, 0)) )
+ instrs.append( (7, 6, 6, 2, 0, 0, (0, 0)) )
+ instrs.append( (1, 7, 2, 2, 0, 0, (0, 0)) )
- if False:
+ if True:
instrs.append((2, 3, 3, 0, 0, 0, (0, 0)))
instrs.append((5, 3, 3, 1, 0, 0, (0, 0)))
instrs.append((3, 5, 5, 2, 0, 0, (0, 0)))