diff --git a/src/lsu/align.sv b/src/lsu/align.sv index 7da314ffd..8a48f310d 100644 --- a/src/lsu/align.sv +++ b/src/lsu/align.sv @@ -107,7 +107,20 @@ module align import cvw::*; #(parameter cvw_t P) ( logic [OFFSET_BIT_POS-1:$clog2(LLENINBYTES)] WordOffsetM; logic [$clog2(LLENINBYTES)-1:0] ByteOffsetM; logic HalfSpillM, WordSpillM; + logic [$clog2(LLENINBYTES)-1:0] AccessByteOffsetM; + assign {WordOffsetM, ByteOffsetM} = IEUAdrM[OFFSET_BIT_POS-1:0]; + + always_comb begin + case (Funct3M[1:0]) + 2'b00: AccessByteOffsetM = '0; // byte access + 2'b01: AccessByteOffsetM = {2'b00, ByteOffsetM[0]}; // half access + 2'b10: AccessByteOffsetM = {1'b0, ByteOffsetM[1:0]}; // word access + 2'b11: AccessByteOffsetM = ByteOffsetM; // double access + default: AccessByteOffsetM = ByteOffsetM; + endcase + end + assign HalfSpillM = (IEUAdrM[OFFSET_BIT_POS-1:1] == '1) & (ByteOffsetM[0] != '0) & Funct3M[1:0] == 2'b01; assign WordSpillM = (IEUAdrM[OFFSET_BIT_POS-1:2] == '1) & (ByteOffsetM[1:0] != '0) & Funct3M[1:0] == 2'b10; if(P.LLEN == 64) begin @@ -170,7 +183,7 @@ module align import cvw::*; #(parameter cvw_t P) ( // shifter (4:1 mux for 32 bit, 8:1 mux for 64 bit) // 8 * is for shifting by bytes not bits - assign ReadDataWordSpillShiftedM = ReadDataWordSpillAllM >> (MisalignedM ? 8 * ByteOffsetM : '0); + assign ReadDataWordSpillShiftedM = ReadDataWordSpillAllM >> (MisalignedM ? 8 * AccessByteOffsetM : '0); assign DCacheReadDataWordSpillM = ReadDataWordSpillShiftedM[P.LLEN-1:0]; // write path. Also has the 8:1 shifter muxing for the byteoffset @@ -178,7 +191,7 @@ module align import cvw::*; #(parameter cvw_t P) ( logic [P.LLEN*2-1:0] LSUWriteDataShiftedM; logic [P.LLEN*3-1:0] LSUWriteDataShiftedExtM; // *** RT: Find a better way. I've extending in both directions so we don't shift in zeros. The cache expects the writedata to not have any zero data, but instead replicated data. - assign LSUWriteDataShiftedExtM = {LSUWriteDataM, LSUWriteDataM, LSUWriteDataM} << (MisalignedM ? 8 * ByteOffsetM : '0); + assign LSUWriteDataShiftedExtM = {LSUWriteDataM, LSUWriteDataM, LSUWriteDataM} << (MisalignedM ? 8 * AccessByteOffsetM : '0); assign LSUWriteDataShiftedM = LSUWriteDataShiftedExtM[P.LLEN*3-1:P.LLEN]; assign LSUWriteDataSpillM = LSUWriteDataShiftedM; //mux2 #(2*P.LLEN) writedataspillmux(LSUWriteDataShiftedM, {LSUWriteDataShiftedM[P.LLEN*2-1:P.LLEN], LSUWriteDataShiftedM[P.LLEN*2-1:P.LLEN]}, SelSpillM, LSUWriteDataSpillM); diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-misaligned-access-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-misaligned-access-01.reference_output index b0a7caeb3..b8051ecdb 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-misaligned-access-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-misaligned-access-01.reference_output @@ -500,7 +500,7 @@ deadbeef # Double7DstData 78777675 7c7b7a79 de7f7e7d -0fffffff #signature +ffffffff #signature ffffffff ffffffff ffffffff diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-misaligned-access-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-misaligned-access-01.S index 2ee4e021c..3ff89a237 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-misaligned-access-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-misaligned-access-01.S @@ -255,7 +255,7 @@ CheckAllWriteSignature: # check values half by half addi a0, s0, 1 # SourceData+1 - addi a1, s1, 0 # ie: ByteDstData + addi a1, s1, 1 # ie: ByteDstData+1 slli a2, s2, 2 # * 4 -1 addi a2, a2, -1 jal ra, memcmp2 @@ -272,7 +272,7 @@ CheckAllWriteSignature: # check values word by word addi a0, s0, 1 # SourceData+1 - addi a1, s1, 0 # ie: ByteDstData + addi a1, s1, 1 # ie: ByteDstData+1 slli a2, s2, 1 # * 2 -1 addi a2, a2, -1 jal ra, memcmp4 @@ -281,7 +281,7 @@ CheckAllWriteSignature: # check values word by word addi a0, s0, 2 # SourceData+2 - addi a1, s1, 0 # ie: ByteDstData + addi a1, s1, 2 # ie: ByteDstData+2 slli a2, s2, 1 # * 2 -1 addi a2, a2, -1 jal ra, memcmp4 @@ -290,7 +290,7 @@ CheckAllWriteSignature: # check values word by word addi a0, s0, 3 # SourceData+3 - addi a1, s1, 0 # ie: ByteDstData + addi a1, s1, 3 # ie: ByteDstData+3 slli a2, s2, 1 # * 2 -1 addi a2, a2, -1 jal ra, memcmp4 @@ -306,7 +306,7 @@ CheckAllWriteSignature: # check values double by double addi a0, s0, 1 # SourceData+1 - addi a1, s1, 0 # ie: ByteDstData + addi a1, s1, 1 # ie: ByteDstData+1 slli a2, s2, 0 # * 1 -1 addi a2, a2, -1 jal ra, memcmp8 @@ -314,7 +314,7 @@ CheckAllWriteSignature: # check values double by double addi a0, s0, 2 # SourceData+2 - addi a1, s1, 0 # ie: ByteDstData + addi a1, s1, 2 # ie: ByteDstData+2 slli a2, s2, 0 # * 1 -1 addi a2, a2, -1 jal ra, memcmp8 @@ -322,7 +322,7 @@ CheckAllWriteSignature: # check values double by double addi a0, s0, 3 # SourceData+3 - addi a1, s1, 2 # ie: ByteDstData + addi a1, s1, 3 # ie: ByteDstData+3 slli a2, s2, 0 # * 1 -1 addi a2, a2, -1 jal ra, memcmp8 @@ -330,7 +330,7 @@ CheckAllWriteSignature: # check values double by double addi a0, s0, 4 # SourceData+4 - addi a1, s1, 0 # ie: ByteDstData + addi a1, s1, 4 # ie: ByteDstData+4 slli a2, s2, 0 # * 1 -1 addi a2, a2, -1 jal ra, memcmp8 @@ -338,7 +338,7 @@ CheckAllWriteSignature: # check values double by double addi a0, s0, 5 # SourceData+5 - addi a1, s1, 0 # ie: ByteDstData + addi a1, s1, 5 # ie: ByteDstData+5 slli a2, s2, 0 # * 1 -1 addi a2, a2, -1 jal ra, memcmp8 @@ -346,7 +346,7 @@ CheckAllWriteSignature: # check values double by double addi a0, s0, 6 # SourceData+6 - addi a1, s1, 0 # ie: ByteDstData + addi a1, s1, 6 # ie: ByteDstData+6 slli a2, s2, 0 # * 1 -1 addi a2, a2, -1 jal ra, memcmp8 @@ -354,7 +354,7 @@ CheckAllWriteSignature: # check values double by double addi a0, s0, 7 # SourceData+7 - addi a1, s1, 0 # ie: ByteDstData + addi a1, s1, 7 # ie: ByteDstData+7 slli a2, s2, 0 # * 1 addi a2, a2, -1 jal ra, memcmp8