Merge branch 'bit-manip' of github.com:kipmacsaigoren/cvw into bit-manip

This commit is contained in:
Kip Macsai-Goren 2023-03-03 09:56:51 -08:00
commit 9b4b0c7901
3 changed files with 97 additions and 98 deletions

View File

@ -58,15 +58,18 @@ module alu #(parameter WIDTH=32) (
logic [WIDTH-1:0] rotA; // XLEN bit input source to shifter logic [WIDTH-1:0] rotA; // XLEN bit input source to shifter
logic [1:0] shASelect; // select signal for shifter source generation mux logic [1:0] shASelect; // select signal for shifter source generation mux
assign shASelect = {W64,SubArith};
// Extract control signals from ALUControl.
assign {W64, SubArith, ALUOp} = ALUControl;
// Pack control signals into shifter select
assign shASelect = {W64,SubArith};
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);
assign CondMaskB = (BSelect[0]) ? MaskB : B; assign CondMaskB = (BSelect[0]) ? MaskB : B;
end else assign CondMaskB = B; end else assign CondMaskB = B;
// Sign/Zero extend mux // Sign/Zero extend mux
if (WIDTH == 64) begin // rv64 must handle word s/z extensions if (WIDTH == 64) begin // rv64 must handle word s/z extensions
always_comb always_comb
@ -99,9 +102,6 @@ module alu #(parameter WIDTH=32) (
assign Rotate = BSelect[2] & (ALUSelect == 3'b001); //NOTE: Do we want to move this logic into the Decode Stage? assign Rotate = BSelect[2] & (ALUSelect == 3'b001); //NOTE: Do we want to move this logic into the Decode Stage?
end else assign Rotate = 1'b0; end else assign Rotate = 1'b0;
// Extract control signals from ALUControl.
assign {W64, SubArith, ALUOp} = ALUControl;
// Addition // Addition
assign CondInvB = SubArith ? ~CondMaskB : CondMaskB; assign CondInvB = SubArith ? ~CondMaskB : CondMaskB;
assign {Carry, Sum} = CondShiftA + CondInvB + {{(WIDTH-1){1'b0}}, SubArith}; assign {Carry, Sum} = CondShiftA + CondInvB + {{(WIDTH-1){1'b0}}, SubArith};

View File

