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

This commit is contained in:
Kip Macsai-Goren 2023-03-07 13:44:51 -08:00
commit 47bbe72d1f
15 changed files with 231 additions and 280 deletions

View File

@ -33,53 +33,61 @@ 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 [2:0] ALUControl, // With Funct3, indicates operation to perform
input logic [2:0] ALUSelect, // ALU mux select signal 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 [1: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] 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, // With ALUControl, indicates operation to perform NOTE: Change signal name to ALUSelect
input logic [1:0] CompFlags, // Comparator flags input logic [1:0] CompFlags, // Comparator flags
input logic Rotate, // Perform Rotate Operation input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage
output logic [WIDTH-1:0] ALUResult, // ALU result output logic [WIDTH-1:0] Result, // ALU result
output logic [WIDTH-1:0] Sum); // Sum of operands 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. // 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. // FullResult = ALU result before adjusting for a RV64 w-suffix instruction.
logic [WIDTH-1:0] CondInvB, Shift, SLT, SLTU, FullResult,CondExtFullResult, ZBCResult, ZBBResult; // Intermediate results logic [WIDTH-1:0] CondInvB,CondMaskInvB, Shift, SLT, SLTU, FullResult,ALUResult; // Intermediate Signals
logic [WIDTH-1:0] ZBCResult, ZBBResult; // Result of ZBB, ZBC
logic [WIDTH-1:0] MaskB; // BitMask of B logic [WIDTH-1:0] MaskB; // BitMask of B
logic [WIDTH-1:0] CondMaskB; // Result of B mask select mux logic [WIDTH-1:0] CondMaskB; // Result of B mask select mux
logic [WIDTH-1:0] CondShiftA; // Result of A shifted select mux logic [WIDTH-1:0] CondShiftA; // Result of A shifted select mux
logic [WIDTH-1:0] CondZextA; // Result of Zero Extend A select mux logic [WIDTH-1:0] CondExtA; // Result of Zero Extend A select mux
logic [WIDTH-1:0] RevA; // Bit-reversed A
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 W64; // RV64 W-type instruction
logic SubArith; // Performing subtraction or arithmetic right shift logic SubArith; // Performing subtraction or arithmetic right shift
logic ALUOp; // 0 for address generation addition or 1 for regular ALU ops 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 [WIDTH:0] shA; // XLEN+1 bit input source to shifter logic shSignA;
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
logic Rotate; // Indicates if it is Rotate instruction
logic Mask; // Indicates if it is ZBS instruction
logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction
logic [1:0] PreShiftAmt; // Amount to Pre-Shift A
// Extract control signals from ALUControl. // Extract control signals from ALUControl.
assign {W64, SubArith, ALUOp} = ALUControl; assign {W64, SubArith, ALUOp} = ALUControl;
// Extract control signals from bitmanip ALUControl.
assign {Rotate, Mask, PreShift} = BALUControl;
// Pack control signals into shifter select // Pack control signals into shifter select
assign shASelect = {W64,SubArith}; assign shASelect = {W64,SubArith};
assign PreShiftAmt = Funct3[2:1] & {2{PreShift}};
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 = (Mask) ? MaskB : B;
end else assign CondMaskB = B; end else assign CondMaskB = B;
// Sign/Zero extend mux
if (WIDTH == 64) begin // rv64 must handle word s/z extensions if (WIDTH == 64) begin
always_comb mux3 #(1) signmux(A[63], A[31], 1'b0, {~SubArith, W64}, shSignA);
case (shASelect) mux3 #(64) extendmux({{32{1'b0}}, A[31:0]},{{32{A[31]}}, A[31:0]}, A,{~W64, SubArith}, CondExtA);
2'b00: shA = {{1'b0}, A}; end else begin
2'b01: shA = {A[63], A}; mux2 #(1) signmux(1'b0, A[31], SubArith, shSignA);
2'b10: shA = {{33'b0}, A[31:0]}; assign CondExtA = A;
2'b11: shA = {{33{A[31]}}, A[31:0]}; end
endcase
end else assign shA = (SubArith) ? {A[31], A} : {{1'b0},A}; // rv32 does need to handle s/z extensions
// shifter rotate source select mux // shifter rotate source select mux
if (`ZBB_SUPPORTED) begin if (`ZBB_SUPPORTED) begin
@ -88,22 +96,17 @@ module alu #(parameter WIDTH=32) (
end else assign rotA = A; end else assign rotA = A;
if (`ZBA_SUPPORTED) begin: zbamuxes if (`ZBA_SUPPORTED) begin: zbamuxes
// Pre-Shift Mux // Pre-Shift
always_comb assign CondShiftA = CondExtA << (PreShiftAmt);
case (Funct3[2:1] & {2{BSelect[3]}})
2'b00: CondShiftA = shA[WIDTH-1:0];
2'b01: CondShiftA = {shA[WIDTH-2:0],{1'b0}}; // sh1add
2'b10: CondShiftA = {shA[WIDTH-3:0],{2'b00}}; // sh2add
2'b11: CondShiftA = {shA[WIDTH-4:0],{3'b000}}; // sh3add
endcase
end else assign CondShiftA = A; end else assign CondShiftA = A;
// Addition // Addition
assign CondInvB = SubArith ? ~CondMaskB : CondMaskB; assign CondMaskInvB = SubArith ? ~CondMaskB : CondMaskB;
assign CondInvB = SubArith ? ~B : B;
assign {Carry, Sum} = CondShiftA + CondInvB + {{(WIDTH-1){1'b0}}, SubArith}; assign {Carry, Sum} = CondShiftA + CondInvB + {{(WIDTH-1){1'b0}}, SubArith};
// Shifts (configurable for rotation) // Shifts (configurable for rotation)
shifter sh(.shA(shA), .rotA(rotA), .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64(W64), .Y(Shift), .Rotate(Rotate)); shifter sh(.shA(CondExtA), .Sign(shSignA), .rotA(rotA), .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64(W64), .Y(Shift), .Rotate(Rotate));
// 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
@ -128,9 +131,9 @@ module alu #(parameter WIDTH=32) (
3'b001: FullResult = Shift; // sll, sra, or srl 3'b001: FullResult = Shift; // sll, sra, or srl
3'b010: FullResult = SLT; // slt 3'b010: FullResult = SLT; // slt
3'b011: FullResult = SLTU; // sltu 3'b011: FullResult = SLTU; // sltu
3'b100: FullResult = A ^ CondInvB; // xor, xnor, binv 3'b100: FullResult = A ^ CondMaskInvB; // xor, xnor, binv
3'b110: FullResult = A | CondInvB; // or, orn, bset 3'b110: FullResult = A | CondMaskInvB; // or, orn, bset
3'b111: FullResult = A & CondInvB; // and, bclr 3'b111: FullResult = A & CondMaskInvB; // and, bclr
3'b101: FullResult = {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}};// bext 3'b101: FullResult = {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}};// bext
endcase endcase
end end
@ -146,33 +149,33 @@ module alu #(parameter WIDTH=32) (
3'b110: FullResult = A | B; // or 3'b110: FullResult = A | B; // or
3'b111: FullResult = A & B; // and 3'b111: FullResult = A & B; // and
endcase endcase
end end
if (`ZBC_SUPPORTED | `ZBB_SUPPORTED) begin: bitreverse
bitreverse #(WIDTH) brA(.a(A), .b(RevA));
end
// Support RV64I W-type addw/subw/addiw/shifts that discard upper 32 bits and sign-extend 32-bit result to 64 bits
if (WIDTH == 64) assign CondExtFullResult = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult;
else assign CondExtFullResult = FullResult;
//NOTE: This looks good and can be merged.
if (`ZBC_SUPPORTED) begin: zbc if (`ZBC_SUPPORTED) begin: zbc
zbc #(WIDTH) ZBC(.A(A), .B(B), .Funct3(Funct3), .ZBCResult(ZBCResult)); zbc #(WIDTH) ZBC(.A(A), .RevA(RevA), .B(B), .Funct3(Funct3), .ZBCResult(ZBCResult));
end else assign ZBCResult = 0; end else assign ZBCResult = 0;
if (`ZBB_SUPPORTED) begin: zbb if (`ZBB_SUPPORTED) begin: zbb
zbb #(WIDTH) ZBB(.A(A), .B(B), .ALUResult(CondExtFullResult), .W64(W64), .lt(CompFlags[0]), .ZBBSelect(ZBBSelect), .ZBBResult(ZBBResult)); zbb #(WIDTH) ZBB(.A(A), .RevA(RevA), .B(B), .ALUResult(ALUResult), .W64(W64), .lt(CompFlags[0]), .ZBBSelect(ZBBSelect), .ZBBResult(ZBBResult));
end else assign ZBBResult = 0; end else assign ZBBResult = 0;
// Support RV64I W-type addw/subw/addiw/shifts that discard upper 32 bits and sign-extend 32-bit result to 64 bits
if (WIDTH == 64) assign ALUResult = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult;
else assign ALUResult = FullResult;
// Final Result B instruction select mux // Final Result B instruction select mux
if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : zbdecoder if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : zbdecoder
always_comb always_comb
case (BSelect) case (BSelect)
//ZBA_ZBB_ZBC_ZBS // 00: ALU, 01: ZBA/ZBS, 10: ZBB, 11: ZBC
4'b0001: ALUResult = FullResult; 2'b00: Result = ALUResult;
4'b0010: ALUResult = ZBCResult; 2'b01: Result = FullResult; // NOTE: We don't use ALUResult because ZBA/ZBS instructions don't sign extend the MSB of the right-hand word.
4'b1000: ALUResult = FullResult; // NOTE: We don't use ALUResult because ZBA instructions don't sign extend the MSB of the right-hand word. 2'b10: Result = ZBBResult;
4'b0100: ALUResult = ZBBResult; 2'b11: Result = ZBCResult;
default: ALUResult = CondExtFullResult;
endcase endcase
end else assign ALUResult = CondExtFullResult; end else assign Result = ALUResult;
endmodule endmodule

