Merge pull request #157 from davidharrishmc/dev

Merged branch fix
This commit is contained in:
Ross Thompson 2023-03-24 10:49:45 -05:00 committed by GitHub
commit 6eae7dda14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 251 additions and 183 deletions

View File

@ -35,8 +35,8 @@ set -e # break on error
# Modify accordingly for your machine # Modify accordingly for your machine
# Increasing NUM_THREADS will speed up parallel compilation of the tools # Increasing NUM_THREADS will speed up parallel compilation of the tools
NUM_THREADS=2 # for low memory machines > 16GiB #NUM_THREADS=2 # for low memory machines > 16GiB
#NUM_THREADS=8 # for >= 32GiB NUM_THREADS=8 # for >= 32GiB
#NUM_THREADS=16 # for >= 64GiB #NUM_THREADS=16 # for >= 64GiB
sudo mkdir -p $RISCV sudo mkdir -p $RISCV

View File

@ -24,11 +24,22 @@
#// and limitations under the License. #// and limitations under the License.
#//////////////////////////////////////////////////////////////////////////////////////////////// #////////////////////////////////////////////////////////////////////////////////////////////////
# LZA (i<64) statement confuses coverage tool
# This is ugly to exlcude the whole file - is there a better option
coverage exclude -srcfile lzc.sv
######################
# Toggle exclusions
# Not used because toggle coverage isn't measured
######################
# Exclude DivBusyE from all design units because rv64gc uses the fdivsqrt unit for integer division # Exclude DivBusyE from all design units because rv64gc uses the fdivsqrt unit for integer division
coverage exclude -togglenode DivBusyE -du * #coverage exclude -togglenode DivBusyE -du *
# Exclude QuotM and RemM from MDU because rv64gc uses the fdivsqrt rather tha div unit for integer division # Exclude QuotM and RemM from MDU because rv64gc uses the fdivsqrt rather tha div unit for integer division
coverage exclude -togglenode /dut/core/mdu/mdu/QuotM #coverage exclude -togglenode /dut/core/mdu/mdu/QuotM
coverage exclude -togglenode /dut/core/mdu/mdu/RemM #coverage exclude -togglenode /dut/core/mdu/mdu/RemM
# StallFCause is hardwired to 0 # StallFCause is hardwired to 0
coverage exclude -togglenode /dut/core/hzu/StallFCause #coverage exclude -togglenode /dut/core/hzu/StallFCause

View File

@ -162,7 +162,7 @@ def run_test_case(config):
"""Run the given test case, and return 0 if the test suceeds and 1 if it fails""" """Run the given test case, and return 0 if the test suceeds and 1 if it fails"""
logname = "logs/"+config.variant+"_"+config.name+".log" logname = "logs/"+config.variant+"_"+config.name+".log"
cmd = config.cmd.format(logname) cmd = config.cmd.format(logname)
print(cmd) # print(cmd)
os.chdir(regressionDir) os.chdir(regressionDir)
os.system(cmd) os.system(cmd)
if search_log_for_text(config.grepstr, logname): if search_log_for_text(config.grepstr, logname):

View File

