diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index f53bb9296..15b2c673d 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -417,7 +417,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( // Subword Accesses ///////////////////////////////////////////////////////////////////////////////////////////// - subwordread #(P.LLEN) subwordread(.ReadDataWordMuxM(LittleEndianReadDataWordM), .PAdrM(PAdrM[2:0]), .BigEndianM, + subwordread #(P) subwordread(.ReadDataWordMuxM(LittleEndianReadDataWordM), .PAdrM(PAdrM[3:0]), .BigEndianM, .FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM); subwordwrite #(P.LLEN) subwordwrite(.LSUFunct3M, .IMAFWriteDataM, .LittleEndianWriteDataM); diff --git a/src/lsu/subwordread.sv b/src/lsu/subwordread.sv index 82fb80fb1..593d01813 100644 --- a/src/lsu/subwordread.sv +++ b/src/lsu/subwordread.sv @@ -28,98 +28,44 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -module subwordread #(parameter LLEN) - ( - input logic [LLEN-1:0] ReadDataWordMuxM, - input logic [2:0] PAdrM, +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 [LLEN-1:0] ReadDataM + output logic [P.LLEN-1:0] ReadDataM ); + localparam ADRBITS = $clog2(P.LLEN)-3; logic [7:0] ByteM; logic [15:0] HalfwordM; - logic [2:0] PAdrSwap; + 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. - assign PAdrSwap = PAdrM ^ {3{BigEndianM}}; + 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 (LLEN == 64) begin:swrmux - // ByteMe mux - always_comb - case(PAdrSwap[2:0]) - 3'b000: ByteM = ReadDataWordMuxM[7:0]; - 3'b001: ByteM = ReadDataWordMuxM[15:8]; - 3'b010: ByteM = ReadDataWordMuxM[23:16]; - 3'b011: ByteM = ReadDataWordMuxM[31:24]; - 3'b100: ByteM = ReadDataWordMuxM[39:32]; - 3'b101: ByteM = ReadDataWordMuxM[47:40]; - 3'b110: ByteM = ReadDataWordMuxM[55:48]; - 3'b111: ByteM = ReadDataWordMuxM[63:56]; - endcase - - // halfword mux - always_comb - case(PAdrSwap[2:1]) - 2'b00: HalfwordM = ReadDataWordMuxM[15:0]; - 2'b01: HalfwordM = ReadDataWordMuxM[31:16]; - 2'b10: HalfwordM = ReadDataWordMuxM[47:32]; - 2'b11: HalfwordM = ReadDataWordMuxM[63:48]; - endcase - - logic [31:0] WordM; - - always_comb - case(PAdrSwap[2]) - 1'b0: WordM = ReadDataWordMuxM[31:0]; - 1'b1: WordM = ReadDataWordMuxM[63:32]; - endcase + if (P.LLEN >= 64) assign DblWordM = ReadDataWordMuxM[PAdrSwap[ADRBITS-1] * 64 +: 64]; - logic [63:0] DblWordM; - assign DblWordM = ReadDataWordMuxM[63:0]; - - // sign extension/ NaN boxing - always_comb + // sign extension/ NaN boxing + always_comb case(Funct3M) - 3'b000: ReadDataM = {{LLEN-8{ByteM[7]}}, ByteM}; // lb - 3'b001: ReadDataM = {{LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh - 3'b010: ReadDataM = {{LLEN-32{WordM[31]|FpLoadStoreM}}, WordM[31:0]}; // lw/flw - 3'b011: ReadDataM = {{LLEN-64{DblWordM[63]|FpLoadStoreM}}, DblWordM[63:0]}; // ld/fld - 3'b100: ReadDataM = {{LLEN-8{1'b0}}, ByteM[7:0]}; // lbu - //3'b100: ReadDataM = FpLoadStoreM ? ReadDataWordMuxM : {{LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq - only needed when LLEN=128 - 3'b101: ReadDataM = {{LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu - 3'b110: ReadDataM = {{LLEN-32{1'b0}}, WordM[31:0]}; // lwu - default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen + 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'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 + 3'b110: ReadDataM = {{P.LLEN-32{1'b0}}, WordM[31:0]}; // lwu + default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen endcase - - end else begin:swrmux // 32-bit - // byte mux - always_comb - case(PAdrSwap[1:0]) - 2'b00: ByteM = ReadDataWordMuxM[7:0]; - 2'b01: ByteM = ReadDataWordMuxM[15:8]; - 2'b10: ByteM = ReadDataWordMuxM[23:16]; - 2'b11: ByteM = ReadDataWordMuxM[31:24]; - endcase - - // halfword mux - always_comb - case(PAdrSwap[1]) - 1'b0: HalfwordM = ReadDataWordMuxM[15:0]; - 1'b1: HalfwordM = ReadDataWordMuxM[31:16]; - endcase - - // sign extension - always_comb - case(Funct3M) - 3'b000: ReadDataM = {{LLEN-8{ByteM[7]}}, ByteM}; // lb - 3'b001: ReadDataM = {{LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh - 3'b010: ReadDataM = {{LLEN-32{ReadDataWordMuxM[31]|FpLoadStoreM}}, ReadDataWordMuxM[31:0]}; // lw/flw - 3'b011: ReadDataM = ReadDataWordMuxM; // fld - 3'b100: ReadDataM = {{LLEN-8{1'b0}}, ByteM[7:0]}; // lbu - 3'b101: ReadDataM = {{LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu - default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen - endcase - end endmodule