--- /dev/null
+from soc.decoder.power_enums import (Function, Form, InternalOp,
+ In1Sel, In2Sel, In3Sel, OutSel, RC, LdstLen,
+ CryIn, get_csv, single_bit_flags,
+ get_signal_name, default_values)
+
+
+class MemorySim:
+ def __init__(self):
+ self.mem = {}
+
+
+class RegFile:
+ def __init__(self):
+ self.regfile = [0] * 32
+ self.sprs = {}
+
+ def write_reg(self, regnum, value):
+ print("Writing {:x} to reg r{}".format(value, regnum))
+ self.regfile[regnum] = value
+
+ def read_reg(self, regnum):
+ val = self.regfile[regnum]
+ print("Read {:x} from reg r{}".format(val, regnum))
+ return val
+
+
+class InternalOpSimulator:
+ def __init__(self):
+ self.mem_sim = MemorySim()
+ self.regfile = RegFile()
+
+ def execute_alu_op(self, op1, op2, internal_op):
+ print(internal_op)
+ if internal_op == InternalOp.OP_ADD.value:
+ return op1 + op2
+ elif internal_op == InternalOp.OP_AND.value:
+ return op1 & op2
+ else:
+ return 0
+
+ def alu_op(self, pdecode2):
+ internal_op = yield pdecode2.dec.op.internal_op
+ operand1 = 0
+ operand2 = 0
+ result = 0
+ r1_ok = yield pdecode2.e.read_reg1.ok
+ r2_ok = yield pdecode2.e.read_reg2.ok
+ r3_ok = yield pdecode2.e.read_reg3.ok
+ imm_ok = yield pdecode2.e.imm_data.ok
+ if r1_ok:
+ r1_sel = yield pdecode2.e.read_reg1.data
+ operand1 = self.regfile.read_reg(r1_sel)
+ elif r3_ok:
+ r3_sel = yield pdecode2.e.read_reg3.data
+ operand1 = self.regfile.read_reg(r3_sel)
+ if r2_ok:
+ r2_sel = yield pdecode2.e.read_reg2.data
+ operand2 = self.regfile.read_reg(r2_sel)
+ if imm_ok:
+ operand2 = yield pdecode2.e.imm_data.data
+
+ result = self.execute_alu_op(operand1, operand2, internal_op)
+ ro_ok = yield pdecode2.e.write_reg.ok
+ if ro_ok:
+ ro_sel = yield pdecode2.e.write_reg.data
+ self.regfile.write_reg(ro_sel, result)
+
+ def execute_op(self, pdecode2):
+ function = yield pdecode2.dec.op.function_unit
+ if function == Function.ALU.value:
+ yield from self.alu_op(pdecode2)
--- /dev/null
+from nmigen import Module, Signal
+from nmigen.back.pysim import Simulator, Delay
+from nmigen.test.utils import FHDLTestCase
+import unittest
+from soc.simulator.internalop_sim import InternalOpSimulator
+from soc.decoder.power_decoder import (create_pdecode)
+from soc.decoder.power_enums import (Function, InternalOp,
+ In1Sel, In2Sel, In3Sel,
+ OutSel, RC, LdstLen, CryIn,
+ single_bit_flags, Form, SPR,
+ get_signal_name, get_csv)
+from soc.decoder.power_decoder2 import (PowerDecode2)
+from soc.simulator.gas import get_assembled_instruction
+
+
+class Register:
+ def __init__(self, num):
+ self.num = num
+
+
+class InstrList:
+ def __init__(self, lst):
+ self.instrs = [x + "\n" for x in lst]
+
+ def generate_instructions(self):
+ return iter(self.instrs)
+
+
+class DecoderTestCase(FHDLTestCase):
+
+ def run_tst(self, generator, simulator):
+ m = Module()
+ comb = m.d.comb
+ instruction = Signal(32)
+
+ pdecode = create_pdecode()
+
+ m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
+ comb += pdecode2.dec.raw_opcode_in.eq(instruction)
+ sim = Simulator(m)
+ gen = generator.generate_instructions()
+
+ def process():
+ for ins in gen:
+ print("instr", ins.strip())
+
+ # turn the instruction into binary data (endian'd)
+ ibin = get_assembled_instruction(ins, 0)
+
+ # ask the decoder to decode this binary data (endian'd)
+ yield pdecode2.dec.bigendian.eq(0) # little / big?
+ yield instruction.eq(ibin) # raw binary instr.
+ yield Delay(1e-6)
+ yield from simulator.execute_op(pdecode2)
+
+ sim.add_process(process)
+ with sim.write_vcd("simulator.vcd", "simulator.gtkw",
+ traces=[pdecode2.ports()]):
+ sim.run()
+
+ def test_example(self):
+ lst = ["addi 1, 0, 0x1234",
+ "addi 2, 0, 0x5678",
+ "add 3, 1, 2",
+ "and 4, 1, 2"]
+ gen = InstrList(lst)
+
+ simulator = InternalOpSimulator()
+
+ self.run_tst(gen, simulator)
+
+
+if __name__ == "__main__":
+ unittest.main()