RegSpec.__init__(self, rwid, n_src, n_dst)
RecordObject.__init__(self, name)
self._subkls = subkls
+ n_src, n_dst = self._n_src, self._n_dst
# create source operands
src = []
* :n_dst: number of destination operands
"""
RegSpecALUAPI.__init__(self, rwid, alu)
- self.n_src, self.n_dst = n_src, n_dst
self.opsubsetkls = opsubsetkls
self.cu = cu = CompUnitRecord(opsubsetkls, rwid, n_src, n_dst)
+ n_src, n_dst = self.n_src, self.n_dst = cu._n_src, cu._n_dst
+ print ("n_src %d n_dst %d" % (self.n_src, self.n_dst))
# convenience names for src operands
for i in range(n_src):
drl = []
for i in range(self.n_dst):
name = "data_r%d" % i
- data_r = Signal(self.cu._get_srcwid(i), name=name, reset_less=True)
+ data_r = Signal(self.cu._get_dstwid(i), name=name, reset_less=True)
latchregister(m, self.get_out(i), data_r, req_l.q[i], name + "_l")
drl.append(data_r)
# 2nd operand in the input "regspec". see for example
# soc.fu.alu.pipe_data.ALUInputData
sl = []
+ print ("src_i", self.src_i)
for i in range(self.n_src):
sl.append([self.src_i[i], self.get_in(i), src_l.q[i], Const(1,1)])
from soc.decoder.isa.all import ISA
from soc.fu.alu.test.test_pipe_caller import TestCase, ALUTestCase, test_data
-from soc.fu.compunits import ALUFunctionUnit
+from soc.fu.compunits.compunits import ALUFunctionUnit
import random
-
-def set_alu_inputs(alu, dec2, sim):
+def set_cu_input(cu, idx, data):
+ yield cu.src_i[idx].eq(data)
+ while True:
+ rd_rel_o = yield cu.rd.rel[idx]
+ print ("rd_rel %d wait" % idx, rd_rel_o)
+ if rd_rel_o:
+ break
+ yield
+ yield cu.rd.go[idx].eq(1)
+ yield
+ yield cu.rd.go[idx].eq(0)
+
+
+def get_cu_output(cu, idx):
+ while True:
+ wr_relall_o = yield cu.wr.rel
+ wr_rel_o = yield cu.wr.rel[idx]
+ print ("wr_rel %d wait" % idx, hex(wr_relall_o), wr_rel_o)
+ if wr_rel_o:
+ break
+ yield
+ yield cu.wr.go[idx].eq(1)
+ yield
+ result = yield cu.dst_i[idx]
+ yield cu.wr.go[idx].eq(0)
+ return result
+
+
+def set_cu_inputs(cu, dec2, sim):
# TODO: see https://bugs.libre-soc.org/show_bug.cgi?id=305#c43
# detect the immediate here (with m.If(self.i.ctx.op.imm_data.imm_ok))
# and place it into data_i.b
else:
data1 = 0
- yield alu.p.data_i.a.eq(data1)
+ if reg3_ok or reg1_ok:
+ yield from set_cu_input(cu, 0, data1)
# If there's an immediate, set the B operand to that
reg2_ok = yield dec2.e.read_reg2.ok
- imm_ok = yield dec2.e.imm_data.imm_ok
- if imm_ok:
- data2 = yield dec2.e.imm_data.imm
- elif reg2_ok:
+ if reg2_ok:
data2 = yield dec2.e.read_reg2.data
data2 = sim.gpr(data2).value
else:
data2 = 0
- yield alu.p.data_i.b.eq(data2)
+
+ if reg2_ok:
+ yield from set_cu_input(cu, 1, data2)
+def set_operand(cu, dec2, sim):
+ yield from cu.oper_i.eq_from_execute1(dec2.e)
+ yield cu.issue_i.eq(1)
+ yield
+ yield cu.issue_i.eq(0)
+ yield
-def set_extra_alu_inputs(alu, dec2, sim):
+
+def set_extra_cu_inputs(cu, dec2, sim):
carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0
carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0
- yield alu.p.data_i.xer_ca[0].eq(carry)
- yield alu.p.data_i.xer_ca[1].eq(carry32)
+ yield from set_cu_input(cu, 2, carry | (carry32<<1))
so = 1 if sim.spr['XER'][XER_bits['SO']] else 0
- yield alu.p.data_i.xer_so.eq(so)
+ yield from set_cu_input(cu, 3, so)
m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
m.submodules.cu = cu = ALUFunctionUnit()
- comb += cu.oper_i.eq_from_execute1(pdecode2.e)
- comb += alu.p.valid_i.eq(1)
- comb += alu.n.ready_i.eq(1)
comb += pdecode2.dec.raw_opcode_in.eq(instruction)
sim = Simulator(m)
print(test.name)
program = test.program
self.subTest(test.name)
- simulator = ISA(pdecode2, test.regs, test.sprs, 0)
+ sim = ISA(pdecode2, test.regs, test.sprs, 0)
gen = program.generate_instructions()
instructions = list(zip(gen, program.assembly.splitlines()))
- index = simulator.pc.CIA.value//4
+ index = sim.pc.CIA.value//4
while index < len(instructions):
ins, code = instructions[index]
yield Settle()
fn_unit = yield pdecode2.e.fn_unit
self.assertEqual(fn_unit, Function.ALU.value)
- yield from set_alu_inputs(alu, pdecode2, simulator)
- yield from set_extra_alu_inputs(alu, pdecode2, simulator)
+ yield from set_operand(cu, pdecode2, sim)
+ yield from set_cu_inputs(cu, pdecode2, sim)
+ yield from set_extra_cu_inputs(cu, pdecode2, sim)
yield
opname = code.split(' ')[0]
- yield from simulator.call(opname)
- index = simulator.pc.CIA.value//4
+ yield from sim.call(opname)
+ index = sim.pc.CIA.value//4
- vld = yield alu.n.valid_o
- while not vld:
- yield
- vld = yield alu.n.valid_o
- yield
- alu_out = yield alu.n.data_o.o.data
out_reg_valid = yield pdecode2.e.write_reg.ok
if out_reg_valid:
write_reg_idx = yield pdecode2.e.write_reg.data
- expected = simulator.gpr(write_reg_idx).value
- print(f"expected {expected:x}, actual: {alu_out:x}")
- self.assertEqual(expected, alu_out, code)
- yield from self.check_extra_alu_outputs(alu, pdecode2,
- simulator, code)
+ expected = sim.gpr(write_reg_idx).value
+ cu_out = yield from get_cu_output(cu, 0)
+ print(f"expected {expected:x}, actual: {cu_out:x}")
+ self.assertEqual(expected, cu_out, code)
+ yield from self.check_extra_cu_outputs(cu, pdecode2,
+ sim, code)
sim.add_sync_process(process)
with sim.write_vcd("simulator.vcd", "simulator.gtkw",
traces=[]):
sim.run()
- def check_extra_alu_outputs(self, alu, dec2, sim, code):
+ def check_extra_cu_outputs(self, cu, dec2, sim, code):
rc = yield dec2.e.rc.data
if rc:
cr_expected = sim.crl[0].get_range().value
- cr_actual = yield alu.n.data_o.cr0.data
+ cr_actual = yield cu.n.data_o.cr0.data
self.assertEqual(cr_expected, cr_actual, code)
op = yield dec2.e.insn_type
if op == InternalOp.OP_CMP.value or \
op == InternalOp.OP_CMPEQB.value:
bf = yield dec2.dec.BF
- cr_actual = yield alu.n.data_o.cr0.data
+ cr_actual = yield cu.n.data_o.cr0.data
cr_expected = sim.crl[bf].get_range().value
self.assertEqual(cr_expected, cr_actual, code)
cry_out = yield dec2.e.output_carry
if cry_out:
expected_carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0
- real_carry = yield alu.n.data_o.xer_ca.data[0] # XXX CO not CO32
+ real_carry = yield cu.n.data_o.xer_ca.data[0] # XXX CO not CO32
self.assertEqual(expected_carry, real_carry, code)
expected_carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0
- real_carry32 = yield alu.n.data_o.xer_ca.data[1] # XXX CO32
+ real_carry32 = yield cu.n.data_o.xer_ca.data[1] # XXX CO32
self.assertEqual(expected_carry32, real_carry32, code)