View File

@ -0,0 +1,32 @@
"""
bitfieldedit.py
Script that appends 0 just before the "illegal instruction" field of the bitstring
Written by Kevin Kim <kekim@hmc.edu>
"""
def addZero(s):
try:
indexSemicolon = s.index(";")
newS = s[:indexSemicolon-1]+"0_"+s[indexSemicolon-1:]
return newS
except: return s
def main():
filename = input("Enter full filename: ")
n1 = int(input("Line number to begin: "))
n2 = int(input("Line number to end: "))
f = open(filename, "r")
flines = f.readlines()
#create list of lines from line n1 to n2, inclusive
lines = flines[(n1-1):(n2-1)]
#string to be printed
out = ""
for i in range(len(lines)):
lines[i] = addZero(lines[i])
out += lines[i]
print(out)
if __name__ == "__main__":
main()

View File

@ -4,9 +4,9 @@
// //
// Written: Kevin Kim <kekim@hmc.edu> and Kip Macsai-Goren <kmacsaigoren@hmc.edu> // Written: Kevin Kim <kekim@hmc.edu> and Kip Macsai-Goren <kmacsaigoren@hmc.edu>
// Created: 1 February 2023 // Created: 1 February 2023
// Modified: // Modified: 6 March 2023
// //
// Purpose: Carry-Less multiplication top-level unit // Purpose: Bit reverse submodule
// //
// Documentation: RISC-V System on Chip Design Chapter *** // Documentation: RISC-V System on Chip Design Chapter ***
// //
@ -37,7 +37,6 @@ module bitreverse #(parameter WIDTH=32) (
for (i=0; i<WIDTH;i++) begin:loop for (i=0; i<WIDTH;i++) begin:loop
assign b[WIDTH-i-1] = a[i]; assign b[WIDTH-i-1] = a[i];
end end
endmodule endmodule

