diff --git a/src/lsu/subwordread.sv b/src/lsu/subwordread.sv index 593d01813..a5ccd12bf 100644 --- a/src/lsu/subwordread.sv +++ b/src/lsu/subwordread.sv @@ -29,39 +29,42 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module subwordread import cvw::*; #(parameter cvw_t P) ( - input logic [P.LLEN-1:0] ReadDataWordMuxM, - input logic [3:0] PAdrM, - input logic [2:0] Funct3M, - input logic FpLoadStoreM, - input logic BigEndianM, - output logic [P.LLEN-1:0] ReadDataM + input logic [P.LLEN-1:0] ReadDataWordMuxM, + input logic [3:0] PAdrM, + input logic [2:0] Funct3M, + input logic FpLoadStoreM, + input logic BigEndianM, + output logic [P.LLEN-1:0] ReadDataM ); + localparam ADRBITS = $clog2(P.LLEN)-3; + logic [ADRBITS-1:0] PAdrSwapM; logic [7:0] ByteM; logic [15:0] HalfwordM; logic [31:0] WordM; logic [63:0] DblWordM; - logic [ADRBITS-1:0] PAdrSwap; - // Funct3M[2] is the unsigned bit. mask upper bits. - // Funct3M[1:0] is the size of the memory access. - if (P.BIGENDIAN_SUPPORTED) assign PAdrSwap = PAdrM[ADRBITS-1:0] ^ {ADRBITS{BigEndianM}}; - else assign PAdrSwap = PAdrM[ADRBITS-1:0]; - assign ByteM = ReadDataWordMuxM[PAdrSwap*8 +: 8]; - assign HalfwordM = ReadDataWordMuxM[PAdrSwap[ADRBITS-1:1]*16 +: 16]; - if (P.LLEN >= 64) assign WordM = ReadDataWordMuxM[PAdrSwap[ADRBITS-1:2] * 32 +: 32]; - else assign WordM = ReadDataWordMuxM; - if (P.LLEN >= 64) assign DblWordM = ReadDataWordMuxM[PAdrSwap[ADRBITS-1] * 64 +: 64]; + // invert lsbs of address to select appropriate subword for big endian + if (P.BIGENDIAN_SUPPORTED) assign PAdrSwapM = PAdrM[ADRBITS-1:0] ^ {ADRBITS{BigEndianM}}; + else assign PAdrSwapM = PAdrM[ADRBITS-1:0]; + + // Use indexed part select to imply muxes to select each size of subword + if (P.LLEN == 128) mux2 #(64) dblmux(ReadDataWordMuxM[63:0], ReadDataWordMuxM[127:64], PAdrSwapM[3], DblWordM); + else if (P.LLEN == 64) assign DblWordM = ReadDataWordMuxM; + if (P.LLEN >= 64) mux2 #(32) wordmux(DblWordM[31:0], DblWordM[63:32], PAdrSwapM[2], WordM); + else assign WordM = ReadDataWordMuxM; + mux2 #(16) halfwordmux(WordM[15:0], WordM[31:16], PAdrSwapM[1], HalfwordM); + mux2 #(8) bytemux(HalfwordM[7:0], HalfwordM[15:8], PAdrSwapM[0], ByteM); // sign extension/ NaN boxing always_comb case(Funct3M) - 3'b000: ReadDataM = {{(P.LLEN-8){ByteM[7]}}, ByteM}; // lb - 3'b001: ReadDataM = {{P.LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh - 3'b010: ReadDataM = {{P.LLEN-32{WordM[31]|FpLoadStoreM}}, WordM[31:0]}; // lw/flw - 3'b011: if (P.LLEN >= 64) ReadDataM = {{P.LLEN-64{DblWordM[63]|FpLoadStoreM}}, DblWordM[63:0]}; // ld/fld - else ReadDataM = ReadDataWordMuxM; + 3'b000: ReadDataM = {{(P.LLEN-8){ByteM[7]}}, ByteM}; // lb + 3'b001: ReadDataM = {{P.LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh + 3'b010: ReadDataM = {{P.LLEN-32{WordM[31]|FpLoadStoreM}}, WordM[31:0]}; // lw/flw + 3'b011: if (P.LLEN >= 64) ReadDataM = {{P.LLEN-64{DblWordM[63]|FpLoadStoreM}}, DblWordM[63:0]}; // ld/fld + else ReadDataM = ReadDataWordMuxM; // shouldn't happen 3'b100: if (P.LLEN == 128) ReadDataM = FpLoadStoreM ? ReadDataWordMuxM : {{P.LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq else ReadDataM = {{P.LLEN-8{1'b0}}, ByteM[7:0]}; // lbu 3'b101: ReadDataM = {{P.LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu diff --git a/src/lsu/subwordwrite.sv b/src/lsu/subwordwrite.sv index 705672ff7..659d6d9c7 100644 --- a/src/lsu/subwordwrite.sv +++ b/src/lsu/subwordwrite.sv @@ -55,9 +55,9 @@ module subwordwrite #(parameter LLEN) ( end else begin:sww // 32-bit always_comb case(LSUFunct3M[1:0]) - 2'b00: LittleEndianWriteDataM = {4{IMAFWriteDataM[7:0]}}; // sb - 2'b01: LittleEndianWriteDataM = {2{IMAFWriteDataM[15:0]}}; // sh - 2'b10: LittleEndianWriteDataM = IMAFWriteDataM; // sw + 2'b00: LittleEndianWriteDataM = {4{IMAFWriteDataM[7:0]}}; // sb + 2'b01: LittleEndianWriteDataM = {2{IMAFWriteDataM[15:0]}}; // sh + 2'b10: LittleEndianWriteDataM = IMAFWriteDataM; // sw default: LittleEndianWriteDataM = IMAFWriteDataM; // shouldn't happen endcase end diff --git a/src/mmu/hptw.sv b/src/mmu/hptw.sv index 4e292ba3d..2a4288560 100644 --- a/src/mmu/hptw.sv +++ b/src/mmu/hptw.sv @@ -148,7 +148,6 @@ module hptw import cvw::*; #(parameter cvw_t P) ( flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrUpdateDAM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB) assign PRegEn = HPTWRW[1] & ~DCacheBusStallM | UpdatePTE; flopenr #(P.XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache - assert property(@(posedge clk) ~PRegEn | reset | NextPTE[0] !== 1'bx); // report writing an x PTE from an uninitialized page table // Assign PTE descriptors common across all XLEN values // For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table