m = Module()
comb = m.d.comb
op = self.i.ctx.op
+ xl_fields = self.fields.instrs['XL']
+ cr_output = Signal.like(self.i.cr)
+ comb += cr_output.eq(self.i.cr)
+
+ # Generate array for cr input so bits can be selected
+ cr_arr = Array([Signal() for _ in range(32)])
+ for i in range(32):
+ comb += cr_arr[i].eq(self.i.cr[31-i])
+
+ # Generate array for cr output so the bit to write to can be
+ # selected by a signal
+ cr_out_arr = Array([Signal() for _ in range(32)])
+ for i in range(32):
+ comb += cr_output[31-i].eq(cr_out_arr[i])
+ comb += cr_out_arr[i].eq(cr_arr[i])
+
with m.Switch(op.insn_type):
- pass
+ with m.Case(InternalOp.OP_MCRF):
+ bf = Signal(xl_fields['BF'][0:-1].shape())
+ comb += bf.eq(xl_fields['BF'][0:-1])
+ bfa = Signal(xl_fields['BFA'][0:-1].shape())
+ comb += bfa.eq(xl_fields['BFA'][0:-1])
+
+ for i in range(4):
+ comb += cr_out_arr[bf*4 + i].eq(cr_arr[bfa*4 + i])
+
+
+ comb += self.o.cr.eq(cr_output)
comb += self.o.ctx.eq(self.i.ctx)
return m
class TestCase:
- def __init__(self, program, regs, sprs, name):
+ def __init__(self, program, regs, sprs, cr, name):
self.program = program
self.regs = regs
self.sprs = sprs
self.name = name
+ self.cr = cr
def get_rec_width(rec):
recwidth = 0
def __init__(self, name):
super().__init__(name)
self.test_name = name
- def run_tst_program(self, prog, initial_regs=[0] * 32, initial_sprs={}):
- tc = TestCase(prog, initial_regs, initial_sprs, self.test_name)
+ def run_tst_program(self, prog, initial_regs=[0] * 32, initial_sprs={},
+ initial_cr=0):
+ tc = TestCase(prog, initial_regs, initial_sprs, initial_cr,
+ self.test_name)
test_data.append(tc)
def test_crand(self):
lst = ["crandc 1, 2, 3"]
self.run_tst_program(Program(lst))
+ def test_mcrf(self):
+ lst = ["mcrf 0, 5"]
+ cr = 0xffff0000
+ self.run_tst_program(Program(lst), initial_cr=cr)
+
def test_ilang(self):
rec = CompALUOpSubset()
print(test.name)
program = test.program
self.subTest(test.name)
- simulator = ISA(pdecode2, test.regs, test.sprs, 0)
+ simulator = ISA(pdecode2, test.regs, test.sprs, test.cr)
gen = program.generate_instructions()
instructions = list(zip(gen, program.assembly.splitlines()))
# ask the decoder to decode this binary data (endian'd)
yield pdecode2.dec.bigendian.eq(0) # little / big?
yield instruction.eq(ins) # raw binary instr.
+ yield alu.p.data_i.cr.eq(simulator.cr.get_range().value)
yield Settle()
fn_unit = yield pdecode2.e.fn_unit
self.assertEqual(fn_unit, Function.CR.value, code)
yield
vld = yield alu.n.valid_o
yield
- alu_out = yield alu.n.data_o.o
- 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)
+ cr_out = yield pdecode2.e.output_cr
+ if cr_out:
+ cr_expected = simulator.cr.get_range().value
+ cr_real = yield alu.n.data_o.cr
+ msg = f"real: {cr_expected:x}, actual: {cr_real:x}"
+ self.assertEqual(cr_expected, cr_real, msg)
sim.add_sync_process(process)
with sim.write_vcd("simulator.vcd", "simulator.gtkw",