View File

@ -1,11 +1,11 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// controller.sv // bmuctrl.sv
// //
// Written: Kevin Kim <kekim@hmc.edu> // Written: Kevin Kim <kekim@hmc.edu>
// Created: 16 February 2023 // Created: 16 February 2023
// Modified: // Modified: 6 March 2023
// //
// Purpose: Top level B instrution controller module // Purpose: Top level bit manipulation instruction decoder
// //
// Documentation: RISC-V System on Chip Design Chapter 4 (Section 4.1.4, Figure 4.8, Table 4.5) // Documentation: RISC-V System on Chip Design Chapter 4 (Section 4.1.4, Figure 4.8, Table 4.5)
// //
@ -29,14 +29,13 @@
`include "wally-config.vh" `include "wally-config.vh"
// NOTE: DO we want to make this XLEN parameterized?
module bmuctrl( module bmuctrl(
input logic clk, reset, input logic clk, reset,
// 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 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 [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 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
@ -46,11 +45,11 @@ module bmuctrl(
// 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,
output logic [3: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
output logic BComparatorSignedE, // Indicates if comparator signed in Execute Stage output logic BComparatorSignedE, // Indicates if comparator signed in Execute Stage
output logic RotateE // Indiciates if rotate instruction in Execute Stage output logic [2:0] BALUControlE // ALU Control signals for B instructions in Execute Stage
); );
logic [6:0] OpD; // Opcode in Decode stage logic [6:0] OpD; // Opcode in Decode stage
@ -59,12 +58,14 @@ module bmuctrl(
logic [4:0] Rs2D; // Rs2 source register in Decode stage logic [4:0] Rs2D; // Rs2 source register in Decode stage
logic BComparatorSignedD; // Indicates if comparator signed (max, min instruction) in Decode Stage logic BComparatorSignedD; // Indicates if comparator signed (max, min instruction) in Decode Stage
logic RotateD; // Indicates if rotate instruction in Decode Stage logic RotateD; // Indicates if rotate 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 [2:0] BALUControlD; // ALU Control signals for B instructions
`define BMUCTRLW 16 `define BMUCTRLW 16
logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals
// Extract fields // Extract fields
assign OpD = InstrD[6:0]; assign OpD = InstrD[6:0];
assign Funct3D = InstrD[14:12]; assign Funct3D = InstrD[14:12];
@ -74,98 +75,99 @@ 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_BSubArithD_RotateD_IllegalBitmanipInstrD // ALUSelect_BSelect_ZBBSelect_BRegWrite_BW64_BALUOp_BSubArithD_RotateD_MaskD_PreShiftD_IllegalBitmanipInstrD
// ZBS // ZBS
17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_000_1_0_1_1_0_0; // bclri 17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_0_1_1_0_1_0_0; // bclri
17'b0010011_0100101_001: if (`XLEN == 64) 17'b0010011_0100101_001: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b111_0001_000_1_0_1_1_0_0; // bclri (rv64) BMUControlsD = `BMUCTRLW'b111_01_000_1_0_1_1_0_1_0_0; // bclri (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_0_1; // illegal instruction BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_1; // illegal instruction
17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_000_1_0_1_1_0_0; // bexti 17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_0_1_1_0_1_0_0; // bexti
17'b0010011_0100101_101: if (`XLEN == 64) 17'b0010011_0100101_101: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b101_0001_000_1_0_1_1_0_0; // bexti (rv64) BMUControlsD = `BMUCTRLW'b101_01_000_1_0_1_1_0_1_0_0; // bexti (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_0_1; // illegal instruction BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_1; // illegal instruction
17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_000_1_0_1_0_0_0; // binvi 17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_0_1_0_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_0_0_0; // binvi (rv64) BMUControlsD = `BMUCTRLW'b100_01_000_1_0_1_0_0_1_0_0; // binvi (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_0_1; // illegal instruction BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_1; // illegal instruction
17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_000_1_0_1_0_0_0; // bseti 17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_0_1_0_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_0_0_0; // bseti (rv64) BMUControlsD = `BMUCTRLW'b110_01_000_1_0_1_0_0_1_0_0; // bseti (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_0_1; // illegal instruction BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_1; // illegal instruction
17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_0001_000_1_0_1_1_0_0; // bclr 17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_0_1_1_0_1_0_0; // bclr
17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_000_1_0_1_1_0_0; // bext 17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_0_1_1_0_1_0_0; // bext
17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_000_1_0_1_0_0_0; // binv 17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_0_1_0_0_1_0_0; // binv
17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_000_1_0_1_0_0_0; // bset 17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_0_1_0_0_1_0_0; // bset
17'b0?1?011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_000_1_0_1_0_0_0; // sra, srai, srl, srli, sll, slli 17'b0?1?011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_0_1_0_0_0_0_0; // sra, srai, srl, srli, sll, slli
// ZBC // ZBC
17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_0010_000_1_0_1_0_0_0; // ZBC instruction 17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_11_000_1_0_1_0_0_0_0_0; // ZBC instruction
// ZBA // ZBA
17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_1000_000_1_0_1_0_0_0; // sh1add 17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_0_0_0_1_0; // sh1add
17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_1000_000_1_0_1_0_0_0; // sh2add 17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_0_0_0_1_0; // sh2add
17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_1000_000_1_0_1_0_0_0; // sh3add 17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_0_0_0_1_0; // sh3add
17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1_0_0_0; // sh1add.uw 17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_1_1_0_0_0_1_0; // sh1add.uw
17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1_0_0_0; // sh2add.uw 17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_1_1_0_0_0_1_0; // sh2add.uw
17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1_0_0_0; // sh3add.uw 17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_01_000_1_1_1_0_0_0_1_0; // sh3add.uw
17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1_0_0_0; // add.uw 17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_01_000_1_1_1_0_0_0_0_0; // add.uw
17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_1000_000_1_1_1_0_0_0; // slli.uw 17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_01_000_1_1_1_0_0_0_0_0; // slli.uw
// ZBB // ZBB
17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1_0_1_0; // rol 17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_1_0_1_0_0_0; // rol
17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0100_111_1_1_1_0_1_0; // rolw 17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_1_0_1_0_0_0; // rolw
17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1_0_1_0; // ror 17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_1_0_1_0_0_0; // ror
17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111_1_1_1_0_1_0; // rorw 17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_1_0_1_0_0_0; // rorw
17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1_0_1_0; // rori (rv32) 17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_0_1_0_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_0_1_0; // rori (rv64) BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_0_1_0_0_0; // rori (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_0_1; // illegal instruction BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_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_0_1_0; // roriw BMUControlsD = `BMUCTRLW'b001_00_111_1_1_1_0_1_0_0_0; // roriw
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_0_1; // illegal instruction BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_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_0_0_0; // sign extend instruction BMUControlsD = `BMUCTRLW'b000_10_001_1_0_1_0_0_0_0_0; // sign extend instruction
else else
BMUControlsD = `BMUCTRLW'b000_0100_000_1_0_1_0_0_0; // count instruction BMUControlsD = `BMUCTRLW'b000_10_000_1_0_1_0_0_0_0_0; // count instruction
17'b0011011_0110000_001: BMUControlsD = `BMUCTRLW'b000_0100_000_1_1_1_0_0_0; // count word instruction 17'b0011011_0110000_001: BMUControlsD = `BMUCTRLW'b000_10_000_1_1_1_0_0_0_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_0_0_0; // zexth (rv64) BMUControlsD = `BMUCTRLW'b000_10_001_1_0_1_0_0_0_0_0; // zexth (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_0_1; // illegal instruction BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_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_0_0_0; // zexth (rv32) BMUControlsD = `BMUCTRLW'b000_10_001_1_0_1_0_0_0_0_0; // zexth (rv32)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_0_1; // illegal instruction BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_1; // illegal instruction
17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_0100_111_1_0_1_1_0_0; // andn 17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_01_111_1_0_1_1_0_0_0_0; // andn
17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_0100_111_1_0_1_1_0_0; // orn 17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_01_111_1_0_1_1_0_0_0_0; // orn
17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_0100_111_1_0_1_1_0_0; // xnor 17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_01_111_1_0_1_1_0_0_0_0; // xnor
17'b0010011_0110101_101: if (`XLEN == 64) 17'b0010011_0110101_101: if (`XLEN == 64)
BMUControlsD = `BMUCTRLW'b000_0100_011_1_0_1_0_0_0; // rev8 (rv64) BMUControlsD = `BMUCTRLW'b000_10_010_1_0_1_0_0_0_0_0; // rev8 (rv64)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_0_1; // illegal instruction BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_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_0_0_0; // rev8 (rv32) BMUControlsD = `BMUCTRLW'b000_10_010_1_0_1_0_0_0_0_0; // rev8 (rv32)
else else
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_0_1; // illegal instruction BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_1; // illegal instruction
17'b0010011_0010100_101: BMUControlsD = `BMUCTRLW'b000_0100_011_1_0_1_0_0_0; // orc.b 17'b0010011_0010100_101: BMUControlsD = `BMUCTRLW'b000_10_010_1_0_1_0_0_0_0_0; // orc.b
17'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_0100_101_1_0_1_0_0_0; // max 17'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_10_100_1_0_1_0_0_0_0_0; // max
17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_0100_101_1_0_1_0_0_0; // maxu 17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_10_100_1_0_1_0_0_0_0_0; // maxu
17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_0100_110_1_0_1_0_0_0; // min 17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_1_0_0_0_0_0; // min
17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_0100_110_1_0_1_0_0_0; // minu 17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_1_0_0_0_0_0; // minu
default: BMUControlsD = {Funct3D, {12'b0}, {1'b1}}; // not B instruction or shift default: BMUControlsD = {Funct3D, {12'b0}, {1'b1}}; // not B instruction or shift
endcase endcase
// Unpack Control Signals // Unpack Control Signals
assign {ALUSelectD,BSelectD,ZBBSelectD, BRegWriteD, BW64D, BALUOpD, BSubArithD, RotateD, IllegalBitmanipInstrD} = BMUControlsD; assign {ALUSelectD,BSelectD,ZBBSelectD, BRegWriteD, BW64D, BALUOpD, BSubArithD, RotateD, MaskD, PreShiftD, IllegalBitmanipInstrD} = BMUControlsD;
// Pack BALUControl Signals
assign BALUControlD = {RotateD, MaskD, PreShiftD};
// 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];
// BMU Execute stage pipieline control register // BMU Execute stage pipieline control register
flopenrc#(13) controlregBMU(clk, reset, FlushE, ~StallE, {ALUSelectD, BSelectD, ZBBSelectD, BRegWriteD, BComparatorSignedD, RotateD}, {ALUSelectE, BSelectE, ZBBSelectE, BRegWriteE, BComparatorSignedE, RotateE}); flopenrc#(13) controlregBMU(clk, reset, FlushE, ~StallE, {ALUSelectD, BSelectD, ZBBSelectD, BRegWriteD, BComparatorSignedD, BALUControlD}, {ALUSelectE, BSelectE, ZBBSelectE, BRegWriteE, BComparatorSignedE, BALUControlE});
endmodule endmodule

View File

@ -1,11 +1,11 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// clmul.sv // byte.sv
// //
// Written: Kevin Kim <kekim@hmc.edu> // Written: Kevin Kim <kekim@hmc.edu>
// Created: 1 February 2023 // Created: 1 February 2023
// Modified: // Modified: 6 March 2023
// //
// Purpose: Carry-Less multiplication top-level unit // Purpose: RISCV bitmanip byte-wise operation unit
// //
// Documentation: RISC-V System on Chip Design Chapter *** // Documentation: RISC-V System on Chip Design Chapter ***
// //

View File

@ -1,11 +1,11 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// clmul.sv (carry-less multiplier) // clmul.sv
// //
// Written: Kevin Kim <kekim@hmc.edu> and Kip Macsai-Goren <kmacsaigoren@hmc.edu> // Written: Kevin Kim <kekim@hmc.edu> and Kip Macsai-Goren <kmacsaigoren@hmc.edu>
// Created: 1 February 2023 // Created: 1 February 2023
// Modified: // Modified:
// //
// Purpose: Carry-Less multiplication top-level unit // Purpose: Carry-Less multiplication unit
// //
// Documentation: RISC-V System on Chip Design Chapter *** // Documentation: RISC-V System on Chip Design Chapter ***
// //

View File

@ -31,7 +31,8 @@
`include "wally-config.vh" `include "wally-config.vh"
module cnt #(parameter WIDTH = 32) ( module cnt #(parameter WIDTH = 32) (
input logic [WIDTH-1:0] A, B, // Operands input logic [WIDTH-1:0] A, RevA, // Operands
input logic [4:0] B, // Last 5 bits of immediate
input logic W64, // Indicates word operation input logic W64, // Indicates word operation
output logic [WIDTH-1:0] CntResult // count result output logic [WIDTH-1:0] CntResult // count result
); );
@ -40,45 +41,19 @@ module cnt #(parameter WIDTH = 32) (
logic [WIDTH-1:0] czResult; // count zeros result logic [WIDTH-1:0] czResult; // count zeros result
logic [WIDTH-1:0] cpopResult; // population count result logic [WIDTH-1:0] cpopResult; // population count result
logic [WIDTH-1:0] lzcA, popcntA; logic [WIDTH-1:0] lzcA, popcntA;
logic [WIDTH-1:0] revA;
//in both rv64, rv32
bitreverse #(WIDTH) brtz(.a(A), .b(revA));
//only in rv64 //only in rv64
if (WIDTH==64) begin if (WIDTH==64) begin
//NOTE: signal widths can be decreased
always_comb begin
//clz input select mux //clz input select mux
case({B[4:0],W64}) mux4 #(WIDTH) lzcmux64(A, {A[31:0],{32{1'b1}}}, RevA, {RevA[63:32],{32{1'b1}}}, {B[0],W64}, lzcA);
6'b00000_0: lzcA = A; //clz
6'b00000_1: lzcA = {A[31:0],{32{1'b1}}}; //clzw
6'b00001_0: lzcA = revA; //ctz
6'b00001_1: lzcA = {revA[63:32],{32{1'b1}}}; //ctzw
default: lzcA = A;
endcase
//cpop select mux //cpop select mux
case ({B[4:0],W64}) mux2 #(WIDTH) popcntmux64(A, {{32{1'b0}}, A[31:0]}, W64, popcntA);
6'b00010_0: popcntA = A;
6'b00010_1: popcntA = {{32{1'b0}}, A[31:0]};
default: popcntA = A;
endcase
end end
end
else begin
//rv32 //rv32
else begin
assign popcntA = A; assign popcntA = A;
always_comb begin mux2 #(WIDTH) lzcmux32(A, RevA, B[0], lzcA);
//clz input slect mux
case(B[4:0])
5'b00000: lzcA = A;
5'b00001: lzcA = revA;
default: lzcA = A;
endcase
end end
end
lzc #(WIDTH) lzc(.num(lzcA), .ZeroCnt(czResult[$clog2(WIDTH):0])); lzc #(WIDTH) lzc(.num(lzcA), .ZeroCnt(czResult[$clog2(WIDTH):0]));
popcnt #(WIDTH) popcntw(.num(popcntA), .PopCnt(cpopResult[$clog2(WIDTH):0])); popcnt #(WIDTH) popcntw(.num(popcntA), .PopCnt(cpopResult[$clog2(WIDTH):0]));
@ -86,6 +61,5 @@ module cnt #(parameter WIDTH = 32) (
assign czResult[WIDTH-1:$clog2(WIDTH)+1] = {(WIDTH-$clog2(WIDTH)-1){1'b0}}; assign czResult[WIDTH-1:$clog2(WIDTH)+1] = {(WIDTH-$clog2(WIDTH)-1){1'b0}};
assign cpopResult[WIDTH-1:$clog2(WIDTH)+1] = {(WIDTH-$clog2(WIDTH)-1){1'b0}}; assign cpopResult[WIDTH-1:$clog2(WIDTH)+1] = {(WIDTH-$clog2(WIDTH)-1){1'b0}};
assign CntResult = (B[1]) ? cpopResult : czResult; mux2 #(WIDTH) cntresultmux(czResult, cpopResult, B[1], CntResult);
endmodule endmodule

View File

@ -1,6 +1,6 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// cnt.sv // ext.sv
// //
// Written: Kevin Kim <kekim@hmc.edu> // Written: Kevin Kim <kekim@hmc.edu>
// Created: 4 February 2023 // Created: 4 February 2023
@ -31,21 +31,15 @@
`include "wally-config.vh" `include "wally-config.vh"
module ext #(parameter WIDTH = 32) ( module ext #(parameter WIDTH = 32) (
input logic [WIDTH-1:0] A, B, // Operands input logic [WIDTH-1:0] A, // Operands
input logic [1:0] ExtSelect, // B[2], B[0] of immediate
output logic [WIDTH-1:0] ExtResult); // Extend Result output logic [WIDTH-1:0] ExtResult); // Extend Result
logic [WIDTH-1:0] sexthResult, zexthResult, sextbResult; logic [WIDTH-1:0] sexthResult, zexthResult, sextbResult;
assign sexthResult = {{(WIDTH-16){A[15]}},A[15:0]}; assign sexthResult = {{(WIDTH-16){A[15]}},A[15:0]};
assign zexthResult = {{(WIDTH-16){1'b0}},A[15:0]}; assign zexthResult = {{(WIDTH-16){1'b0}},A[15:0]};
assign sextbResult = {{(WIDTH-8){A[7]}},A[7:0]}; assign sextbResult = {{(WIDTH-8){A[7]}},A[7:0]};
always_comb mux3 #(WIDTH) extmux(sextbResult, sexthResult, zexthResult, ExtSelect, ExtResult);
case({B[2],B[0]})
2'b00: ExtResult = zexthResult;
2'b10: ExtResult = sextbResult;
2'b11: ExtResult = sexthResult;
default: ExtResult = 0;
endcase
endmodule endmodule

