From: Michael Nolan Date: Mon, 23 Mar 2020 14:53:53 +0000 (-0400) Subject: Add memory loads and stores to simulator X-Git-Tag: div_pipeline~1647 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a0e1af6c5dab5c324a8bf3a7ce6eb665d26a65c1;p=soc.git Add memory loads and stores to simulator --- diff --git a/src/soc/simulator/internalop_sim.py b/src/soc/simulator/internalop_sim.py index 035277b4..2f435dc7 100644 --- a/src/soc/simulator/internalop_sim.py +++ b/src/soc/simulator/internalop_sim.py @@ -2,11 +2,29 @@ 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) +import math class MemorySim: - def __init__(self): + def __init__(self, bytes_per_word=8): self.mem = {} + self.bytes_per_word = bytes_per_word + self.word_log2 = math.ceil(math.log2(bytes_per_word)) + + # TODO: Implement ld/st of lesser width + def ld(self, address): + address = address >> self.word_log2 + if address in self.mem: + val = self.mem[address] + else: + val = 0 + print("Read {:x} from addr {:x}".format(val, address)) + return val + + def st(self, address, value): + address = address >> self.word_log2 + print("Writing {:x} to addr {:x}".format(value, address)) + self.mem[address] = value class RegFile: @@ -23,6 +41,13 @@ class RegFile: print("Read {:x} from reg r{}".format(val, regnum)) return val + def assert_gprs(self, gprs): + for k,v in list(gprs.items()): + reg_val = self.read_reg(k) + msg = "reg r{} got {:x}, expecting {:x}".format( + k, reg_val, v) + assert reg_val == v, msg + class InternalOpSimulator: def __init__(self): @@ -36,7 +61,7 @@ class InternalOpSimulator: elif internal_op == InternalOp.OP_AND.value: return op1 & op2 else: - return 0 + assert(False, "Not implemented") def alu_op(self, pdecode2): internal_op = yield pdecode2.dec.op.internal_op @@ -65,7 +90,28 @@ class InternalOpSimulator: ro_sel = yield pdecode2.e.write_reg.data self.regfile.write_reg(ro_sel, result) + def mem_op(self, pdecode2): + internal_op = yield pdecode2.dec.op.internal_op + addr_reg = yield pdecode2.e.read_reg1.data + addr = self.regfile.read_reg(addr_reg) + + imm_ok = yield pdecode2.e.imm_data.ok + if imm_ok: + imm = yield pdecode2.e.imm_data.data + addr += imm + if internal_op == InternalOp.OP_STORE.value: + val_reg = yield pdecode2.e.read_reg3.data + val = self.regfile.read_reg(val_reg) + self.mem_sim.st(addr, val) + elif internal_op == InternalOp.OP_LOAD.value: + dest_reg = yield pdecode2.e.write_reg.data + val = self.mem_sim.ld(addr) + self.regfile.write_reg(dest_reg, val) + + def execute_op(self, pdecode2): function = yield pdecode2.dec.op.function_unit if function == Function.ALU.value: yield from self.alu_op(pdecode2) + elif function == Function.LDST.value: + yield from self.mem_op(pdecode2) diff --git a/src/soc/simulator/test_sim.py b/src/soc/simulator/test_sim.py index d26aaf72..3a5e37b9 100644 --- a/src/soc/simulator/test_sim.py +++ b/src/soc/simulator/test_sim.py @@ -68,6 +68,26 @@ class DecoderTestCase(FHDLTestCase): simulator = InternalOpSimulator() self.run_tst(gen, simulator) + simulator.regfile.assert_gprs( + {1: 0x1234, + 2: 0x5678, + 3: 0x68ac, + 4: 0x1230}) + + def test_ldst(self): + lst = ["addi 1, 0, 0x1234", + "addi 2, 0, 0x5678", + "stw 1, 0(2)", + "lwz 3, 0(2)"] + gen = InstrList(lst) + + simulator = InternalOpSimulator() + + self.run_tst(gen, simulator) + simulator.regfile.assert_gprs( + {1: 0x1234, + 2: 0x5678, + 3: 0x1234}) if __name__ == "__main__":