Fixed that non word aligned loads would not have the data shifted. Also fixed signed loads.
diff --git a/verilog/rtl/ExperiarCore/RV32ICore.v b/verilog/rtl/ExperiarCore/RV32ICore.v index f9cfe5e..856946e 100644 --- a/verilog/rtl/ExperiarCore/RV32ICore.v +++ b/verilog/rtl/ExperiarCore/RV32ICore.v
@@ -294,10 +294,10 @@ wire[31:0] targetMemoryAddress = state == STATE_FETCH ? programCounter : state == STATE_EXECUTE ? aluAPlusB: 32'b0; - wire loadSigned = (funct3 == 3'b100) || (funct3 == 3'b101); - wire loadStoreWord = funct3 == 3'b010; - wire loadStoreHalf = funct3[1:0] == 3'b01; + wire loadSigned = (funct3 == 3'b000) || (funct3 == 3'b001); wire loadStoreByte = funct3[1:0] == 2'b00; + wire loadStoreHalf = funct3[1:0] == 2'b01; + wire loadStoreWord = funct3 == 3'b010; reg[3:0] baseByteMask; always @(*) begin if (state == STATE_FETCH) baseByteMask <= 4'b1111; @@ -309,6 +309,33 @@ end else baseByteMask <= 4'b0000; end + reg signExtend; + always @(*) begin + if (loadSigned) begin + if (loadStoreByte) begin + case (targetMemoryAddress[1:0]) + 2'b00: signExtend <= memoryDataRead[7]; + 2'b01: signExtend <= memoryDataRead[15]; + 2'b10: signExtend <= memoryDataRead[23]; + 2'b11: signExtend <= memoryDataRead[31]; + endcase + end else if (loadStoreHalf) begin + case (targetMemoryAddress[1:0]) + 2'b00: signExtend <= memoryDataRead[15]; + 2'b01: signExtend <= memoryDataRead[23]; + 2'b10: signExtend <= memoryDataRead[31]; + 2'b11: signExtend <= 1'b0; + endcase + end else begin + signExtend <= 1'b0; + end + end else begin + signExtend <= 1'b0; + end + end + + wire[7:0] signExtendByte = signExtend ? 8'hFF : 8'h00; + wire[6:0] loadStoreByteMask = {3'b0, baseByteMask} << targetMemoryAddress[1:0]; wire loadStoreByteMaskValid = |(loadStoreByteMask[3:0]); wire addressMissaligned = |loadStoreByteMask[6:4]; @@ -320,20 +347,74 @@ wire[31:0] loadData = shouldLoad && !shouldStore ? dataIn : 32'b0; wire[31:0] storeData = shouldStore && !shouldLoad ? rs2 : 32'b0; + + reg[31:0] dataIn; + always @(*) begin + case (targetMemoryAddress[1:0]) + 2'b00: dataIn = { + loadStoreByteMask[3] ? memoryDataRead[31:24] : signExtendByte, + loadStoreByteMask[2] ? memoryDataRead[23:16] : signExtendByte, + loadStoreByteMask[1] ? memoryDataRead[15:8] : signExtendByte, + loadStoreByteMask[0] ? memoryDataRead[7:0] : 8'h00 + }; - wire[31:0] dataIn = { - loadStoreByteMask[3] ? memoryDataRead[31:24] : 8'h00, - loadStoreByteMask[2] ? memoryDataRead[23:16] : 8'h00, - loadStoreByteMask[1] ? memoryDataRead[15:8] : 8'h00, - loadStoreByteMask[0] ? memoryDataRead[7:0] : 8'h00 - }; + 2'b01: dataIn = { + signExtendByte, + loadStoreByteMask[3] ? memoryDataRead[31:24] : signExtendByte, + loadStoreByteMask[2] ? memoryDataRead[23:16] : signExtendByte, + loadStoreByteMask[1] ? memoryDataRead[15:8] : 8'h00 + }; - assign memoryDataWrite = { - loadStoreByteMask[3] ? storeData[31:24] : 8'h00, - loadStoreByteMask[2] ? storeData[23:16] : 8'h00, - loadStoreByteMask[1] ? storeData[15:8] : 8'h00, - loadStoreByteMask[0] ? storeData[7:0] : 8'h00 - }; + 2'b10: dataIn = { + signExtendByte, + signExtendByte, + loadStoreByteMask[3] ? memoryDataRead[31:24] : signExtendByte, + loadStoreByteMask[2] ? memoryDataRead[23:16] : 8'h00 + }; + + 2'b11: dataIn = { + signExtendByte, + signExtendByte, + signExtendByte, + loadStoreByteMask[3] ? memoryDataRead[31:24] : 8'h00 + }; + endcase + end + + reg[31:0] dataOut; + always @(*) begin + case (targetMemoryAddress[1:0]) + 2'b00: dataOut = { + loadStoreByteMask[3] ? storeData[31:24] : 8'h00, + loadStoreByteMask[2] ? storeData[23:16] : 8'h00, + loadStoreByteMask[1] ? storeData[15:8] : 8'h00, + loadStoreByteMask[0] ? storeData[7:0] : 8'h00 + }; + + 2'b01: dataOut = { + loadStoreByteMask[2] ? storeData[23:16] : 8'h00, + loadStoreByteMask[1] ? storeData[15:8] : 8'h00, + loadStoreByteMask[0] ? storeData[7:0] : 8'h00, + 8'h00 + }; + + 2'b10: dataOut = { + loadStoreByteMask[1] ? storeData[15:8] : 8'h00, + loadStoreByteMask[0] ? storeData[7:0] : 8'h00, + 8'h00, + 8'h00 + }; + + 2'b11: dataOut = { + loadStoreByteMask[0] ? storeData[7:0] : 8'h00, + 8'h00, + 8'h00, + 8'h00 + }; + endcase + end + + assign memoryDataWrite = dataOut; assign memoryWriteEnable = shouldStore; assign memoryReadEnable = shouldLoad;