View File

@ -1,6 +1,6 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// // popccnt.sv
// Written: Kevin Kim <kekim@hmc.edu> // Written: Kevin Kim <kekim@hmc.edu>
// Modified: 2/4/2023 // Modified: 2/4/2023
// //
@ -39,6 +39,4 @@ module popcnt #(parameter WIDTH = 32) (
end end
assign PopCnt = sum[$clog2(WIDTH):0]; assign PopCnt = sum[$clog2(WIDTH):0];
endmodule endmodule

View File

@ -4,9 +4,9 @@
// //
// Written: Kevin Kim <kekim@hmc.edu> and Kip Macsai-Goren <kmacsaigoren@hmc.edu> // Written: Kevin Kim <kekim@hmc.edu> and Kip Macsai-Goren <kmacsaigoren@hmc.edu>
// Created: 2 February 2023 // Created: 2 February 2023
// Modified: // Modified: March 6 2023
// //
// Purpose: RISC-V miscellaneous bit manipulation unit (subset of ZBB instructions) // Purpose: RISC-V ZBB top level unit
// //
// Documentation: RISC-V System on Chip Design Chapter *** // Documentation: RISC-V System on Chip Design Chapter ***
// //
@ -31,57 +31,25 @@
`include "wally-config.vh" `include "wally-config.vh"
module zbb #(parameter WIDTH=32) ( module zbb #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, B, // Operands input logic [WIDTH-1:0] A, RevA, B, // Operands
input logic [WIDTH-1:0] ALUResult, // ALU Result input logic [WIDTH-1:0] ALUResult, // ALU Result
input logic W64, // Indicates word operation input logic W64, // Indicates word operation
input logic lt, // lt flag input logic lt, // lt flag
input logic [2:0] ZBBSelect, // Indicates word operation input logic [2:0] ZBBSelect, // Indicates word operation
output logic [WIDTH-1:0] ZBBResult); // ZBB result output logic [WIDTH-1:0] ZBBResult); // ZBB result
logic [WIDTH-1:0] CntResult; // count result
logic [WIDTH-1:0] MinResult,MaxResult; // min,max result
logic [WIDTH-1:0] ByteResult; // byte results
logic [WIDTH-1:0] ExtResult; // sign/zero extend results
cnt #(WIDTH) cnt(.A(A), .RevA(RevA), .B(B[4:0]), .W64(W64), .CntResult(CntResult));
// count result
logic [WIDTH-1:0] CntResult;
// min,max result
logic [WIDTH-1:0] MaxResult;
logic [WIDTH-1:0] MinResult;
// byte results
logic [WIDTH-1:0] ByteResult;
// sign/zero extend results
logic [WIDTH-1:0] ExtResult; // sign/zero extend result
cnt #(WIDTH) cnt(.A(A), .B(B), .W64(W64), .CntResult(CntResult));
byteUnit #(WIDTH) bu(.A(A), .ByteSelect(B[0]), .ByteResult(ByteResult)); byteUnit #(WIDTH) bu(.A(A), .ByteSelect(B[0]), .ByteResult(ByteResult));
ext #(WIDTH) ext(.A(A), .B(B), .ExtResult(ExtResult)); ext #(WIDTH) ext(.A(A), .ExtSelect({~B[2], {B[2] & B[0]}}), .ExtResult(ExtResult));
assign MaxResult = (lt) ? B : A; assign MaxResult = (lt) ? B : A;
assign MinResult = (lt) ? A : B; assign MinResult = (lt) ? A : B;
//can replace with structural mux by looking at bit 4 in rs2 field // ZBB Result select mux
always_comb begin mux5 #(WIDTH) zbbresultmux(CntResult, ExtResult, ByteResult, MinResult, MaxResult, ZBBSelect, ZBBResult);
case (ZBBSelect)
3'b111: ZBBResult = ALUResult; // rotates, andn, xnor, orn
3'b000: ZBBResult = CntResult; // count
3'b100: ZBBResult = ExtResult; // sign/zero extend
3'b011: ZBBResult = ByteResult; // byte instructions
3'b110: ZBBResult = MinResult; // min, minu
3'b101: ZBBResult = MaxResult; // max, maxu
/*15'b0010100_101_00111: ZBBResult = OrcBResult;
15'b0110100_101_11000: ZBBResult = Rev8Result;
15'b0110101_101_11000: ZBBResult = Rev8Result;
15'b0110000_001_00000: ZBBResult = czResult;
15'b0110000_001_00010: ZBBResult = cpopResult;
15'b0110000_001_00001: ZBBResult = czResult;
15'b0000100_100_00000: ZBBResult = zexthResult;
15'b0110000_001_00100: ZBBResult = sextbResult;
15'b0110000_001_00101: ZBBResult = sexthResult;*/
default: ZBBResult = {(WIDTH){1'b0}};
endcase
end
endmodule endmodule

View File

@ -3,9 +3,9 @@
// //
// Written: Kevin Kim <kekim@hmc.edu> and Kip Macsai-Goren <kmacsaigoren@hmc.edu> // Written: Kevin Kim <kekim@hmc.edu> and Kip Macsai-Goren <kmacsaigoren@hmc.edu>
// Created: 2 February 2023 // Created: 2 February 2023
// Modified: // Modified: 3 March 2023
// //
// Purpose: RISC-V single bit manipulation unit (ZBC instructions) // Purpose: RISC-V ZBC top-level unit
// //
// Documentation: RISC-V System on Chip Design Chapter *** // Documentation: RISC-V System on Chip Design Chapter ***
// //
@ -30,43 +30,25 @@
`include "wally-config.vh" `include "wally-config.vh"
module zbc #(parameter WIDTH=32) ( module zbc #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, B, // Operands input logic [WIDTH-1:0] A, RevA, B, // Operands
input logic [2:0] Funct3, // Indicates operation to perform input logic [2:0] Funct3, // Indicates operation to perform
output logic [WIDTH-1:0] ZBCResult); // ZBC result output logic [WIDTH-1:0] ZBCResult); // ZBC result
logic [WIDTH-1:0] ClmulResult, RevClmulResult; logic [WIDTH-1:0] ClmulResult, RevClmulResult;
logic [WIDTH-1:0] RevA, RevB; logic [WIDTH-1:0] RevB;
logic [WIDTH-1:0] x,y; logic [WIDTH-1:0] x,y;
logic [1:0] select;
assign select = ~Funct3[1:0];
bitreverse #(WIDTH) brA(.a(A), .b(RevA));
bitreverse #(WIDTH) brB(.a(B), .b(RevB)); bitreverse #(WIDTH) brB(.a(B), .b(RevB));
// zbc input select mux mux3 #(WIDTH) xmux({RevA[WIDTH-2:0], {1'b0}}, RevA, A, select, x);
always_comb begin mux3 #(WIDTH) ymux({{1'b0},RevB[WIDTH-2:0]}, RevB, B, select, y);
casez (Funct3[1:0])
2'b01: begin //clmul
x = A;
y = B;
end
2'b11: begin //clmulh
x = {RevA[WIDTH-2:0], {1'b0}};
y = {{1'b0}, RevB[WIDTH-2:0]};
end
2'b10: begin //clmulr
x = RevA;
y = RevB;
end
default: begin
x = 0;
y = 0;
end
endcase
end
clmul #(WIDTH) clm(.A(x), .B(y), .ClmulResult(ClmulResult)); clmul #(WIDTH) clm(.A(x), .B(y), .ClmulResult(ClmulResult));
bitreverse #(WIDTH) brClmulResult(.a(ClmulResult), .b(RevClmulResult)); bitreverse #(WIDTH) brClmulResult(.a(ClmulResult), .b(RevClmulResult));
assign ZBCResult = (Funct3[1]) ? RevClmulResult : ClmulResult; mux2 #(WIDTH) zbcresultmux(ClmulResult, RevClmulResult, Funct3[1], ZBCResult);
endmodule endmodule

View File

@ -58,9 +58,10 @@ module controller(
output logic BranchE, // Branch instruction output logic BranchE, // Branch instruction
output logic SCE, // Store Conditional instruction output logic SCE, // Store Conditional instruction
output logic BranchSignedE, // Branch comparison operands are signed (if it's a branch) 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 [1: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 output logic [2:0] ZBBSelectE, // ZBB mux select signal in Execute stage
output logic RotateE, // Indicates if rotate instruction in Execute Stage output logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage
// Memory stage control signals // Memory stage control signals
input logic StallM, FlushM, // Stall, flush Memory stage 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 output logic [1:0] MemRWM, // Mem read/write: MemRWM[1] = 1 for read, MemRWM[0] = 1 for write
@ -123,7 +124,7 @@ module controller(
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 [3: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 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 BW64D; // Indicates if it is a W type B instruction in decode stage
@ -256,9 +257,9 @@ module controller(
assign BaseSubArithD = ALUOpD & (subD | sraD | sltD | sltuD); assign BaseSubArithD = ALUOpD & (subD | sraD | sltD | sltuD);
assign ALUControlD = {W64D, SubArithD, ALUOpD}; assign ALUControlD = {W64D, SubArithD, ALUOpD};
// BITMANIP 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, .BRegWriteD, .BW64D, .BALUOpD, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE, .ALUSelectE, .BSelectE, .ZBBSelectE, .BRegWriteE, .BComparatorSignedE, .RotateE); bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUSelectD, .BSelectD, .ZBBSelectD, .BRegWriteD, .BW64D, .BALUOpD, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE, .ALUSelectE, .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])) ;
@ -268,8 +269,8 @@ module controller(
end else begin: bitmanipi end else begin: bitmanipi
assign ALUSelectD = Funct3D; assign ALUSelectD = Funct3D;
assign ALUSelectE = Funct3E; assign ALUSelectE = Funct3E;
assign BSelectE = 4'b0000; assign BSelectE = 2'b00;
assign BSelectD = 4'b0000; assign BSelectD = 2'b00;
assign ZBBSelectE = 3'b000; assign ZBBSelectE = 3'b000;
assign BRegWriteD = 1'b0; assign BRegWriteD = 1'b0;
assign BW64D = 1'b0; assign BW64D = 1'b0;
@ -277,11 +278,10 @@ module controller(
assign BRegWriteE = 1'b0; assign BRegWriteE = 1'b0;
assign BSubArithD = 1'b0; assign BSubArithD = 1'b0;
assign BComparatorSignedE = 1'b0; assign BComparatorSignedE = 1'b0;
assign RotateE = 1'b0; assign BALUControlE = 3'b0;
assign sltD = (Funct3D == 3'b010); assign sltD = (Funct3D == 3'b010);
assign IllegalBitmanipInstrD = 1'b1; assign IllegalBitmanipInstrD = 1'b1;
end end

View File

@ -46,9 +46,9 @@ module datapath (
input logic [2:0] ALUSelectE, // ALU mux select signal input logic [2:0] ALUSelectE, // ALU mux select signal
input logic JumpE, // Is a jump (j) instruction input logic JumpE, // Is a jump (j) instruction
input logic BranchSignedE, // Branch comparison operands are signed (if it's a branch) 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 [1:0] BSelectE, // One hot encoding of ZBA_ZBB_ZBC_ZBS instruction
input logic [2:0] ZBBSelectE, // ZBB mux select signal input logic [2:0] ZBBSelectE, // ZBB mux select signal
input logic RotateE, // Indicates if Rotate instruction in Execute Stage input logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage
output logic [1:0] FlagsE, // Comparison flags ({eq, lt}) output logic [1:0] FlagsE, // Comparison flags ({eq, lt})
output logic [`XLEN-1:0] IEUAdrE, // Address computed by ALU 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 output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU sources before the mux chooses between them and PCE to put in srcA/B
@ -113,7 +113,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, RotateE, ALUResultE, IEUAdrE); alu #(`XLEN) alu(SrcAE, SrcBE, ALUControlE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE, BALUControlE, ALUResultE, IEUAdrE);
mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE);
mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE); mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);

View File

@ -85,9 +85,9 @@ module ieu (
logic SCE; // Store Conditional instruction logic SCE; // Store Conditional instruction
logic FWriteIntM; // FPU writing to integer register file logic FWriteIntM; // FPU writing to integer register file
logic IntDivW; // Integer divide instruction logic IntDivW; // Integer divide instruction
logic [3: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 RotateE; // Indicates if Rotate Instruction in Execute Stage logic [2:0] BALUControlE; // ALU Control signals for B instructions in Execute Stage
// 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
@ -101,7 +101,7 @@ 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, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE,
.Funct3E, .IntDivE, .MDUE, .W64E, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .BSelectE, .ZBBSelectE, .RotateE, .StallM, .FlushM, .MemRWM, .Funct3E, .IntDivE, .MDUE, .W64E, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .StallM, .FlushM, .MemRWM,
.CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM, .RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .FenceM, .StoreStallD); .StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .FenceM, .StoreStallD);
@ -109,7 +109,7 @@ controller c(
datapath dp( datapath dp(
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
.ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE, .ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE,
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .RotateE, .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,
.CSRReadValW, .MDUResultW, .FIntDivResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW); .CSRReadValW, .MDUResultW, .FIntDivResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW);

View File

@ -30,23 +30,22 @@
`include "wally-config.vh" `include "wally-config.vh"
module shifter ( module shifter (
input logic [`XLEN:0] shA, // shift Source input logic [`XLEN-1:0] shA, // shift Source
input logic [`XLEN-1:0] rotA, // rotate 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, // Shift right, rotate signals 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
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 = {shA[31:0], 31'b0};
2'b01: z = {rotA,rotA[31:1]}; 2'b01: z = {rotA,rotA[31:1]};
2'b10: z = {{31{shA[32]}}, shA[31:0]}; 2'b10: z = {{31{Sign}}, shA[31:0]};
2'b11: z = {rotA[30:0],rotA}; 2'b11: z = {rotA[30:0],rotA};
endcase endcase
assign amttrunc = Amt; // shift amount assign amttrunc = Amt; // shift amount
@ -55,7 +54,7 @@ module shifter (
case ({Right, Rotate}) case ({Right, Rotate})
2'b00: z = {shA[63:0],{63'b0}}; 2'b00: z = {shA[63:0],{63'b0}};
2'b01: z = {rotA, rotA[63:1]}; 2'b01: z = {rotA, rotA[63:1]};
2'b10: z = {{63{shA[64]}},shA[63:0]}; 2'b10: z = {{63{Sign}},shA[63:0]};
2'b11: z = {rotA[62:0],rotA[63:0]}; 2'b11: z = {rotA[62:0],rotA[63:0]};
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
@ -63,12 +62,12 @@ module shifter (
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{shA[32]}}, shA[31:0]}; if (Right) z = {{31{Sign}}, shA[31:0]};
else z = {shA[31:0], 31'b0}; else z = {shA[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{shA[64]}},shA[63:0]}; if (Right) z = {{63{Sign}},shA[63:0]};
else z = {shA[63:0],{63'b0}}; else z = {shA[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