began ZBB integration into ieu

This commit is contained in:
Kevin Kim 2023-02-18 19:44:14 -08:00
parent 5f56f72bb1
commit f18cd53dee
7 changed files with 80 additions and 61 deletions

View File

@ -34,13 +34,14 @@ module alu #(parameter WIDTH=32) (
input logic [2:0] ALUControl, // With Funct3, indicates operation to perform
input logic [2:0] ALUSelect, // ALU mux select signal
input logic [3:0] BSelect, // One-Hot encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
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
output logic [WIDTH-1:0] Result, // ALU result
output logic [WIDTH-1:0] Sum); // Sum of operands
// CondInvB = ~B when subtracting, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction.
// FullResult = ALU result before adjusting for a RV64 w-suffix instruction.
logic [WIDTH-1:0] CondInvB, Shift, SLT, SLTU, FullResult,ALUResult, ZBCResult; // Intermediate results
logic [WIDTH-1:0] CondInvB, Shift, SLT, SLTU, FullResult,ALUResult, ZBCResult, ZBBResult; // Intermediate results
logic [WIDTH-1:0] MaskB; // BitMask of B
logic [WIDTH-1:0] CondMaskB; // Result of B mask select mux
logic [WIDTH-1:0] CondShiftA; // Result of A shifted select mux
@ -143,6 +144,10 @@ module alu #(parameter WIDTH=32) (
zbc #(WIDTH) ZBC(.A(A), .B(B), .Funct3(Funct3), .ZBCResult(ZBCResult));
end else assign ZBCResult = 0;
if (`ZBB_SUPPORTED) begin: zbb
zbb #(WIDTH) ZBB(.A(A), .B(B), .W64(W64), .ZBBSelect(ZBBSelect), .ZBBResult(ZBBResult));
end else assign ZBBResult = 0;
// Final Result B instruction select mux
if (`ZBC_SUPPORTED | `ZBS_SUPPORTED) begin : zbdecoder
always_comb

View File

@ -37,18 +37,20 @@ module bmuctrl(
input logic [31:0] InstrD, // Instruction in Decode stage
output logic [2:0] ALUSelectD, // ALU Mux select signal
output logic [3: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?
// Execute stage control signals
input logic StallE, FlushE, // Stall, flush Execute stage
output logic [2:0] ALUSelectE,
output logic [3:0] BSelectE // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding
output logic [3:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding
output logic [2:0] ZBBSelectE // ZBB mux select signal
);
logic [6:0] OpD; // Opcode in Decode stage
logic [2:0] Funct3D; // Funct3 field in Decode stage
logic [6:0] Funct7D; // Funct7 field in Decode stage
logic [4:0] Rs1D; // Rs1 source register in Decode stage
logic [4:0] Rs2D; // Rs2 source register in Decode stage
`define BMUCTRLW 7
`define BMUCTRLW 10
logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals
@ -57,70 +59,74 @@ module bmuctrl(
assign OpD = InstrD[6:0];
assign Funct3D = InstrD[14:12];
assign Funct7D = InstrD[31:25];
assign Rs1D = InstrD[19:15];
assign Rs2D = InstrD[24:20];
// Main Instruction Decoder
always_comb
casez({OpD, Funct7D, Funct3D})
// ALUSelect_BSelect
17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001; // bclri
17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_000; // bclri
17'b0010011_0100101_001: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b111_0001; // bclri (rv64)
BMUControlsD = `BMUCTRLW'b111_0001_000; // bclri (rv64)
else
BMUControlsD = `BMUCTRLW'b000_0000; // illegal instruction
17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001; // bexti
BMUControlsD = `BMUCTRLW'b000_0000_000; // illegal instruction
17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_000; // bexti
17'b0010011_0100101_101: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b101_0001; // bexti (rv64)
BMUControlsD = `BMUCTRLW'b101_0001_000; // bexti (rv64)
else
BMUControlsD = `BMUCTRLW'b000_0000; // illegal instruction
17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001; // binvi
BMUControlsD = `BMUCTRLW'b000_0000_000; // illegal instruction
17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_000; // binvi
17'b0010011_0110101_001: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b100_0001; // binvi (rv64)
BMUControlsD = `BMUCTRLW'b100_0001_000; // binvi (rv64)
else
BMUControlsD = `BMUCTRLW'b000_0000; // illegal instruction
17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001; // bseti
BMUControlsD = `BMUCTRLW'b000_0000_000; // illegal instruction
17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_000; // bseti
17'b0010011_0010101_001: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b110_0001; // bseti
BMUControlsD = `BMUCTRLW'b110_0001_000; // bseti
else
BMUControlsD = `BMUCTRLW'b000_0000; // illegal instruction
17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001; // bclr
17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001; // bext
17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001; // binv
17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001; // bset
17'b0?1?011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000; // sra, srai, srl, srli, sll, slli
17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_0010; // ZBC instruction
17'b0110011_0010000_?01: BMUControlsD = `BMUCTRLW'b001_1000; // slli.uw
17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_1000; // sh1add
17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_1000; // sh2add
17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_1000; // sh3add
17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_1000; // sh1add.uw
17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_1000; // sh2add.uw
17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_1000; // sh3add.uw
17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_1000; // add.uw
17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_1000; // slli.uw
17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0100; // rol
17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0100; // rolw
17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100; // ror
17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100; // rorw
17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100; // rori (rv32)
BMUControlsD = `BMUCTRLW'b000_0000_000; // illegal instruction
17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_000; // bclr
17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_000; // bext
17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_000; // binv
17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_000; // bset
17'b0?1?011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_000; // sra, srai, srl, srli, sll, slli
17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_0010_000; // ZBC instruction
17'b0110011_0010000_?01: BMUControlsD = `BMUCTRLW'b001_1000_000; // slli.uw
17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_1000_000; // sh1add
17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_1000_000; // sh2add
17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_1000_000; // sh3add
17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_1000_000; // sh1add.uw
17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_1000_000; // sh2add.uw
17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_1000_000; // sh3add.uw
17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_1000_000; // add.uw
17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_1000_000; // slli.uw
17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0100_111; // rol
17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0100_111; // rolw
17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111; // ror
17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111; // rorw
17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111; // rori (rv32)
17'b0010011_0110001_101: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b001_0100; // rori (rv64)
BMUControlsD = `BMUCTRLW'b001_0100_111; // rori (rv64)
else
BMUControlsD = `BMUCTRLW'b000_0000; //illegal instruction
BMUControlsD = `BMUCTRLW'b000_0000_000; // illegal instruction
17'b0011011_0110000_101: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b001_0100; // roriw
BMUControlsD = `BMUCTRLW'b001_0100_111; // roriw
else
BMUControlsD = `BMUCTRLW'b000_0000; //illegal instruction
BMUControlsD = `BMUCTRLW'b000_0000_000; // illegal instruction
17'b0010011_0110000_001: if (Rs2D[2])
BMUControlsD = `BMUCTRLW'b000_0100_000; // count instruction
else
BMUControlsD = `BMUCTRLW'b000_0100_100; // sign ext instruction
default: BMUControlsD = {Funct3D, {4'b0}}; // not B instruction or shift
default: BMUControlsD = {Funct3D, {7'b0}}; // not B instruction or shift
endcase
// Unpack Control Signals
assign {ALUSelectD,BSelectD} = BMUControlsD;
assign {ALUSelectD,BSelectD,ZBBSelectD} = BMUControlsD;
// BMU Execute stage pipieline control register
flopenrc#(7) controlregBMU(clk, reset, FlushE, ~StallE, {ALUSelectD, BSelectD}, {ALUSelectE, BSelectE});
flopenrc#(10) controlregBMU(clk, reset, FlushE, ~StallE, {ALUSelectD, BSelectD, ZBBSelectD}, {ALUSelectE, BSelectE, ZBBSelectE});
endmodule

View File

@ -33,10 +33,12 @@
module cnt #(parameter WIDTH = 32) (
input logic [WIDTH-1:0] A, B, // Operands
input logic W64, // Indicates word operation
output logic [WIDTH-1:0] czResult, // count zeros result
output logic [WIDTH-1:0] cpopResult);// population count result
output logic [WIDTH-1:0] CntResult // count result
);
//count instructions
logic [WIDTH-1:0] czResult; // count zeros result
logic [WIDTH-1:0] cpopResult; // population count result
logic [WIDTH-1:0] lzcA, popcntA;
logic [WIDTH-1:0] revA;
@ -81,4 +83,6 @@ module cnt #(parameter WIDTH = 32) (
lzc #(WIDTH) lzc(.num(lzcA), .ZeroCnt(czResult));
popcnt #(WIDTH) popcntw(.num(popcntA), .PopCnt(cpopResult));
assign CntResult = (B[1]) ? cpopResult : czResult;
endmodule

View File

@ -32,16 +32,14 @@
module zbb #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, B, // Operands
input logic [2:0] Funct3, // Indicates operation to perform
input logic [6:0] Funct7, // Indicates operation to perform
input logic W64, // Indicates word operation
input logic [2:0] ZBBSelect, // Indicates word operation
output logic [WIDTH-1:0] ZBBResult); // ZBB result
// count results
logic [WIDTH-1:0] czResult; // count zeros result (lzc or tzc)
logic [WIDTH-1:0] cpopResult; // population count result
// count result
logic [WIDTH-1:0] CntResult;
// byte results
logic [WIDTH-1:0] OrcBResult;
@ -52,14 +50,14 @@ module zbb #(parameter WIDTH=32) (
logic [WIDTH-1:0] sextbResult; // sign extend byte result
logic [WIDTH-1:0] zexthResult; // zero extend halfword result
cnt #(WIDTH) cnt(.A(A), .B(B), .W64(W64), .czResult(czResult), .cpopResult(cpopResult));
cnt #(WIDTH) cnt(.A(A), .B(B), .W64(W64), .CntResult(CntResult));
byteUnit #(WIDTH) bu(.A(A), .OrcBResult(OrcBResult), .Rev8Result(Rev8Result));
ext #(WIDTH) ext(.A(A), .sexthResult(sexthResult), .sextbResult(sextbResult), .zexthResult(zexthResult));
//can replace with structural mux by looking at bit 4 in rs2 field
always_comb begin
case ({Funct7, Funct3, B[4:0]})
15'b0010100_101_00111: ZBBResult = OrcBResult;
case (ZBBSelect)
/*15'b0010100_101_00111: ZBBResult = OrcBResult;
15'b0110100_101_11000: ZBBResult = Rev8Result;
15'b0110101_101_11000: ZBBResult = Rev8Result;
15'b0110000_001_00000: ZBBResult = czResult;
@ -67,7 +65,7 @@ module zbb #(parameter WIDTH=32) (
15'b0110000_001_00001: ZBBResult = czResult;
15'b0000100_100_00000: ZBBResult = zexthResult;
15'b0110000_001_00100: ZBBResult = sextbResult;
15'b0110000_001_00101: ZBBResult = sexthResult;
15'b0110000_001_00101: ZBBResult = sexthResult;*/
default: ZBBResult = {(WIDTH){1'b0}};
endcase
end

View File

@ -56,6 +56,7 @@ module controller(
output logic SCE, // Store Conditional instruction
output logic BranchSignedE, // Branch comparison operands are signed (if it's a branch)
output logic [3:0] BSelectE, // One-Hot encoding of if it's ZBA_ZBB_ZBC_ZBS instruction
output logic [2:0] ZBBSelectE, // ZBB mux select signal in Execute stage
// Memory stage control signals
input logic StallM, FlushM, // Stall, flush Memory stage
output logic [1:0] MemRWM, // Mem read/write: MemRWM[1] = 1 for read, MemRWM[0] = 1 for write
@ -117,6 +118,7 @@ module controller(
logic SFenceVmaD; // sfence.vma instruction
logic IntDivM; // Integer divide instruction
logic [3:0] BSelectD; // One-Hot encoding if it's ZBA_ZBB_ZBC_ZBS instruction in decode stage
logic [2:0] ZBBSelectD; // ZBB Mux Select Signal
// Extract fields
@ -216,11 +218,13 @@ module controller(
assign ALUControlD = {W64D, SubArithD, ALUOpD};
if (`ZBS_SUPPORTED) begin: bitmanipi //change the conditional expression to OR any Z supported flags
bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUSelectD, .BSelectD, .StallE, .FlushE, .ALUSelectE, .BSelectE);
bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUSelectD, .BSelectD, .ZBBSelectD, .StallE, .FlushE, .ALUSelectE, .BSelectE, .ZBBSelectE);
end else begin: bitmanipi
assign ALUSelectD = Funct3D;
assign ALUSelectE = Funct3E;
assign BSelectE = 4'b0000;
assign BSelectD = 4'b0000;
assign ZBBSelectE = 3'b000;
end
// Fences

View File

@ -18,6 +18,7 @@ module datapath (
input logic JumpE, // Is a jump (j) instruction
input logic BranchSignedE, // Branch comparison operands are signed (if it's a branch)
input logic [3:0] BSelectE, // One hot encoding of ZBA_ZBB_ZBC_ZBS instruction
input logic [2:0] ZBBSelectE, // ZBB mux select signal
output logic [1:0] FlagsE, // Comparison flags ({eq, lt})
output logic [`XLEN-1:0] IEUAdrE, // Address computed by ALU
output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU sources before the mux chooses between them and PCE to put in srcA/B
@ -82,7 +83,7 @@ module datapath (
comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE);
mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE);
alu #(`XLEN) alu(SrcAE, SrcBE, ALUControlE, ALUSelectE, BSelectE, Funct3E, ALUResultE, IEUAdrE);
alu #(`XLEN) alu(SrcAE, SrcBE, ALUControlE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, ALUResultE, IEUAdrE);
mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE);
mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);

View File

@ -83,6 +83,7 @@ module ieu (
logic FWriteIntM; // FPU writing to integer register file
logic IntDivW; // Integer divide instruction
logic [3:0] BSelectE; // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding
logic [2:0] ZBBSelectE;
// Forwarding signals
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E; // Source and destination registers
@ -96,7 +97,7 @@ module ieu (
controller c(
.clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD,
.IllegalIEUInstrFaultD, .IllegalBaseInstrFaultD, .StallE, .FlushE, .FlagsE, .FWriteIntE,
.PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .BSelectE, .MemReadE, .CSRReadE,
.PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .BSelectE, .ZBBSelectE, .MemReadE, .CSRReadE,
.Funct3E, .IntDivE, .MDUE, .W64E, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM,
.CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
@ -105,7 +106,7 @@ module ieu (
datapath dp(
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
.ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE,
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE,
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE,
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
.StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,
.CSRReadValW, .MDUResultW, .FIntDivResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW);