+ # bit of a hack: treereduce needs a list with an item named "data_o"
+ if self.units:
+ data_o = treereduce(self.units)
+ comb += self.data_o.eq(data_o)
+
+ for i, alu in enumerate(self.units):
+ comb += alu.src1_i.eq(self.src1_i)
+ comb += alu.src2_i.eq(self.src2_i)
+
+ if not self.ldstmode:
+ return m
+
+ ldmem_l = []
+ stmem_l = []
+ go_ad_l = []
+ adr_rel_l = []
+ sto_rel_l = []
+ for alu in self.units:
+ adr_rel_l.append(alu.adr_rel_o)
+ sto_rel_l.append(alu.sto_rel_o)
+ ldmem_l.append(alu.load_mem_o)
+ stmem_l.append(alu.stwd_mem_o)
+ go_ad_l.append(alu.go_ad_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)
+
+ return m
+
+
+class CompUnitLDSTs(CompUnitsBase):
+
+ def __init__(self, rwid, opwid, mem):
+ """ Inputs:
+
+ * :rwid: bit width of register file(s) - both FP and INT
+ * :opwid: operand bit width
+ """
+ self.opwid = opwid
+
+ # inputs
+ self.oper_i = Signal(opwid, reset_less=True)
+ self.imm_i = Signal(rwid, reset_less=True)
+
+ # Int ALUs
+ add1 = ALU(rwid)
+ add2 = ALU(rwid)
+
+ units = []
+ for alu in [add1, add2]:
+ aluopwid = 4 # see compldst.py for "internal" opcode
+ units.append(LDSTCompUnit(rwid, aluopwid, alu, mem))
+
+ CompUnitsBase.__init__(self, rwid, units, ldstmode=True)
+
+ def elaborate(self, platform):
+ m = CompUnitsBase.elaborate(self, platform)
+ comb = m.d.comb
+
+ # 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.isalu_i.eq(0)
+
+ return m
+
+
+class CompUnitALUs(CompUnitsBase):
+
+ def __init__(self, rwid, opwid, n_alus):
+ """ Inputs:
+
+ * :rwid: bit width of register file(s) - both FP and INT
+ * :opwid: operand bit width
+ """
+ self.opwid = opwid
+
+ # inputs
+ self.oper_i = Signal(opwid, reset_less=True)
+ self.imm_i = Signal(rwid, reset_less=True)
+
+ # Int ALUs
+ alus = []
+ for i in range(n_alus):
+ alus.append(ALU(rwid))
+
+ units = []
+ for alu in alus:
+ aluopwid = 3 # extra bit for immediate mode
+ units.append(ComputationUnitNoDelay(rwid, aluopwid, alu))
+
+ CompUnitsBase.__init__(self, rwid, units)
+
+ def elaborate(self, platform):
+ m = CompUnitsBase.elaborate(self, platform)
+ comb = m.d.comb
+
+ # hand the same operation to all units, only lower 3 bits though
+ for alu in self.units:
+ comb += alu.oper_i[0:3].eq(self.oper_i)
+ comb += alu.imm_i.eq(self.imm_i)
+
+ return m
+
+
+class CompUnitBR(CompUnitsBase):
+
+ def __init__(self, rwid, opwid):
+ """ Inputs:
+
+ * :rwid: bit width of register file(s) - both FP and INT
+ * :opwid: operand bit width
+
+ Note: bgt unit is returned so that a shadow unit can be created
+ for it
+ """
+ self.opwid = opwid
+
+ # inputs
+ self.oper_i = Signal(opwid, reset_less=True)
+ self.imm_i = Signal(rwid, reset_less=True)
+
+ # Branch ALU and CU
+ self.bgt = BranchALU(rwid)
+ aluopwid = 3 # extra bit for immediate mode
+ self.br1 = ComputationUnitNoDelay(rwid, aluopwid, self.bgt)
+ CompUnitsBase.__init__(self, rwid, [self.br1])
+
+ def elaborate(self, platform):
+ m = CompUnitsBase.elaborate(self, platform)
+ comb = m.d.comb