@ -35,12 +35,14 @@ 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 output logic [2:0] ALUSelectD, // ALU Mux select signal in Decode Stage
output logic [3:0] BSelectD, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding in Decode stage 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? 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 output logic BRegWriteD, // Indicates if it is a R type B instruction in Decode Stage
output logic BW64D, // Indiciates if it is a W type B instruction 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 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 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] ALUSelectE,
@ -54,7 +56,7 @@ module bmuctrl(
logic [6:0] Funct7D; // Funct7 field in Decode stage logic [6:0] Funct7D; // Funct7 field in Decode stage
logic [4:0] Rs2D; // Rs2 source register in Decode stage logic [4:0] Rs2D; // Rs2 source register in Decode stage
`define BMUCTRLW 13 `define BMUCTRLW 15
logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals
@ -68,94 +70,93 @@ module bmuctrl(
// Main Instruction Decoder // Main Instruction Decoder
always_comb always_comb
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
// ALUSelect_BSelect_ZBBSelect_BRegWrite_BW64_BALUOp // ALUSelect_BSelect_ZBBSelect_BRegWrite_BW64_BALUOp_BSubArithD_IllegalBitmanipInstrD
// ZBS // ZBS
17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_000_1_0_1; // bclri 17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_000_1_0_1_1_0; // bclri
17'b0010011_0100101_001: if (`XLEN == 64) 17'b0010011_0100101_001: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b111_0001_000_1_0_1; // bclri (rv64) BMUControlsD = `BMUCTRLW'b111_0001_000_1_0_1_1_0; // bclri (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0; // illegal instruction BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_1; // illegal instruction
17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_000_1_0_1; // bexti 17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_000_1_0_1_1_0; // bexti
17'b0010011_0100101_101: if (`XLEN == 64) 17'b0010011_0100101_101: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b101_0001_000_1_0_1; // bexti (rv64) BMUControlsD = `BMUCTRLW'b101_0001_000_1_0_1_1_0; // bexti (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0; // illegal instruction BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_1; // illegal instruction
17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_000_1_0_1; // binvi 17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_000_1_0_1_0_0; // binvi
17'b0010011_0110101_001: if (`XLEN == 64) 17'b0010011_0110101_001: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b100_0001_000_1_0_1; // binvi (rv64) BMUControlsD = `BMUCTRLW'b100_0001_000_1_0_1_0_0; // binvi (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0; // illegal instruction BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_1; // illegal instruction
17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_000_1_0_1; // bseti 17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_000_1_0_1_0_0; // bseti
17'b0010011_0010101_001: if (`XLEN == 64) 17'b0010011_0010101_001: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b110_0001_000_1_0_1; // bseti (rv64) BMUControlsD = `BMUCTRLW'b110_0001_000_1_0_1_0_0; // bseti (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0; // illegal instruction BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_1; // illegal instruction
17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_000_1_0_1; // bclr 17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_000_1_0_1_1_0; // bclr
17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_000_1_0_1; // bext 17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_000_1_0_1_1_0; // bext
17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_000_1_0_1; // binv 17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_000_1_0_1_0_0; // binv
17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_000_1_0_1; // bset 17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_000_1_0_1_0_0; // bset
17'b0?1?011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_000_1_0_1; // sra, srai, srl, srli, sll, slli 17'b0?1?011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_000_1_0_1_0_0; // sra, srai, srl, srli, sll, slli
// ZBC // ZBC
17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_0010_000_1_0_1; // ZBC instruction 17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_0010_000_1_0_1_0_0; // ZBC instruction
// ZBA // ZBA
17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_1000_000_1_0_1; // sh1add 17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_1000_000_1_0_1_0_0; // sh1add
17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_1000_000_1_0_1; // sh2add 17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_1000_000_1_0_1_0_0; // sh2add
17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_1000_000_1_0_1; // sh3add 17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_1000_000_1_0_1_0_0; // sh3add
17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1; // sh1add.uw 17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1_0_0; // sh1add.uw
17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1; // sh2add.uw 17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1_0_0; // sh2add.uw
17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1; // sh3add.uw 17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1_0_0; // sh3add.uw
17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1; // add.uw 17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1_0_0; // add.uw
17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_1000_000_1_1_1; // slli.uw 17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_1000_000_1_1_1_0_0; // slli.uw
// ZBB // ZBB
17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1; // rol 17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1_0_0; // rol
17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0100_111_1_1_1; // rolw 17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0100_111_1_1_1_0_0; // rolw
17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1; // ror 17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1_0_0; // ror
17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111_1_1_1; // rorw 17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111_1_1_1_0_0; // rorw
17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1; // rori (rv32) 17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1_0_0; // rori (rv32)
17'b0010011_0110001_101: if (`XLEN == 64) 17'b0010011_0110001_101: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1; // rori (rv64) BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1_0_0; // rori (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0; // illegal instruction BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_1; // illegal instruction
17'b0011011_0110000_101: if (`XLEN == 64) 17'b0011011_0110000_101: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b001_0100_111_1_1_1; // roriw BMUControlsD = `BMUCTRLW'b001_0100_111_1_1_1_0_0; // roriw
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0; // illegal instruction BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_1; // illegal instruction
17'b0010011_0110000_001: if (Rs2D[2]) 17'b0010011_0110000_001: if (Rs2D[2])
BMUControlsD = `BMUCTRLW'b000_0100_100_1_0_1; // sign extend instruction BMUControlsD = `BMUCTRLW'b000_0100_100_1_0_1_0_0; // sign extend instruction
else else
BMUControlsD = `BMUCTRLW'b000_0100_000_1_0_1; // count instruction BMUControlsD = `BMUCTRLW'b000_0100_000_1_0_1_0_0; // count instruction
17'b0011011_0110000_001: BMUControlsD = `BMUCTRLW'b000_0100_000_1_1_1; // count word instruction 17'b0011011_0110000_001: BMUControlsD = `BMUCTRLW'b000_0100_000_1_1_1_0_0; // count word instruction
17'b0111011_0000100_100: if (`XLEN == 64) 17'b0111011_0000100_100: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b000_0100_100_1_0_1; // zexth (rv64) BMUControlsD = `BMUCTRLW'b000_0100_100_1_0_1_0_0; // zexth (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0; // illegal instruction BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_1; // illegal instruction
17'b0110011_0000100_100: if (`XLEN == 32) 17'b0110011_0000100_100: if (`XLEN == 32)
BMUControlsD = `BMUCTRLW'b000_0100_100_1_0_1; // zexth (rv32) BMUControlsD = `BMUCTRLW'b000_0100_100_1_0_1_0_0; // zexth (rv32)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0; // illegal instruction BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_1; // illegal instruction
17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_0100_111_1_0_1; // andn 17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_0100_111_1_0_1_1_0; // andn
17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_0100_111_1_0_1; // orn 17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_0100_111_1_0_1_1_0; // orn
17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_0100_111_1_0_1; // xnor 17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_0100_111_1_0_1_1_0; // xnor
17'b0010011_0110101_101: if (`XLEN == 64) 17'b0010011_0110101_101: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b000_0100_011_1_0_1; // rev8 (rv64) BMUControlsD = `BMUCTRLW'b000_0100_011_1_0_1_0_0; // rev8 (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0; // illegal instruction BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_1; // illegal instruction
17'b0010011_0110100_101: if (`XLEN == 32) 17'b0010011_0110100_101: if (`XLEN == 32)
BMUControlsD = `BMUCTRLW'b000_0100_011_1_0_1; // rev8 (rv32) BMUControlsD = `BMUCTRLW'b000_0100_011_1_0_1_0_0; // rev8 (rv32)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0; // illegal instruction BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_1; // illegal instruction
17'b0010011_0010100_101: BMUControlsD = `BMUCTRLW'b000_0100_011_1_0_1; // orc.b 17'b0010011_0010100_101: BMUControlsD = `BMUCTRLW'b000_0100_011_1_0_1_0_0; // orc.b
17'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_0100_101_1_0_1; // max 17'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_0100_101_1_0_1_0_0; // max
17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_0100_101_1_0_1; // maxu 17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_0100_101_1_0_1_0_0; // maxu
17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_0100_110_1_0_1; // min 17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_0100_110_1_0_1_0_0; // min
17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_0100_110_1_0_1; // minu 17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_0100_110_1_0_1_0_0; // minu
default: BMUControlsD = {Funct3D, {10'b0}}; // not B instruction or shift default: BMUControlsD = {Funct3D, {11'b0}, {1'b1}}; // not B instruction or shift
endcase endcase
// Unpack Control Signals // Unpack Control Signals
assign {ALUSelectD,BSelectD,ZBBSelectD, BRegWriteD, BW64D, BALUOpD, BSubArithD, IllegalBitmanipInstrD} = BMUControlsD;
assign {ALUSelectD,BSelectD,ZBBSelectD, BRegWriteD, BW64D, BALUOpD} = BMUControlsD;

View File

@ -92,6 +92,9 @@ 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 BaseRegWriteD; // Indicates if Base instruction register write instruction
logic BaseSubArithD; // Indicates if Base instruction subtracts, sra, slt, sltu
logic [2:0] ALUControlD; // Determines ALU operation logic [2:0] ALUControlD; // Determines ALU operation
logic [2:0] ALUSelectD; // ALU mux select signal logic [2:0] ALUSelectD; // ALU mux select signal
logic ALUSrcAD, ALUSrcBD; // ALU inputs logic ALUSrcAD, ALUSrcBD; // ALU inputs
@ -105,10 +108,8 @@ module controller(
logic PrivilegedD, PrivilegedE; // Privileged instruction logic PrivilegedD, PrivilegedE; // Privileged instruction
logic InvalidateICacheE, FlushDCacheE;// Invalidate I$, flush D$ logic InvalidateICacheE, FlushDCacheE;// Invalidate I$, flush D$
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 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 bclrD, bextD; // Indicates if is one of these instructions
logic andnD, ornD, xnorD; // Indicates if is one of these instructions
logic maxE, maxuE, minE, minuE; // Indicates if is one of these instructions in Execute Stage logic maxE, maxuE, minE, minuE; // Indicates if is one of these instructions in Execute Stage
logic BranchTakenE; // Branch is taken logic BranchTakenE; // Branch is taken
logic eqE, ltE; // Comparator outputs logic eqE, ltE; // Comparator outputs
@ -117,6 +118,7 @@ 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
@ -126,6 +128,7 @@ module controller(
logic BRegWriteD; // Indicates if it is a R type B instruction in decode stage logic BRegWriteD; // Indicates if it is a R type B instruction in decode stage
logic BW64D; // Indiciates if it is a W type B instruction in decode stage logic BW64D; // Indiciates 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 BALUOpD; // Indicates if it is an ALU B instruction in decode stage
logic BSubArithD; // TRUE for B-type ext, clr, andn, orn, xnor
// Extract fields // Extract fields
@ -137,7 +140,7 @@ module controller(
// Main Instruction Decoder // Main Instruction Decoder
always_comb always_comb
case(OpD) case(OpD)
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MDU_Atomic_Illegal // RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_BaseALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MDU_Atomic_Illegal
7'b0000000: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Illegal instruction 7'b0000000: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Illegal instruction
7'b0000011: ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // lw 7'b0000011: ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // lw
7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_1; // flw - only legal if FP supported 7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_1; // flw - only legal if FP supported
@ -162,14 +165,14 @@ module controller(
ControlsD = `CTRLW'b1_101_01_11_001_0_0_0_0_0_0_0_0_0_10_0; // amo ControlsD = `CTRLW'b1_101_01_11_001_0_0_0_0_0_0_0_0_0_10_0; // amo
end else end else
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
7'b0110011: if (Funct7D == 7'b0000000 | Funct7D == 7'b0100000 | ((`ZBB_SUPPORTED & BSelectD[2]) | (`ZBC_SUPPORTED & BSelectD[1]) | (`ZBS_SUPPORTED & BSelectD[0]) | (`ZBA_SUPPORTED & BSelectD[3]))) 7'b0110011: if (Funct7D == 7'b0000000 | Funct7D == 7'b0100000)
ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_0_0_0_0_0_00_0; // R-type ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_0_0_0_0_0_00_0; // R-type
else if (Funct7D == 7'b0000001 & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2]))) else if (Funct7D == 7'b0000001 & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])))
ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_0_0_0_0_1_00_0; // Multiply/divide ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_0_0_0_0_1_00_0; // Multiply/divide
else else
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_0_0_1_0_0_0_0_0_00_0; // lui 7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_0_0_1_0_0_0_0_0_00_0; // lui
7'b0111011: if ((Funct7D == 7'b0000000 | Funct7D == 7'b0100000 | (`ZBA_SUPPORTED & BSelectD[3]) | (`ZBB_SUPPORTED & BSelectD[2])) & `XLEN == 64) 7'b0111011: if ((Funct7D == 7'b0000000 | Funct7D == 7'b0100000) & `XLEN == 64)
ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_1_0_0_0_0_00_0; // R-type W instructions for RV64i ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_1_0_0_0_0_00_0; // R-type W instructions for RV64i
else if (Funct7D == 7'b0000001 & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])) & `XLEN == 64) else if (Funct7D == 7'b0000001 & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])) & `XLEN == 64)
ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_1_0_0_0_1_00_0; // W-type Multiply/Divide ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_1_0_0_0_1_00_0; // W-type Multiply/Divide
@ -192,11 +195,18 @@ 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] | IllegalERegAdrD; assign IllegalBaseInstrD = (ControlsD[0] & IllegalBitmanipInstrD) | IllegalERegAdrD ; //NOTE: Do we want to segregate the IllegalBitmanipInstrD into its own output signal
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD, //assign IllegalBaseInstrD = 1'b0;
ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, W64D, CSRReadD, assign {BaseRegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
ResultSrcD, BranchD, BaseALUOpD, 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 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
@ -211,27 +221,13 @@ module controller(
assign sltD = (Funct3D == 3'b010); assign sltD = (Funct3D == 3'b010);
end end
if (`ZBS_SUPPORTED) begin
assign bclrD = (ALUSelectD == 3'b111 & BSelectD[0]);
assign bextD = (ALUSelectD == 3'b101 & BSelectD[0]);
end else begin
assign bclrD = 1'b0;
assign bextD = 1'b0;
end
if (`ZBB_SUPPORTED) begin if (`ZBB_SUPPORTED) begin
assign andnD = (ALUSelectD == 3'b111 & BSelectD[2]);
assign ornD = (ALUSelectD == 3'b110 & BSelectD[2]);
assign xnorD = (ALUSelectD == 3'b100 & BSelectD[2]);
// we only need these signals if we want to calculate a signedD flag in decode stage to pass to the comparator. // we only need these signals if we want to calculate a signedD flag in decode stage to pass to the comparator.
assign maxE = (Funct3E[1:0] == 2'b10 & BSelectE[2]); assign maxE = (Funct3E[1:0] == 2'b10 & BSelectE[2]);
assign maxuE = (Funct3E[1:0] == 2'b11 & BSelectE[2]); assign maxuE = (Funct3E[1:0] == 2'b11 & BSelectE[2]);
assign minE = (Funct3E[1:0] == 2'b00 & BSelectE[2]); assign minE = (Funct3E[1:0] == 2'b00 & BSelectE[2]);
assign minuE = (Funct3E[1:0] == 2'b01 & BSelectE[2]); assign minuE = (Funct3E[1:0] == 2'b01 & BSelectE[2]);
end else begin end else begin
assign andnD = 0;
assign ornD = 0;
assign xnorD = 0;
assign maxE = 0; assign maxE = 0;
assign maxuE = 0; assign maxuE = 0;
assign minE = 0; assign minE = 0;
@ -242,13 +238,14 @@ module controller(
assign sltuD = (Funct3D == 3'b011); assign sltuD = (Funct3D == 3'b011);
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 ALUControlD = {W64D, SubArithD, ALUOpD};
// BITMANIP 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, .BRegWriteD, .BW64D, .BALUOpD, .StallE, .FlushE, .ALUSelectE, .BSelectE, .ZBBSelectE, .BRegWriteE); bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUSelectD, .BSelectD, .ZBBSelectD, .BRegWriteD, .BW64D, .BALUOpD, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE, .ALUSelectE, .BSelectE, .ZBBSelectE, .BRegWriteE);
assign RegWriteE = IEURegWriteE | FWriteIntE | BRegWriteE; // IRF register writes could come from IEU, BMU or FPU controllers //assign SubArithD = (ALUOpD) & (subD | sraD | sltD | sltuD | (`ZBS_SUPPORTED & (bextD | bclrD)) | (`ZBB_SUPPORTED & (andnD | ornD | xnorD))); // TRUE for R-type subtracts and sra, slt, sltu, and any B instruction that requires inverted operand
assign SubArithD = (ALUOpD | BALUOpD) & (subD | sraD | sltD | sltuD | (`ZBS_SUPPORTED & (bextD | bclrD)) | (`ZBB_SUPPORTED & (andnD | ornD | xnorD))); // TRUE for R-type subtracts and sra, slt, sltu, and any B instruction that requires inverted operand
assign ALUControlD = {(W64D | BW64D), SubArithD, ALUOpD};
end else begin: bitmanipi end else begin: bitmanipi
assign ALUSelectD = Funct3D; assign ALUSelectD = Funct3D;
assign ALUSelectE = Funct3E; assign ALUSelectE = Funct3E;
@ -259,10 +256,10 @@ module controller(
assign BW64D = 1'b0; assign BW64D = 1'b0;
assign BALUOpD = 1'b0; assign BALUOpD = 1'b0;
assign BRegWriteE = 1'b0; assign BRegWriteE = 1'b0;
assign BSubArithD = 1'b0;
assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers
assign SubArithD = ALUOpD & (subD | sraD | sltD | sltuD); assign IllegalBitmanipInstrD = 1'b1;
assign ALUControlD = {W64D, SubArithD, ALUOpD};
end end
// Fences // Fences
@ -299,6 +296,7 @@ module controller(
// Other execute stage controller signals // Other execute stage controller signals
assign MemReadE = MemRWE[1]; assign MemReadE = MemRWE[1];
assign SCE = (ResultSrcE == 3'b100); assign SCE = (ResultSrcE == 3'b100);
assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers
assign IntDivE = MDUE & Funct3E[2]; // Integer division operation assign IntDivE = MDUE & Funct3E[2]; // Integer division operation
// Memory stage pipeline control register // Memory stage pipeline control register