@ -56,7 +56,7 @@ module ebufsmarb (
logic IFUReqD; // 1 cycle delayed IFU request. Part of arbitration logic IFUReqD; // 1 cycle delayed IFU request. Part of arbitration
logic FinalBeat, FinalBeatD; // Indicates the last beat of a burst logic FinalBeat, FinalBeatD; // Indicates the last beat of a burst
logic BeatCntEn; logic BeatCntEn;
logic [4-1:0] NextBeatCount, BeatCount; // Position within a burst transfer logic [3:0] BeatCount; // Position within a burst transfer
logic CntReset; logic CntReset;
logic [3:0] Threshold; // Number of beats derived from HBURST logic [3:0] Threshold; // Number of beats derived from HBURST
@ -91,31 +91,36 @@ module ebufsmarb (
// This is necessary because the pipeline is stalled for the entire duration of both transactions, // This is necessary because the pipeline is stalled for the entire duration of both transactions,
// and the LSU memory request will stil be active. // and the LSU memory request will stil be active.
flopr #(1) ifureqreg(HCLK, ~HRESETn, IFUReq, IFUReqD); flopr #(1) ifureqreg(HCLK, ~HRESETn, IFUReq, IFUReqD);
assign LSUDisable = CurrState == ARBITRATE ? 1'b0 : (IFUReqD & ~(HREADY & FinalBeatD)); assign LSUDisable = (CurrState == ARBITRATE) ? 1'b0 : (IFUReqD & ~(HREADY & FinalBeatD));
assign LSUSelect = NextState == ARBITRATE ? 1'b1: LSUReq; assign LSUSelect = (NextState == ARBITRATE) ? 1'b1: LSUReq;
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Burst mode logic // Burst mode logic
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
flopenr #(4) BeatCountReg(HCLK, ~HRESETn | CntReset | FinalBeat, BeatCntEn, NextBeatCount, BeatCount);
assign NextBeatCount = BeatCount + 1'b1;
assign CntReset = NextState == IDLE; assign CntReset = NextState == IDLE;
assign FinalBeat = (BeatCount == Threshold); // Detect when we are waiting on the final access. assign FinalBeat = (BeatCount == Threshold); // Detect when we are waiting on the final access.
assign BeatCntEn = (NextState == ARBITRATE & HREADY); assign BeatCntEn = (NextState == ARBITRATE) & HREADY;
counter #(4) BeatCounter(HCLK, ~HRESETn | CntReset | FinalBeat, BeatCntEn, BeatCount);
// Used to store data from data phase of AHB. // Used to store data from data phase of AHB.
flopenr #(1) FinalBeatReg(HCLK, ~HRESETn | CntReset, BeatCntEn, FinalBeat, FinalBeatD); flopenr #(1) FinalBeatReg(HCLK, ~HRESETn | CntReset, BeatCntEn, FinalBeat, FinalBeatD);
// unlike the bus fsm in lsu/ifu, we need to derive the number of beats from HBURST. // unlike the bus fsm in lsu/ifu, we need to derive the number of beats from HBURST.
always_comb begin // HBURST[2:1] Beats
case(HBURST) // 00 1
// 01 4
// 10 8
// 11 16
always_comb
if (HBURST[2:1] == 2'b00) Threshold = 4'b0000;
else Threshold = (2 << HBURST[2:1]) - 1;
/* case(HBURST)
0: Threshold = 4'b0000; 0: Threshold = 4'b0000;
3: Threshold = 4'b0011; // INCR4 3: Threshold = 4'b0011; // INCR4
5: Threshold = 4'b0111; // INCR8 5: Threshold = 4'b0111; // INCR8
7: Threshold = 4'b1111; // INCR16 7: Threshold = 4'b1111; // INCR16
default: Threshold = 4'b0000; // INCR without end. default: Threshold = 4'b0000; // INCR without end.
endcase endcase
end end */
endmodule endmodule

View File

@ -123,7 +123,7 @@ module fctrl (
7'b00001??: ControlsD = `FCTRLW'b1_0_01_10_111_0_0_0; // fsub 7'b00001??: ControlsD = `FCTRLW'b1_0_01_10_111_0_0_0; // fsub
7'b00010??: ControlsD = `FCTRLW'b1_0_01_10_100_0_0_0; // fmul 7'b00010??: ControlsD = `FCTRLW'b1_0_01_10_100_0_0_0; // fmul
7'b00011??: ControlsD = `FCTRLW'b1_0_01_01_xx0_1_0_0; // fdiv 7'b00011??: ControlsD = `FCTRLW'b1_0_01_01_xx0_1_0_0; // fdiv
7'b01011??: ControlsD = `FCTRLW'b1_0_01_01_xx1_1_0_0; // fsqrt 7'b01011??: if (Rs2D == 5'b0000) ControlsD = `FCTRLW'b1_0_01_01_xx1_1_0_0; // fsqrt
7'b00100??: case(Funct3D) 7'b00100??: case(Funct3D)
3'b000: ControlsD = `FCTRLW'b1_0_00_xx_000_0_0_0; // fsgnj 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_000_0_0_0; // fsgnj
3'b001: ControlsD = `FCTRLW'b1_0_00_xx_001_0_0_0; // fsgnjn 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_001_0_0_0; // fsgnjn
@ -141,7 +141,8 @@ module fctrl (
3'b000: ControlsD = `FCTRLW'b0_1_00_xx_011_0_0_0; // fle 3'b000: ControlsD = `FCTRLW'b0_1_00_xx_011_0_0_0; // fle
default: ControlsD = `FCTRLW'b0_0_00_xx_000__0_1_0; // non-implemented instruction default: ControlsD = `FCTRLW'b0_0_00_xx_000__0_1_0; // non-implemented instruction
endcase endcase
7'b11100??: if (Funct3D == 3'b001) ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000)
ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass
else if (Funct3D[1:0] == 2'b00) ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w to int reg else if (Funct3D[1:0] == 2'b00) ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w to int reg
else if (Funct3D[1:0] == 2'b01) ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.d to int reg else if (Funct3D[1:0] == 2'b01) ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.d to int reg
else ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction else ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction

View File

@ -69,6 +69,6 @@ module fdivsqrtexpcalc(
assign SExp = {SXExp[`NE+1], SXExp[`NE+1:1]} + {2'b0, Bias}; assign SExp = {SXExp[`NE+1], SXExp[`NE+1:1]} + {2'b0, Bias};
// correct exponent for subnormal input's normalization shifts // correct exponent for subnormal input's normalization shifts
assign DExp = ({2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(`NE+1-`DIVBLEN){1'b0}}, m} + {3'b0, Bias}) & {`NE+2{~XZero}}; // *** why Xzero? Is this a hack for postprocessor? assign DExp = ({2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(`NE+1-`DIVBLEN){1'b0}}, m} + {3'b0, Bias});
assign Qe = Sqrt ? SExp : DExp; assign Qe = Sqrt ? SExp : DExp;
endmodule endmodule

View File

@ -32,7 +32,7 @@ module lzc #(parameter WIDTH = 1) (
always_comb begin always_comb begin
i = 0; i = 0;
while (~num[WIDTH-1-i] & (i < WIDTH)) i = i+1; // search for leading one while ((i < WIDTH) & ~num[WIDTH-1-i]) i = i+1; // search for leading one
ZeroCnt = i[$clog2(WIDTH+1)-1:0]; ZeroCnt = i[$clog2(WIDTH+1)-1:0];
end end
endmodule endmodule

View File

@ -31,11 +31,12 @@
module alu #(parameter WIDTH=32) ( module alu #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, B, // Operands input logic [WIDTH-1:0] A, B, // Operands
input logic [2:0] ALUControl, // With Funct3, indicates operation to perform input logic W64, // W64-type instruction
input logic SubArith, // Subtraction or arithmetic shift
input logic [2:0] ALUSelect, // ALU mux select signal input logic [2:0] ALUSelect, // ALU mux select signal
input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
input logic [2:0] ZBBSelect, // ZBB mux select signal input logic [2:0] ZBBSelect, // ZBB mux select signal
input logic [2:0] Funct3, // With ALUControl, indicates operation to perform NOTE: Change signal name to ALUSelect input logic [2:0] Funct3, // For BMU decoding
input logic [1:0] CompFlags, // Comparator flags input logic [1:0] CompFlags, // Comparator flags
input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage
output logic [WIDTH-1:0] Result, // ALU result output logic [WIDTH-1:0] Result, // ALU result
@ -49,30 +50,12 @@ module alu #(parameter WIDTH=32) (
logic [WIDTH-1:0] CondExtA; // Result of Zero Extend A select mux logic [WIDTH-1:0] CondExtA; // Result of Zero Extend A select mux
logic Carry, Neg; // Flags: carry out, negative logic Carry, Neg; // Flags: carry out, negative
logic LT, LTU; // Less than, Less than unsigned logic LT, LTU; // Less than, Less than unsigned
logic W64; // RV64 W-type instruction
logic SubArith; // Performing subtraction or arithmetic right shift
logic ALUOp; // 0 for address generation addition or 1 for regular ALU ops
logic Asign, Bsign; // Sign bits of A, B logic Asign, Bsign; // Sign bits of A, B
logic shSignA;
logic [WIDTH-1:0] rotA; // XLEN bit input source to shifter
logic [1:0] shASelect; // select signal for shifter source generation mux
logic Rotate; // Indicates if it is Rotate instruction
// Extract control signals from ALUControl. // *** explain this part better; possibly move into shifter and BMU?
assign {W64, SubArith, ALUOp} = ALUControl;
// Extract rotate signal from BALUControl.
assign Rotate = BALUControl[2];
// Pack control signals into shifter select signal.
assign shASelect = {W64, SubArith};
// A, A sign bit muxes
if (WIDTH == 64) begin if (WIDTH == 64) begin
mux3 #(1) signmux(A[63], A[31], 1'b0, {~SubArith, W64}, shSignA); mux3 #(64) extendmux({{32{1'b0}}, A[31:0]}, {{32{A[31]}}, A[31:0]}, A, {~W64, SubArith}, CondExtA); // bottom 32 bits are always A[31:0], so effectively a 32-bit upper mux
mux3 #(64) extendmux({{32{1'b0}}, A[31:0]},{{32{A[31]}}, A[31:0]}, A,{~W64, SubArith}, CondExtA);
end else begin end else begin
mux2 #(1) signmux(1'b0, A[31], SubArith, shSignA);
assign CondExtA = A; assign CondExtA = A;
end end
@ -81,7 +64,7 @@ module alu #(parameter WIDTH=32) (
assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(WIDTH-1){1'b0}}, SubArith}; assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(WIDTH-1){1'b0}}, SubArith};
// Shifts (configurable for rotation) // Shifts (configurable for rotation)
shifter sh(.shA(CondExtA), .Sign(shSignA), .rotA, .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .Y(Shift), .Rotate); shifter sh(.A(CondExtA), .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .SubArith, .Y(Shift), .Rotate(BALUControl[2]));
// Condition code flags are based on subtraction output Sum = A-B. // Condition code flags are based on subtraction output Sum = A-B.
// Overflow occurs when the numbers being subtracted have the opposite sign // Overflow occurs when the numbers being subtracted have the opposite sign
@ -95,14 +78,13 @@ module alu #(parameter WIDTH=32) (
// Select appropriate ALU Result // Select appropriate ALU Result
always_comb begin always_comb begin
if (~ALUOp) FullResult = Sum; // Always add for ALUOp = 0 (address generation) case (ALUSelect)
else casez (ALUSelect) // Otherwise check Funct3 NOTE: change signal name to ALUSelect 3'b000: FullResult = Sum; // add or sub (including address generation)
3'b000: FullResult = Sum; // add or sub
3'b001: FullResult = Shift; // sll, sra, or srl 3'b001: FullResult = Shift; // sll, sra, or srl
3'b010: FullResult = {{(WIDTH-1){1'b0}}, LT}; // slt 3'b010: FullResult = {{(WIDTH-1){1'b0}}, LT}; // slt
3'b011: FullResult = {{(WIDTH-1){1'b0}}, LTU}; // sltu 3'b011: FullResult = {{(WIDTH-1){1'b0}}, LTU}; // sltu
3'b100: FullResult = A ^ CondMaskInvB; // xor, xnor, binv 3'b100: FullResult = A ^ CondMaskInvB; // xor, xnor, binv
3'b101: FullResult = (`ZBS_SUPPORTED | `ZBB_SUPPORTED) ? {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}} : Shift;// bext 3'b101: FullResult = (`ZBS_SUPPORTED | `ZBB_SUPPORTED) ? {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}} : Shift; // bext (or IEU shift when BMU not supported)
3'b110: FullResult = A | CondMaskInvB; // or, orn, bset 3'b110: FullResult = A | CondMaskInvB; // or, orn, bset
3'b111: FullResult = A & CondMaskInvB; // and, bclr 3'b111: FullResult = A & CondMaskInvB; // and, bclr
endcase endcase
@ -114,13 +96,12 @@ module alu #(parameter WIDTH=32) (
// Final Result B instruction select mux // Final Result B instruction select mux
if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : bitmanipalu if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : bitmanipalu
bitmanipalu #(WIDTH) balu(.A, .B, .ALUControl, .ALUSelect, .BSelect, .ZBBSelect, bitmanipalu #(WIDTH) balu(.A, .B, .W64, .BSelect, .ZBBSelect,
.Funct3, .CompFlags, .BALUControl, .CondExtA, .ALUResult, .FullResult, .Funct3, .CompFlags, .BALUControl, .CondExtA, .ALUResult, .FullResult,
.CondMaskB, .CondShiftA, .rotA, .Result); .CondMaskB, .CondShiftA, .Result);
end else begin end else begin
assign Result = ALUResult; assign Result = ALUResult;
assign CondMaskB = B; assign CondMaskB = B;
assign CondShiftA = A; assign CondShiftA = A;
assign rotA = A;
end end
endmodule endmodule

View File

@ -31,34 +31,26 @@
module bitmanipalu #(parameter WIDTH=32) ( module bitmanipalu #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, B, // Operands input logic [WIDTH-1:0] A, B, // Operands
input logic [2:0] ALUControl, // With Funct3, indicates operation to perform input logic W64, // W64-type instruction
input logic [2:0] ALUSelect, // ALU mux select signal
input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
input logic [2:0] ZBBSelect, // ZBB mux select signal input logic [2:0] ZBBSelect, // ZBB mux select signal
input logic [2:0] Funct3, // With ALUControl, indicates operation to perform NOTE: Change signal name to ALUSelect input logic [2:0] Funct3, // Funct3 field of opcode indicates operation to perform
input logic [1:0] CompFlags, // Comparator flags input logic [1:0] CompFlags, // Comparator flags
input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage
input logic [WIDTH-1:0] CondExtA, // A Conditional Extend Intermediary Signal input logic [WIDTH-1:0] CondExtA, // A Conditional Extend Intermediary Signal
input logic [WIDTH-1:0] ALUResult, FullResult, // ALUResult, FullResult signals input logic [WIDTH-1:0] ALUResult, FullResult, // ALUResult, FullResult signals
output logic [WIDTH-1:0] CondMaskB, // B is conditionally masked for ZBS instructions output logic [WIDTH-1:0] CondMaskB, // B is conditionally masked for ZBS instructions
output logic [WIDTH-1:0] CondShiftA, // A is conditionally shifted for ShAdd instructions output logic [WIDTH-1:0] CondShiftA, // A is conditionally shifted for ShAdd instructions
output logic [WIDTH-1:0] rotA, // Rotate source signal
output logic [WIDTH-1:0] Result); // Result output logic [WIDTH-1:0] Result); // Result
logic [WIDTH-1:0] ZBBResult, ZBCResult; // ZBB, ZBC Result logic [WIDTH-1:0] ZBBResult, ZBCResult; // ZBB, ZBC Result
logic [WIDTH-1:0] MaskB; // BitMask of B logic [WIDTH-1:0] MaskB; // BitMask of B
logic [WIDTH-1:0] RevA; // Bit-reversed A logic [WIDTH-1:0] RevA; // Bit-reversed A
logic W64; // RV64 W-type instruction
logic SubArith; // Performing subtraction or arithmetic right shift
logic ALUOp; // 0 for address generation addition or 1 for regular ALU ops
logic Rotate; // Indicates if it is Rotate instruction logic Rotate; // Indicates if it is Rotate instruction
logic Mask; // Indicates if it is ZBS instruction logic Mask; // Indicates if it is ZBS instruction
logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction
logic [1:0] PreShiftAmt; // Amount to Pre-Shift A logic [1:0] PreShiftAmt; // Amount to Pre-Shift A
// Extract control signals from ALUControl.
assign {W64, SubArith, ALUOp} = ALUControl;
// Extract control signals from bitmanip ALUControl. // Extract control signals from bitmanip ALUControl.
assign {Mask, PreShift} = BALUControl[1:0]; assign {Mask, PreShift} = BALUControl[1:0];
@ -68,12 +60,7 @@ module bitmanipalu #(parameter WIDTH=32) (
mux2 #(WIDTH) maskmux(B, MaskB, Mask, CondMaskB); mux2 #(WIDTH) maskmux(B, MaskB, Mask, CondMaskB);
end else assign CondMaskB = B; end else assign CondMaskB = B;
// shifter rotate source select mux // 0-3 bit Pre-Shift Mux
if (`ZBB_SUPPORTED & WIDTH == 64) begin
mux2 #(WIDTH) rotmux(A, {A[31:0], A[31:0]}, W64, rotA);
end else assign rotA = A;
// Pre-Shift Mux
if (`ZBA_SUPPORTED) begin: zbapreshift if (`ZBA_SUPPORTED) begin: zbapreshift
assign PreShiftAmt = Funct3[2:1] & {2{PreShift}}; assign PreShiftAmt = Funct3[2:1] & {2{PreShift}};
assign CondShiftA = CondExtA << (PreShiftAmt); assign CondShiftA = CondExtA << (PreShiftAmt);

View File

@ -34,18 +34,17 @@ module bmuctrl(
// Decode stage control signals // Decode stage control signals
input logic StallD, FlushD, // Stall, flush Decode stage input logic StallD, FlushD, // Stall, flush Decode stage
input logic [31:0] InstrD, // Instruction in Decode stage input logic [31:0] InstrD, // Instruction in Decode stage
output logic [2:0] ALUSelectD, // ALU Mux select signal in Decode Stage input logic ALUOpD, // Regular ALU Operation
output logic [1:0] BSelectD, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding in Decode stage output logic [1:0] BSelectD, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding in Decode stage
output logic [2:0] ZBBSelectD, // ZBB mux select signal in Decode stage NOTE: do we need this in decode? output logic [2:0] ZBBSelectD, // ZBB mux select signal in Decode stage NOTE: do we need this in decode?
output logic BRegWriteD, // Indicates if it is a R type B instruction in Decode Stage output logic BRegWriteD, // Indicates if it is a R type B instruction in Decode Stage
output logic BALUSrcBD, // Indicates if it is an I/IW (non auipc) type B instruction in Decode Stage output logic BALUSrcBD, // Indicates if it is an I/IW (non auipc) type B instruction in Decode Stage
output logic BW64D, // Indiciates if it is a W type B instruction in Decode Stage output logic BW64D, // Indiciates if it is a W type B instruction in Decode Stage
output logic BALUOpD, // Indicates if it is an ALU B instruction in Decode Stage
output logic BSubArithD, // TRUE if ext, clr, andn, orn, xnor instruction in Decode Stage output logic BSubArithD, // TRUE if ext, clr, andn, orn, xnor instruction in Decode Stage
output logic IllegalBitmanipInstrD, // Indicates if it is unrecognized B instruction in Decode Stage output logic IllegalBitmanipInstrD, // Indicates if it is unrecognized B instruction in Decode Stage
// Execute stage control signals // Execute stage control signals
input logic StallE, FlushE, // Stall, flush Execute stage input logic StallE, FlushE, // Stall, flush Execute stage
output logic [2:0] ALUSelectE, output logic [2:0] ALUSelectD, // ALU select
output logic [1:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding output logic [1:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding
output logic [2:0] ZBBSelectE, // ZBB mux select signal output logic [2:0] ZBBSelectE, // ZBB mux select signal
output logic BRegWriteE, // Indicates if it is a R type B instruction in Execute output logic BRegWriteE, // Indicates if it is a R type B instruction in Execute
@ -62,9 +61,10 @@ module bmuctrl(
logic MaskD; // Indicates if zbs instruction in Decode Stage logic MaskD; // Indicates if zbs instruction in Decode Stage
logic PreShiftD; // Indicates if sh1add, sh2add, sh3add instruction in Decode Stage logic PreShiftD; // Indicates if sh1add, sh2add, sh3add instruction in Decode Stage
logic [2:0] BALUControlD; // ALU Control signals for B instructions logic [2:0] BALUControlD; // ALU Control signals for B instructions
logic [2:0] BALUSelectD; // ALU Mux select signal in Decode Stage for BMU operations
logic BALUOpD; // Indicates if it is an ALU B instruction in Decode Stage
`define BMUCTRLW 17 `define BMUCTRLW 17
`define BMUCTRLWSUB3 14
logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals
@ -76,15 +76,15 @@ module bmuctrl(
// Main Instruction Decoder // Main Instruction Decoder
always_comb begin always_comb begin
// ALUSelect_BSelect_ZBBSelect_BRegWrite_BALUSrcB_BW64_BALUOp_BSubArithD_RotateD_MaskD_PreShiftD_IllegalBitmanipInstrD // BALUSelect_BSelect_ZBBSelect_BRegWrite_BALUSrcB_BW64_BALUOp_BSubArithD_RotateD_MaskD_PreShiftD_IllegalBitmanipInstrD
BMUControlsD = {Funct3D, `BMUCTRLWSUB3'b00_000_0_0_0_0_0_0_0_0_1}; // default: Illegal instruction BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_0_1; // default: Illegal bmu instruction;
if (`ZBA_SUPPORTED) if (`ZBA_SUPPORTED) begin
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh1add 17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh1add
17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh2add 17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh2add
17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh3add 17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh3add
endcase endcase
if (`ZBA_SUPPORTED & `XLEN==64) if (`XLEN==64)
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh1add.uw 17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh1add.uw
17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh2add.uw 17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh2add.uw
@ -92,7 +92,8 @@ module bmuctrl(
17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_0_0; // add.uw 17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_0_0; // add.uw
17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_01_000_1_1_1_1_0_0_0_0_0; // slli.uw 17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_01_000_1_1_1_1_0_0_0_0_0; // slli.uw
endcase endcase
if (`ZBB_SUPPORTED) end
if (`ZBB_SUPPORTED) begin
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_0_1_0_1_0_0_0; // rol 17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_0_1_0_1_0_0_0; // rol
17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_0_1_0_1_0_0_0; // ror 17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_0_1_0_1_0_0_0; // ror
@ -102,7 +103,6 @@ module bmuctrl(
BMUControlsD = `BMUCTRLW'b000_10_000_1_1_0_1_0_0_0_0_0; // count instruction BMUControlsD = `BMUCTRLW'b000_10_000_1_1_0_1_0_0_0_0_0; // count instruction
17'b0110011_0000100_100: if (`XLEN == 32) 17'b0110011_0000100_100: if (`XLEN == 32)
BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32) BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32)
17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_0_1_0_1_0_0_0; // rori (rv32)
17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_01_111_1_0_0_1_1_0_0_0_0; // andn 17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_01_111_1_0_0_1_1_0_0_0_0; // andn
17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_01_111_1_0_0_1_1_0_0_0_0; // orn 17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_01_111_1_0_0_1_1_0_0_0_0; // orn
17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_01_111_1_0_0_1_1_0_0_0_0; // xnor 17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_01_111_1_0_0_1_1_0_0_0_0; // xnor
@ -115,50 +115,59 @@ module bmuctrl(
17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_0_0_0_0_0; // min 17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_0_0_0_0_0; // min
17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_0_0_0_0_0; // minu 17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_0_0_0_0_0; // minu
endcase endcase
if (`ZBB_SUPPORTED & `XLEN==64) if (`XLEN==32)
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0000100_100: BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32)
17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_0_1_0_1_0_0_0; // rori (rv32)
endcase
else if (`XLEN==64)
casez({OpD, Funct7D, Funct3D})
17'b0111011_0000100_100: BMUControlsD = `BMUCTRLW'b000_10_001_1_0_0_1_0_0_0_0_0; // zexth (rv64)
17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rolw 17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rolw
17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rorw 17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rorw
17'b0010011_011000?_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_0_1_0_1_0_0_0; // rori (rv64) 17'b0010011_011000?_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_0_1_0_1_0_0_0; // rori (rv64)
17'b0011011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_1_1_0_1_0_0_0; // roriw 17'b0011011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_1_1_0_1_0_0_0; // roriw
17'b0011011_0110000_001: if ((Rs2D[4:2]==3'b000) & ~(Rs2D[1] & Rs2D[0])) 17'b0011011_0110000_001: if ((Rs2D[4:2]==3'b000) & ~(Rs2D[1] & Rs2D[0]))
BMUControlsD = `BMUCTRLW'b000_10_000_1_1_1_1_0_0_0_0_0; // count word instruction BMUControlsD = `BMUCTRLW'b000_10_000_1_1_1_1_0_0_0_0_0; // count word instruction
17'b0111011_0000100_100: BMUControlsD = `BMUCTRLW'b000_10_001_1_0_0_1_0_0_0_0_0; // zexth (rv64)
endcase endcase
end
if (`ZBC_SUPPORTED) if (`ZBC_SUPPORTED)
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_11_000_1_0_0_1_0_0_0_0_0; // ZBC instruction 17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_11_000_1_0_0_1_0_0_0_0_0; // ZBC instruction
endcase endcase
if (`ZBS_SUPPORTED) // ZBS if (`ZBS_SUPPORTED) begin // ZBS
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri
17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti
17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_1_0_1_0_0_1_0_0; // binvi
17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti
17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_0_0_1_1_0_1_0_0; // bclr 17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_0_0_1_1_0_1_0_0; // bclr
17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_0_0_1_1_0_1_0_0; // bext 17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_0_0_1_1_0_1_0_0; // bext
17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_0_0_1_0_0_1_0_0; // binv 17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_0_0_1_0_0_1_0_0; // binv
17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_0_0_1_0_0_1_0_0; // bset 17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_0_0_1_0_0_1_0_0; // bset
endcase endcase
if (`ZBS_SUPPORTED & `XLEN==64) // ZBS 64-bit if (`XLEN==32) // ZBS 64-bit
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0010011_0100101_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri (rv64) 17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri
17'b0010011_0100101_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti (rv64) 17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti
17'b0010011_0110101_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_1_0_1_0_0_1_0_0; // binvi (rv64) 17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_1_0_1_0_0_1_0_0; // binvi
17'b0010011_0010101_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti (rv64) 17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti
endcase endcase
if (`ZBB_SUPPORTED | `ZBS_SUPPORTED) // rv32i/64i shift instructions need certain BMU shifter control when BMU shifter is used else if (`XLEN==64) // ZBS 64-bit
casez({OpD, Funct7D, Funct3D})
17'b0010011_010010?_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri (rv64)
17'b0010011_010010?_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti (rv64)
17'b0010011_011010?_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_1_0_1_0_0_1_0_0; // binvi (rv64)
17'b0010011_001010?_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti (rv64)
endcase
end
if (`ZBB_SUPPORTED | `ZBS_SUPPORTED) // rv32i/64i shift instructions need BMU ALUSelect when BMU shifter is used
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_0_0_1_0_0_0_0_0; // sra, srl, sll 17'b0110011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_0_0_1_0_0_0_0_0; // sra, srl, sll
17'b0010011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_1_0_1_0_0_0_0_0; // srai, srli, slli 17'b0010011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_1_0_1_0_0_0_0_0; // srai, srli, slli
17'b0111011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_0_1_1_0_0_0_0_0; // sraw, srlw, sllw 17'b0111011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_0_1_1_0_0_0_0_0; // sraw, srlw, sllw
17'b0011011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_1_1_1_0_0_0_0_0; // sraiw, srliw, slliw 17'b0011011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_1_1_1_0_0_0_0_0; // sraiw, srliw, slliw
endcase endcase
// ZBC
end end
// Unpack Control Signals // Unpack Control Signals
assign {ALUSelectD,BSelectD,ZBBSelectD, BRegWriteD,BALUSrcBD, BW64D, BALUOpD, BSubArithD, RotateD, MaskD, PreShiftD, IllegalBitmanipInstrD} = BMUControlsD; assign {BALUSelectD, BSelectD, ZBBSelectD, BRegWriteD,BALUSrcBD, BW64D, BALUOpD, BSubArithD, RotateD, MaskD, PreShiftD, IllegalBitmanipInstrD} = BMUControlsD;
// Pack BALUControl Signals // Pack BALUControl Signals
assign BALUControlD = {RotateD, MaskD, PreShiftD}; assign BALUControlD = {RotateD, MaskD, PreShiftD};
@ -166,6 +175,9 @@ module bmuctrl(
// Comparator should perform signed comparison when min/max instruction. We have overlap in funct3 with some branch instructions so we use opcode to differentiate betwen min/max and branches // Comparator should perform signed comparison when min/max instruction. We have overlap in funct3 with some branch instructions so we use opcode to differentiate betwen min/max and branches
assign BComparatorSignedD = (Funct3D[2]^Funct3D[0]) & ~OpD[6]; assign BComparatorSignedD = (Funct3D[2]^Funct3D[0]) & ~OpD[6];
// Choose ALUSelect brom BMU for BMU operations, Funct3 for IEU operations, or 0 for addition
assign ALUSelectD = BALUOpD ? BALUSelectD : (ALUOpD ? Funct3D : 3'b000);
// BMU Execute stage pipieline control register // BMU Execute stage pipieline control register
flopenrc#(13) controlregBMU(clk, reset, FlushE, ~StallE, {ALUSelectD, BSelectD, ZBBSelectD, BRegWriteD, BComparatorSignedD, BALUControlD}, {ALUSelectE, BSelectE, ZBBSelectE, BRegWriteE, BComparatorSignedE, BALUControlE}); flopenrc#(10) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BComparatorSignedD, BALUControlD}, {BSelectE, ZBBSelectE, BRegWriteE, BComparatorSignedE, BALUControlE});
endmodule endmodule

View File

@ -45,7 +45,6 @@ module controller(
input logic [1:0] FlagsE, // Comparison flags ({eq, lt}) input logic [1:0] FlagsE, // Comparison flags ({eq, lt})
input logic FWriteIntE, // Write integer register, coming from FPU controller input logic FWriteIntE, // Write integer register, coming from FPU controller
output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit) output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit)
output logic [2:0] ALUControlE, // ALU operation to perform
output logic ALUSrcAE, ALUSrcBE, // ALU operands output logic ALUSrcAE, ALUSrcBE, // ALU operands
output logic ALUResultSrcE, // Selects result to pass on to Memory stage output logic ALUResultSrcE, // Selects result to pass on to Memory stage
output logic [2:0] ALUSelectE, // ALU mux select signal output logic [2:0] ALUSelectE, // ALU mux select signal
@ -54,6 +53,7 @@ module controller(
output logic IntDivE, // Integer divide output logic IntDivE, // Integer divide
output logic MDUE, // MDU (multiply/divide) operatio output logic MDUE, // MDU (multiply/divide) operatio
output logic W64E, // RV64 W-type operation output logic W64E, // RV64 W-type operation
output logic SubArithE, // Subtraction or arithmetic shift
output logic JumpE, // jump instruction output logic JumpE, // jump instruction
output logic BranchE, // Branch instruction output logic BranchE, // Branch instruction
output logic SCE, // Store Conditional instruction output logic SCE, // Store Conditional instruction
@ -93,12 +93,11 @@ module controller(
logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; // Select which result to write back to register file logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; // Select which result to write back to register file
logic [1:0] MemRWD, MemRWE; // Store (write to memory) logic [1:0] MemRWD, MemRWE; // Store (write to memory)
logic ALUOpD; // 0 for address generation, 1 for all other operations (must use Funct3) logic ALUOpD; // 0 for address generation, 1 for all other operations (must use Funct3)
logic BaseALUOpD, BaseW64D; // ALU operation and W64 for Base instructions specifically logic BaseW64D; // W64 for Base instructions specifically
logic BaseRegWriteD; // Indicates if Base instruction register write instruction logic BaseRegWriteD; // Indicates if Base instruction register write instruction
logic BaseSubArithD; // Indicates if Base instruction subtracts, sra, slt, sltu logic BaseSubArithD; // Indicates if Base instruction subtracts, sra, slt, sltu
logic BaseALUSrcBD; // Base instruction ALU B source select signal logic BaseALUSrcBD; // Base instruction ALU B source select signal
logic [2:0] ALUControlD; // Determines ALU operation logic [2:0] ALUControlD; // Determines ALU operation
logic [2:0] ALUSelectD; // ALU mux select signal
logic ALUSrcAD, ALUSrcBD; // ALU inputs logic ALUSrcAD, ALUSrcBD; // ALU inputs
logic ALUResultSrcD, W64D, MDUD; // ALU result, is RV64 W-type, is multiply/divide instruction logic ALUResultSrcD, W64D, MDUD; // ALU result, is RV64 W-type, is multiply/divide instruction
logic CSRZeroSrcD; // Ignore setting and clearing zeros to CSR logic CSRZeroSrcD; // Ignore setting and clearing zeros to CSR
@ -112,6 +111,7 @@ module controller(
logic [`CTRLW-1:0] ControlsD; // Main Instruction Decoder control signals logic [`CTRLW-1:0] ControlsD; // Main Instruction Decoder control signals
logic SubArithD; // TRUE for R-type subtracts and sra, slt, sltu or B-type ext clr, andn, orn, xnor logic SubArithD; // TRUE for R-type subtracts and sra, slt, sltu or B-type ext clr, andn, orn, xnor
logic subD, sraD, sltD, sltuD; // Indicates if is one of these instructions logic subD, sraD, sltD, sltuD; // Indicates if is one of these instructions
logic ALUOpE; // 0 for address generationm 1 for ALU operations
logic BranchTakenE; // Branch is taken logic BranchTakenE; // Branch is taken
logic eqE, ltE; // Comparator outputs logic eqE, ltE; // Comparator outputs
logic unused; logic unused;
@ -119,23 +119,18 @@ module controller(
logic IEURegWriteE; // Register write logic IEURegWriteE; // Register write
logic BRegWriteE; // Register write from BMU controller in Execute Stage logic BRegWriteE; // Register write from BMU controller in Execute Stage
logic IllegalERegAdrD; // RV32E attempts to write upper 16 registers logic IllegalERegAdrD; // RV32E attempts to write upper 16 registers
logic IllegalBitmanipInstrD; // Unrecognized B instruction
logic [1:0] AtomicE; // Atomic instruction logic [1:0] AtomicE; // Atomic instruction
logic FenceD, FenceE; // Fence instruction logic FenceD, FenceE; // Fence instruction
logic SFenceVmaD; // sfence.vma instruction logic SFenceVmaD; // sfence.vma instruction
logic IntDivM; // Integer divide instruction logic IntDivM; // Integer divide instruction
logic [1:0] BSelectD; // One-Hot encoding if it's ZBA_ZBB_ZBC_ZBS instruction in decode stage logic [1:0] BSelectD; // One-Hot encoding if it's ZBA_ZBB_ZBC_ZBS instruction in decode stage
logic [2:0] ZBBSelectD; // ZBB Mux Select Signal logic [2:0] ZBBSelectD; // ZBB Mux Select Signal
logic BRegWriteD; // Indicates if it is a R type B instruction in decode stage
logic BW64D; // Indicates if it is a W type B instruction in decode stage
logic BALUOpD; // Indicates if it is an ALU B instruction in decode stage
logic BSubArithD; // TRUE for B-type ext, clr, andn, orn, xnor
logic BALUSrcBD; // B-type alu src select signal
logic BComparatorSignedE; // Indicates if max, min (signed comarison) instruction in Execute Stage logic BComparatorSignedE; // Indicates if max, min (signed comarison) instruction in Execute Stage
logic IFunctD, RFunctD, MFunctD; // Detect I, R, and M-type RV32IM/Rv64IM instructions logic IFunctD, RFunctD, MFunctD; // Detect I, R, and M-type RV32IM/Rv64IM instructions
logic LFunctD, SFunctD, BFunctD; // Detect load, store, branch instructions logic LFunctD, SFunctD, BFunctD; // Detect load, store, branch instructions
logic JFunctD; // detect jalr instruction logic JFunctD; // detect jalr instruction
logic FenceM; // Fence.I or sfence.VMA instruction in memory stage logic FenceM; // Fence.I or sfence.VMA instruction in memory stage
logic [2:0] ALUSelectD; // ALU Output selection mux control
// Extract fields // Extract fields
assign OpD = InstrD[6:0]; assign OpD = InstrD[6:0];
@ -233,19 +228,11 @@ module controller(
// Squash control signals if coming from an illegal compressed instruction // Squash control signals if coming from an illegal compressed instruction
// On RV32E, can't write to upper 16 registers. Checking reads to upper 16 is more costly so disregard them. // On RV32E, can't write to upper 16 registers. Checking reads to upper 16 is more costly so disregard them.
assign IllegalERegAdrD = `E_SUPPORTED & `ZICSR_SUPPORTED & ControlsD[`CTRLW-1] & InstrD[11]; assign IllegalERegAdrD = `E_SUPPORTED & `ZICSR_SUPPORTED & ControlsD[`CTRLW-1] & InstrD[11];
assign IllegalBaseInstrD = (ControlsD[0] & IllegalBitmanipInstrD) | IllegalERegAdrD ; //NOTE: Do we want to segregate the IllegalBitmanipInstrD into its own output signal
//assign IllegalBaseInstrD = 1'b0; //assign IllegalBaseInstrD = 1'b0;
assign {BaseRegWriteD, ImmSrcD, ALUSrcAD, BaseALUSrcBD, MemRWD, assign {BaseRegWriteD, ImmSrcD, ALUSrcAD, BaseALUSrcBD, MemRWD,
ResultSrcD, BranchD, BaseALUOpD, JumpD, ALUResultSrcD, BaseW64D, CSRReadD, ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, BaseW64D, CSRReadD,
PrivilegedD, FenceXD, MDUD, AtomicD, unused} = IllegalIEUFPUInstrD ? `CTRLW'b0 : ControlsD; PrivilegedD, FenceXD, MDUD, AtomicD, unused} = IllegalIEUFPUInstrD ? `CTRLW'b0 : ControlsD;
// If either bitmanip signal or base instruction signal
assign ALUOpD = BaseALUOpD | BALUOpD;
assign RegWriteD = BaseRegWriteD | BRegWriteD;
assign W64D = BaseW64D | BW64D;
assign ALUSrcBD = BaseALUSrcBD | BALUSrcBD;
assign SubArithD = BaseSubArithD | BSubArithD; // TRUE If B-type or R-type instruction involves inverted operand
assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source? assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source?
assign CSRWriteD = CSRReadD & !(CSRZeroSrcD & InstrD[13]); // Don't write if setting or clearing zeros assign CSRWriteD = CSRReadD & !(CSRZeroSrcD & InstrD[13]); // Don't write if setting or clearing zeros
assign SFenceVmaD = PrivilegedD & (InstrD[31:25] == 7'b0001001); assign SFenceVmaD = PrivilegedD & (InstrD[31:25] == 7'b0001001);
@ -256,36 +243,45 @@ module controller(
assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]); // OpD[5] needed to distinguish sub from addi assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]); // OpD[5] needed to distinguish sub from addi
assign sraD = (Funct3D == 3'b101 & Funct7D[5]); assign sraD = (Funct3D == 3'b101 & Funct7D[5]);
assign BaseSubArithD = ALUOpD & (subD | sraD | sltD | sltuD); assign BaseSubArithD = ALUOpD & (subD | sraD | sltD | sltuD);
assign ALUControlD = {W64D, SubArithD, ALUOpD};
// bit manipulation Configuration Block // bit manipulation Configuration Block
if (`ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED | `ZBC_SUPPORTED) begin: bitmanipi //change the conditional expression to OR any Z supported flags if (`ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED | `ZBC_SUPPORTED) begin: bitmanipi //change the conditional expression to OR any Z supported flags
bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUSelectD, .BSelectD, .ZBBSelectD, logic IllegalBitmanipInstrD; // Unrecognized B instruction
.BRegWriteD, .BALUSrcBD, .BW64D, .BALUOpD, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE, logic BRegWriteD; // Indicates if it is a R type BMU instruction in decode stage
.ALUSelectE, .BSelectE, .ZBBSelectE, .BRegWriteE, .BComparatorSignedE, .BALUControlE); logic BW64D; // Indicates if it is a W type BMU instruction in decode stage
logic BSubArithD; // TRUE for BMU ext, clr, andn, orn, xnor
logic BALUSrcBD; // BMU alu src select signal
bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUOpD, .BSelectD, .ZBBSelectD,
.BRegWriteD, .BALUSrcBD, .BW64D, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE,
.ALUSelectD, .BSelectE, .ZBBSelectE, .BRegWriteE, .BComparatorSignedE, .BALUControlE);
if (`ZBA_SUPPORTED) begin if (`ZBA_SUPPORTED) begin
// ALU Decoding is more comprehensive when ZBA is supported. slt and slti conflicts with sh1add, sh1add.uw // ALU Decoding is more comprehensive when ZBA is supported. slt and slti conflicts with sh1add, sh1add.uw
assign sltD = (Funct3D == 3'b010 & (~(Funct7D[4]) | ~OpD[5])) ; assign sltD = (Funct3D == 3'b010 & (~(Funct7D[4]) | ~OpD[5])) ;
end else assign sltD = (Funct3D == 3'b010); end else assign sltD = (Funct3D == 3'b010);
// Combine base and bit manipulation signals
assign IllegalBaseInstrD = (ControlsD[0] & IllegalBitmanipInstrD) | IllegalERegAdrD ;
assign RegWriteD = BaseRegWriteD | BRegWriteD;
assign W64D = BaseW64D | BW64D;
assign ALUSrcBD = BaseALUSrcBD | BALUSrcBD;
assign SubArithD = BaseSubArithD | BSubArithD; // TRUE If BMU or R-type instruction involves inverted operand
end else begin: bitmanipi end else begin: bitmanipi
assign ALUSelectD = Funct3D; assign ALUSelectD = ALUOpD ? Funct3D : 3'b000; // add for address generation when not doing ALU operation
assign ALUSelectE = Funct3E; assign sltD = (Funct3D == 3'b010);
assign IllegalBaseInstrD = ControlsD[0] | IllegalERegAdrD ;
assign RegWriteD = BaseRegWriteD;
assign W64D = BaseW64D;
assign ALUSrcBD = BaseALUSrcBD;
assign SubArithD = BaseSubArithD; // TRUE If B-type or R-type instruction involves inverted operand
// tie off unused bit manipulation signals
assign BSelectE = 2'b00; assign BSelectE = 2'b00;
assign BSelectD = 2'b00; assign BSelectD = 2'b00;
assign ZBBSelectE = 3'b000; assign ZBBSelectE = 3'b000;
assign BRegWriteD = 1'b0;
assign BW64D = 1'b0;
assign BALUOpD = 1'b0;
assign BRegWriteE = 1'b0;
assign BSubArithD = 1'b0;
assign BComparatorSignedE = 1'b0; assign BComparatorSignedE = 1'b0;
assign BALUControlE = 3'b0; assign BALUControlE = 3'b0;
assign BALUSrcBD = 1'b0;
assign sltD = (Funct3D == 3'b010);
assign IllegalBitmanipInstrD = 1'b1;
end end
// Fences // Fences
@ -305,9 +301,9 @@ module controller(
flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD); flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD);
// Execute stage pipeline control register and logic // Execute stage pipeline control register and logic
flopenrc #(28) controlregE(clk, reset, FlushE, ~StallE, flopenrc #(29) controlregE(clk, reset, FlushE, ~StallE,
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, InstrValidD}, {ALUSelectD, RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, SubArithD, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, InstrValidD},
{IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE}); {ALUSelectE, IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, SubArithE, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE});
// Branch Logic // Branch Logic
// The comparator handles both signed and unsigned branches using BranchSignedE // The comparator handles both signed and unsigned branches using BranchSignedE

View File

@ -40,7 +40,8 @@ module datapath (
input logic [2:0] Funct3E, // Funct3 field of instruction in Execute stage input logic [2:0] Funct3E, // Funct3 field of instruction in Execute stage
input logic StallE, FlushE, // Stall, flush Execute stage input logic StallE, FlushE, // Stall, flush Execute stage
input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages
input logic [2:0] ALUControlE, // Indicate operation ALU performs input logic W64E, // W64-type instruction
input logic SubArithE, // Subtraction or arithmetic shift
input logic ALUSrcAE, ALUSrcBE, // ALU operands input logic ALUSrcAE, ALUSrcBE, // ALU operands
input logic ALUResultSrcE, // Selects result to pass on to Memory stage input logic ALUResultSrcE, // Selects result to pass on to Memory stage
input logic [2:0] ALUSelectE, // ALU mux select signal input logic [2:0] ALUSelectE, // ALU mux select signal
@ -113,7 +114,7 @@ module datapath (
comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE); comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE);
mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE); mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE); mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE);
alu #(`XLEN) alu(SrcAE, SrcBE, ALUControlE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE, BALUControlE, ALUResultE, IEUAdrE); alu #(`XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE, BALUControlE, ALUResultE, IEUAdrE);
mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE);
mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE); mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);

View File

@ -76,7 +76,6 @@ module ieu (
logic [2:0] ImmSrcD; // Select type of immediate extension logic [2:0] ImmSrcD; // Select type of immediate extension
logic [1:0] FlagsE; // Comparison flags ({eq, lt}) logic [1:0] FlagsE; // Comparison flags ({eq, lt})
logic [2:0] ALUControlE; // ALU control indicates function to perform
logic ALUSrcAE, ALUSrcBE; // ALU source operands logic ALUSrcAE, ALUSrcBE; // ALU source operands
logic [2:0] ResultSrcW; // Selects result in Writeback stage logic [2:0] ResultSrcW; // Selects result in Writeback stage
logic ALUResultSrcE; // Selects ALU result to pass on to Memory stage logic ALUResultSrcE; // Selects ALU result to pass on to Memory stage
@ -87,6 +86,7 @@ module ieu (
logic [1:0] BSelectE; // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding logic [1:0] BSelectE; // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding
logic [2:0] ZBBSelectE; // ZBB Result Select Signal in Execute Stage logic [2:0] ZBBSelectE; // ZBB Result Select Signal in Execute Stage
logic [2:0] BALUControlE; // ALU Control signals for B instructions in Execute Stage logic [2:0] BALUControlE; // ALU Control signals for B instructions in Execute Stage
logic SubArithE; // Subtraction or arithmetic shift
// Forwarding signals // Forwarding signals
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E; // Source and destination registers logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E; // Source and destination registers
@ -99,15 +99,15 @@ module ieu (
controller c( controller c(
.clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD, .clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD,
.IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE, .IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE,
.PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE, .PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE,
.Funct3E, .IntDivE, .MDUE, .W64E, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .StallM, .FlushM, .MemRWM, .Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .StallM, .FlushM, .MemRWM,
.CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
.RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM, .RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD); .StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD);
datapath dp( datapath dp(
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE,
.ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE,
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE,
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW, .StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
.StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW, .StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,

View File

@ -30,54 +30,59 @@
`include "wally-config.vh" `include "wally-config.vh"
module shifter ( module shifter (
input logic [`XLEN-1:0] shA, // shift Source input logic [`XLEN-1:0] A, // shift Source
input logic [`XLEN-1:0] rotA, // rotate source
input logic [`LOG_XLEN-1:0] Amt, // Shift amount input logic [`LOG_XLEN-1:0] Amt, // Shift amount
input logic Right, Rotate, W64, Sign, // Shift right, rotate signals input logic Right, Rotate, W64, SubArith, // Shift right, rotate, W64-type operation, arithmetic shift
output logic [`XLEN-1:0] Y); // Shifted result output logic [`XLEN-1:0] Y); // Shifted result
logic [2*`XLEN-2:0] z, zshift; // Input to funnel shifter, shifted amount before truncated to 32 or 64 bits logic [2*`XLEN-2:0] z, zshift; // Input to funnel shifter, shifted amount before truncated to 32 or 64 bits
logic [`LOG_XLEN-1:0] amttrunc, offset; // Shift amount adjusted for RV64, right-shift amount logic [`LOG_XLEN-1:0] amttrunc, Offset; // Shift amount adjusted for RV64, right-shift amount
logic Sign; // Sign bit for sign extension
assign Sign = A[`XLEN-1] & SubArith; // sign bit for sign extension
if (`ZBB_SUPPORTED) begin: rotfunnel if (`ZBB_SUPPORTED) begin: rotfunnel
if (`XLEN==32) begin // rv32 with rotates if (`XLEN==32) begin // rv32 with rotates
always_comb // funnel mux always_comb // funnel mux
case({Right, Rotate}) case({Right, Rotate})
2'b00: z = {shA[31:0], 31'b0}; 2'b00: z = {A[31:0], 31'b0};
2'b01: z = {rotA,rotA[31:1]}; 2'b01: z = {A[31:0], A[31:1]};
2'b10: z = {{31{Sign}}, shA[31:0]}; 2'b10: z = {{31{Sign}}, A[31:0]};
2'b11: z = {rotA[30:0],rotA}; 2'b11: z = {A[30:0], A};
endcase endcase
assign amttrunc = Amt; // shift amount assign amttrunc = Amt; // shift amount
end else begin // rv64 with rotates end else begin // rv64 with rotates
// shifter rotate source select mux
logic [`XLEN-1:0] RotA; // rotate source
mux2 #(`XLEN) rotmux(A, {A[31:0], A[31:0]}, W64, RotA); // W64 rotatons
always_comb // funnel mux always_comb // funnel mux
case ({Right, Rotate}) case ({Right, Rotate})
2'b00: z = {shA[63:0],{63'b0}}; 2'b00: z = {A[63:0],{63'b0}};
2'b01: z = {rotA, rotA[63:1]}; 2'b01: z = {RotA, RotA[63:1]};
2'b10: z = {{63{Sign}},shA[63:0]}; 2'b10: z = {{63{Sign}}, A[63:0]};
2'b11: z = {rotA[62:0],rotA[63:0]}; 2'b11: z = {RotA[62:0], RotA};
endcase endcase
assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32- or 64-bit shift assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32- or 64-bit shift
end end
end else begin: norotfunnel end else begin: norotfunnel
if (`XLEN==32) begin:shifter // RV32 if (`XLEN==32) begin:shifter // RV32
always_comb // funnel mux always_comb // funnel mux
if (Right) z = {{31{Sign}}, shA[31:0]}; if (Right) z = {{31{Sign}}, A[31:0]};
else z = {shA[31:0], 31'b0}; else z = {A[31:0], 31'b0};
assign amttrunc = Amt; // shift amount assign amttrunc = Amt; // shift amount
end else begin:shifter // RV64 end else begin:shifter // RV64
always_comb // funnel mux always_comb // funnel mux
if (Right) z = {{63{Sign}},shA[63:0]}; if (Right) z = {{63{Sign}}, A[63:0]};
else z = {shA[63:0],{63'b0}}; else z = {A[63:0], {63'b0}};
assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32- or 64-bit shift assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32- or 64-bit shift
end end
end end
// Opposite offset for right shifts // Opposite offset for right shifts
assign offset = Right ? amttrunc : ~amttrunc; assign Offset = Right ? amttrunc : ~amttrunc;
// Funnel operation // Funnel operation
assign zshift = z >> offset; assign zshift = z >> Offset;
assign Y = zshift[`XLEN-1:0]; assign Y = zshift[`XLEN-1:0];
endmodule endmodule

View File

@ -44,7 +44,8 @@ string tvpaths[] = '{
string coverage64gc[] = '{ string coverage64gc[] = '{
`COVERAGE, `COVERAGE,
"badinstr", "ieu",
"ebu",
"csrwrites" "csrwrites"
}; };

View File

@ -17,7 +17,7 @@ all: $(OBJECTS)
# Change many things if bit width isn't 64 # Change many things if bit width isn't 64
%.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile %.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile
riscv64-unknown-elf-gcc -g -o $@ -march=rv64gc -mabi=lp64 -mcmodel=medany \ riscv64-unknown-elf-gcc -g -o $@ -march=rv64gc_zba_zbb_zbc_zbs -mabi=lp64 -mcmodel=medany \
-nostartfiles -T../../examples/link/link.ld $< -nostartfiles -T../../examples/link/link.ld $<
riscv64-unknown-elf-objdump -S $@ > $@.objdump riscv64-unknown-elf-objdump -S $@ > $@.objdump
riscv64-unknown-elf-elf2hex --bit-width 64 --input $@ --output $@.memfile riscv64-unknown-elf-elf2hex --bit-width 64 --input $@ --output $@.memfile

45
tests/coverage/ebu.S Normal file
View File

@ -0,0 +1,45 @@
///////////////////////////////////////////
// ebu.S
//
// Written: David_Harris@hmc.edu 23 March 2023
//
// Purpose: Test coverage for EBU
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the License); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
// load code to initalize stack, handle interrupts, terminate
#include "WALLY-init-lib.h"
main:
# Test clz with all bits being 0
li t0, 0
clz t1, t0
li t0, -1
clz t1, t0
li t0, 1
clz t1, t0
# Test forwarding from store conditional
lr.w t0, 0(a0)
sc.w t0, a1, 0(a0)
addi t0, t0, 1
j done

