forked from Github_Repos/cvw
commit
6eae7dda14
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
@ -31,49 +31,36 @@
|
|||||||
|
|
||||||
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];
|
||||||
|
|
||||||
// Mask Generation Mux
|
// Mask Generation Mux
|
||||||
if (`ZBS_SUPPORTED) begin: zbsdec
|
if (`ZBS_SUPPORTED) begin: zbsdec
|
||||||
decoder #($clog2(WIDTH)) maskgen (B[$clog2(WIDTH)-1:0], MaskB);
|
decoder #($clog2(WIDTH)) maskgen(B[$clog2(WIDTH)-1:0], MaskB);
|
||||||
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);
|
||||||
|
@ -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,23 +76,24 @@ 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
|
||||||
17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh3add.uw
|
17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh3add.uw
|
||||||
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'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rolw
|
17'b0110011_0000100_100: BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32)
|
||||||
17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rorw
|
17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_0_1_0_1_0_0_0; // rori (rv32)
|
||||||
17'b0010011_011000?_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_0_1_0_1_0_0_0; // rori (rv64)
|
endcase
|
||||||
17'b0011011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_1_1_0_1_0_0_0; // roriw
|
else if (`XLEN==64)
|
||||||
17'b0011011_0110000_001: if ((Rs2D[4:2]==3'b000) & ~(Rs2D[1] & Rs2D[0]))
|
casez({OpD, Funct7D, Funct3D})
|
||||||
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)
|
||||||
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
|
||||||
endcase
|
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'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]))
|
||||||
|
BMUControlsD = `BMUCTRLW'b000_10_000_1_1_1_1_0_0_0_0_0; // count word instruction
|
||||||
|
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
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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, SubArith, // Shift right, rotate, W64-type operation, arithmetic shift
|
||||||
input logic Right, Rotate, W64, Sign, // Shift right, rotate signals
|
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
|
||||||
|
|
||||||
|
@ -44,7 +44,8 @@ string tvpaths[] = '{
|
|||||||
|
|
||||||
string coverage64gc[] = '{
|
string coverage64gc[] = '{
|
||||||
`COVERAGE,
|
`COVERAGE,
|
||||||
"badinstr",
|
"ieu",
|
||||||
|
"ebu",
|
||||||
"csrwrites"
|
"csrwrites"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
45
tests/coverage/ebu.S
Normal 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
|
||||||
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user