From b5d07371fed9666cc3895da675081ef459596f75 Mon Sep 17 00:00:00 2001 From: Kristopher38 Date: Sat, 23 Jul 2022 23:21:16 +0200 Subject: [PATCH 1/2] Fix right shifts and sltu[i] instructions --- riscvmodel/insn.py | 16 ++++++++-------- riscvmodel/types.py | 5 ++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/riscvmodel/insn.py b/riscvmodel/insn.py index d1b00b8..991d1c7 100644 --- a/riscvmodel/insn.py +++ b/riscvmodel/insn.py @@ -163,7 +163,7 @@ def execute(self, model: Model): @isa("sltiu", RV32I, opcode=0b0010011, funct3=0b011) class InstructionSLTIU(InstructionIType): def execute(self, model: Model): - if model.state.intreg[self.rs1].unsigned() < int(self.imm): + if model.state.intreg[self.rs1].unsigned() < int(self.imm) & 0xFFFFFFFF: model.state.intreg[self.rd] = 1 else: model.state.intreg[self.rd] = 0 @@ -203,7 +203,7 @@ def execute(self, model: Model): @isa("srai", RV32I, opcode=0b0010011, funct3=0b101, funct7=0b0100000) class InstructionSRAI(InstructionISType): def execute(self, model: Model): - model.state.intreg[self.rd] = model.state.intreg[self.rs1] >> self.shamt + model.state.intreg[self.rd] = (model.state.intreg[self.rs1] & 0xFFFFFFFF) >> self.shamt @isa("add", RV32I, opcode=0b0110011, funct3=0b000, funct7=0b0000000) @@ -236,12 +236,12 @@ def execute(self, model: Model): @isa("sltu", RV32I, opcode=0b0110011, funct3=0b011, funct7=0b0000000) class InstructionSLTU(InstructionRType): - def execute(self, state: State): - if state.intreg[self.rs1].unsigned() < state.intreg[ + def execute(self, model: Model): + if model.state.intreg[self.rs1].unsigned() < model.state.intreg[ self.rs2].unsigned(): - state.intreg[self.rd] = 1 + model.state.intreg[self.rd] = 1 else: - state.intreg[self.rd] = 0 + model.state.intreg[self.rd] = 0 @isa("xor", RV32I, opcode=0b0110011, funct3=0b100, funct7=0b0000000) @@ -253,8 +253,8 @@ def execute(self, model: Model): @isa("srl", RV32I, opcode=0b0110011, funct3=0b101, funct7=0b0000000) class InstructionSRL(InstructionRType): def execute(self, model: Model): - src = model.state.intreg[self.rs1] - shift = model.state.intreg[self.rs2] & 0x1f + src = model.state.intreg[self.rs1].unsigned() + shift = int(model.state.intreg[self.rs2] & 0x1f) model.state.intreg[self.rd] = src >> shift diff --git a/riscvmodel/types.py b/riscvmodel/types.py index b59164a..90dd88f 100644 --- a/riscvmodel/types.py +++ b/riscvmodel/types.py @@ -226,11 +226,10 @@ def __lshift__(self, other): def __rshift__(self, other): new = Register(self.bits) - value = (self.value + 2**self.bits) if self.value < 0 else self.value if isinstance(other, int): - new.set(value >> other) + new.set(self.value >> other) elif isinstance(other, (Register, Immediate)): - new.set(value >> other.value) + new.set(self.value >> other.value) else: raise TypeError("unsupported operand type for Register >>: {}".format(other.__class__)) return new From 5180f0cf5cc2e5c421b3a13c7aa3027464fd376a Mon Sep 17 00:00:00 2001 From: Kristopher38 Date: Fri, 16 May 2025 18:28:18 +0200 Subject: [PATCH 2/2] Fix JALR, make memory deterministic, add support for halfword stores to memory --- riscvmodel/insn.py | 3 ++- riscvmodel/isa.py | 2 +- riscvmodel/model.py | 14 +++++++++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/riscvmodel/insn.py b/riscvmodel/insn.py index 991d1c7..6d8e10c 100644 --- a/riscvmodel/insn.py +++ b/riscvmodel/insn.py @@ -36,8 +36,9 @@ def execute(self, model: Model): @isa("jalr", RV32I, opcode=0b1100111, funct3=0b000) class InstructionJALR(InstructionIType): def execute(self, model: Model): + target = (model.state.intreg[self.rs1] + self.imm) & 0xFFFFFFFE model.state.intreg[self.rd] = model.state.pc + 4 - model.state.pc = model.state.intreg[self.rs1] + self.imm + model.state.pc = target @isa("beq", RV32I, opcode=0b1100011, funct3=0b000) diff --git a/riscvmodel/isa.py b/riscvmodel/isa.py index 868abdd..6e80626 100644 --- a/riscvmodel/isa.py +++ b/riscvmodel/isa.py @@ -331,7 +331,7 @@ def __str__(self) -> str: class InstructionILType(InstructionIType, metaclass=ABCMeta): """ - I-type instruction specialization for stores. The produce a different + I-type instruction specialization for loads. They produce a different assembler than the base class :param rd: Destination register diff --git a/riscvmodel/model.py b/riscvmodel/model.py index a297a9e..aeed546 100644 --- a/riscvmodel/model.py +++ b/riscvmodel/model.py @@ -79,20 +79,20 @@ def lb(self, address): word = address >> 2 offset = address % 4 if word not in self.memory: - self.memory[word] = randrange(0, 1 << 32) + return 0 return (self.memory[word] >> (offset*8)) & 0xff def lh(self, address): word = address >> 2 offset = (address >> 1) % 2 if word not in self.memory: - self.memory[word] = randrange(0, 1 << 32) - return (self.memory[word] >> (offset*16)) & 0xffff + return 0 + return (self.memory[word] >> (offset*16)) & 0xffff def lw(self, address): word = address >> 2 if word not in self.memory: - self.memory[word] = randrange(0, 1 << 32) + return 0 return self.memory[word] def sb(self, address, data): @@ -112,12 +112,16 @@ def commit(self): address = update.addr base = address >> 2 offset = address & 0x3 + offset_hw = address & 0x2 if base not in self.memory: - self.memory[base] = randrange(0, 1 << 32) + self.memory[base] = 0 data = update.data if update.gran == TraceMemory.GRANULARITY.BYTE: mask = ~(0xFF << (offset*8)) & 0xFFFFFFFF data = (self.memory[base] & mask) | (data << (offset*8)) + elif update.gran == TraceMemory.GRANULARITY.HALFWORD: + mask = ~(0xFFFF << (offset_hw*8)) & 0xFFFFFFFF + data = (self.memory[base] & mask) | (data << (offset_hw*8)) self.memory[base] = data self.memory_updates = []