View File

@ -1,9 +1,9 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// badinstr.S // ieu.S
// //
// Written: David_Harris@hmc.edu 21 March 2023 // Written: David_Harris@hmc.edu 21 March 2023
// //
// Purpose: Test illegal instruction opcodes // Purpose: Test coverage for IEU
// //
// A component of the CORE-V-WALLY configurable RISC-V project. // A component of the CORE-V-WALLY configurable RISC-V project.
// //
@ -27,7 +27,21 @@
#include "WALLY-init-lib.h" #include "WALLY-init-lib.h"
main: main:
.word 0x00000033 // legal R-type instruction
# Test clz with all bits being 0
li t0, 0
clz t1, t0
li t0, -1
clz t1, t0
li t0, 1
clz t1, t0
# Test forwarding from store conditional
lr.w t0, 0(a0)
sc.w t0, a1, 0(a0)
addi t0, t0, 1
# Test illegal instructions are detected
.word 0x80000033 // illegal R-type instruction .word 0x80000033 // illegal R-type instruction
.word 0x00007003 // illegal Load instruction .word 0x00007003 // illegal Load instruction
.word 0x80005013 // illegal I-type instruction: srli: op = 0010011, funct3 = 101, funct7 = 1000000 .word 0x80005013 // illegal I-type instruction: srli: op = 0010011, funct3 = 101, funct7 = 1000000
@ -37,6 +51,15 @@ main:
.word 0x0400003B // Illegal RW or MulDivW instruction .word 0x0400003B // Illegal RW or MulDivW instruction
.word 0x00007067 // Illegal JALR instruction .word 0x00007067 // Illegal JALR instruction
.word 0x00002063 // Illegal branch instruction .word 0x00002063 // Illegal branch instruction
.word 0x60F01013 // Illegal BMU sign extend / count instruction
.word 0x60801013 // Illegal BMU sign extend / count instruction
.word 0x60301013 // Illegal BMU sign extend / count instruction
.word 0x6BF05013 // Illegal BMU similar to rev8
.word 0x69805013 // Illegal BMU similar to rev8
.word 0x28F05013 // Illegal BMU similar to or.c
.word 0x60F0101B // Illegal BMU similar to count word
.word 0x6080101B // Illegal BMU similar to count word
.word 0x6030101B // Illegal BMU similar to count word
j done j done