* :addr_o: Address out (LD or ST)
"""
- def __init__(self, rwid, alu, mem, n_src=2, n_dst=1):
+ def __init__(self, rwid, alu, mem, n_src=2, n_dst=1, debugtest=False):
self.rwid = rwid
self.alu = alu
self.mem = mem
+ self.debugtest = debugtest
self.counter = Signal(4)
src = []
op_is_st = Signal(reset_less=True)
op_ldst = Signal(reset_less=True)
op_is_imm = Signal(reset_less=True)
+
+ # ALU/LD data output control
alulatch = Signal(reset_less=True)
+ ldlatch = Signal(reset_less=True)
# src2 register
src2_r = Signal(self.rwid, reset_less=True)
# TODO: think about moving these to another module
+ if self.debugtest:
+ return m
+
# connect ST to memory. NOTE: unit *must* be set back
# to start again by dropping go_st_i on next clock
with m.If(self.stwd_mem_o):
# connect LD to memory. NOTE: unit *must* be set back
# to start again by dropping go_ad_i on next clock
+ rdport = self.mem.rdport
+ ldd_r = Signal(self.rwid, reset_less=True) # Dest register
+ # latch LD-out
+ latchregister(m, rdport.data, ldd_r, ldlatch, "ldo_r")
+ sync += ldlatch.eq(self.load_mem_o)
with m.If(self.load_mem_o):
- rdport = self.mem.rdport
comb += rdport.addr.eq(self.addr_o)
- comb += self.data_o.eq(rdport.data)
# comb += rdport.en.eq(1) # only when transparent=False
+ # if LD-latch, put ld-reg out onto output
+ with m.If(ldlatch | self.load_mem_o):
+ comb += self.data_o.eq(ldd_r)
+
return m
def __iter__(self):
self.opwid = opwid
# inputs
- self.oper_i = Signal(opwid, reset_less=True)
- self.imm_i = Signal(rwid, reset_less=True)
+ self.op = CompALUOpSubset("cua_i")
# Int ALUs
self.alus = []
self.alus.append(ALU(rwid))
units = []
- for alu in self.alus:
- units.append(LDSTCompUnit(rwid, alu, mem))
+ for i, alu in enumerate(self.alus):
+ # XXX disable the 2nd memory temporarily
+ if i == 0:
+ debugtest = False
+ else:
+ debugtest = True
+ units.append(LDSTCompUnit(rwid, alu, mem, debugtest=debugtest))
CompUnitsBase.__init__(self, rwid, units, ldstmode=True)
# hand the same operation to all units, 4 lower bits though
for alu in self.units:
- comb += alu.oper_i[0:4].eq(self.oper_i)
- #comb += alu.imm_i.eq(self.imm_i)
+ comb += alu.oper_i.eq(self.op)
comb += alu.isalu_i.eq(0)
return m
self.br_oper_i = Signal(4, reset_less=True)
self.br_imm_i = Signal(rwid, reset_less=True)
self.ls_oper_i = Signal(4, reset_less=True)
- self.ls_imm_i = Signal(rwid, reset_less=True)
# inputs
self.int_dest_i = Signal(range(n_regs), reset_less=True) # Dest R# in
comb += cua.op.eq(self.alu_op)
comb += cub.oper_i.eq(self.br_oper_i)
comb += cub.imm_i.eq(self.br_imm_i)
- comb += cul.oper_i.eq(self.ls_oper_i)
- comb += cul.imm_i.eq(self.ls_imm_i)
+ comb += cul.op.eq(self.alu_op) # TODO: separate ls_op?
# TODO: issueunit.f (FP)
# choose a Function-Unit-Group
with m.If(fu == Function.ALU): # alu
comb += sc.alu_op.eq_from_execute1(instr)
- comb += sc.aluissue.insn_i.eq(1)
+ comb += sc.aluissue.insn_i.eq(1) # enable alu issue
comb += wait_issue_alu.eq(1)
+ with m.Elif(fu == Function.LDST): # ld/st
+ comb += sc.alu_op.eq_from_execute1(instr) # XXX separate ls_op?
+ comb += sc.lsissue.insn_i.eq(1) # enable ldst issue
+ comb += wait_issue_ls.eq(1)
+
with m.Elif((op & (0x3 << 2)) != 0): # branch
comb += sc.br_oper_i.eq(Cat(op[0:2], opi))
comb += sc.br_imm_i.eq(imm)
comb += sc.brissue.insn_i.eq(1)
comb += wait_issue_br.eq(1)
- with m.Elif((op & (0x3 << 4)) != 0): # ld/st
- # see compldst.py
- # bit 0: ADD/SUB
- # bit 1: immed
- # bit 4: LD
- # bit 5: ST
- comb += sc.ls_oper_i.eq(Cat(op[0], opi[0], op[4:6]))
- comb += sc.ls_imm_i.eq(imm)
- comb += sc.lsissue.insn_i.eq(1)
- comb += wait_issue_ls.eq(1)
-
# XXX TODO
# these indicate that the instruction is to be made
# shadow-dependent on
alusim.setval(i, val)
# create some instructions
- lst = ["addi 2, 0, 0x4321",
- "addi 3, 0, 0x1234",
- "add 1, 3, 2",
- "add 4, 3, 5"
- ]
+ lst = []
+ if False:
+ lst += ["addi 2, 0, 0x4321",
+ "addi 3, 0, 0x1234",
+ "add 1, 3, 2",
+ "add 4, 3, 5"
+ ]
+ if True:
+ lst += [ "lbz 6, 7(2)",
+ ]
+
with Program(lst) as program:
gen = program.generate_instructions()