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

@ -30,56 +30,64 @@
`include "wally-config.vh"
module alu #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, B, // Operands
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
input logic [1:0] CompFlags, // Comparator flags
input logic Rotate, // Perform Rotate Operation
output logic [WIDTH-1:0] ALUResult, // ALU result
output logic [WIDTH-1:0] Sum); // Sum of operands
input logic [WIDTH-1:0] A, B, // Operands
input logic [2:0] ALUControl, // With Funct3, indicates operation to perform
input logic [2:0] ALUSelect, // ALU mux select signal
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] Funct3, // With ALUControl, indicates operation to perform NOTE: Change signal name to ALUSelect
input logic [1:0] CompFlags, // Comparator flags
input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage
output logic [WIDTH-1:0] Result, // ALU result
output logic [WIDTH-1:0] 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,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] CondMaskB; // Result of B mask 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 LT, LTU; // Less than, Less than unsigned
logic W64; // RV64 W-type instruction
logic SubArith; // Performing subtraction or arithmetic right shift
logic ALUOp; // 0 for address generation addition or 1 for regular ALU ops
logic Asign, Bsign; // Sign bits of A, B
logic [WIDTH:0] shA; // XLEN+1 bit input source to shifter
logic shSignA;
logic [WIDTH-1:0] rotA; // XLEN bit input source to shifter
logic [1:0] shASelect; // select signal for shifter source generation mux
logic Rotate; // Indicates if it is Rotate instruction
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.
assign {W64, SubArith, ALUOp} = ALUControl;
// Extract control signals from bitmanip ALUControl.
assign {Rotate, Mask, PreShift} = BALUControl;
// Pack control signals into shifter select
assign shASelect = {W64,SubArith};
assign PreShiftAmt = Funct3[2:1] & {2{PreShift}};
if (`ZBS_SUPPORTED) begin: zbsdec
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;
// Sign/Zero extend mux
if (WIDTH == 64) begin // rv64 must handle word s/z extensions
always_comb
case (shASelect)
2'b00: shA = {{1'b0}, A};
2'b01: shA = {A[63], A};
2'b10: shA = {{33'b0}, A[31:0]};
2'b11: shA = {{33{A[31]}}, A[31:0]};
endcase
end else assign shA = (SubArith) ? {A[31], A} : {{1'b0},A}; // rv32 does need to handle s/z extensions
if (WIDTH == 64) begin
mux3 #(1) signmux(A[63], A[31], 1'b0, {~SubArith, W64}, shSignA);
mux3 #(64) extendmux({{32{1'b0}}, A[31:0]},{{32{A[31]}}, A[31:0]}, A,{~W64, SubArith}, CondExtA);
end else begin
mux2 #(1) signmux(1'b0, A[31], SubArith, shSignA);
assign CondExtA = A;
end
// shifter rotate source select mux
if (`ZBB_SUPPORTED) begin
@ -88,22 +96,17 @@ module alu #(parameter WIDTH=32) (
end else assign rotA = A;
if (`ZBA_SUPPORTED) begin: zbamuxes
// Pre-Shift Mux
always_comb
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
// Pre-Shift
assign CondShiftA = CondExtA << (PreShiftAmt);
end else assign CondShiftA = A;
// 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};
// 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.
// 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'b010: FullResult = SLT; // slt
3'b011: FullResult = SLTU; // sltu
3'b100: FullResult = A ^ CondInvB; // xor, xnor, binv
3'b110: FullResult = A | CondInvB; // or, orn, bset
3'b111: FullResult = A & CondInvB; // and, bclr
3'b100: FullResult = A ^ CondMaskInvB; // xor, xnor, binv
3'b110: FullResult = A | CondMaskInvB; // or, orn, bset
3'b111: FullResult = A & CondMaskInvB; // and, bclr
3'b101: FullResult = {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}};// bext
endcase
end
@ -146,33 +149,33 @@ module alu #(parameter WIDTH=32) (
3'b110: FullResult = A | B; // or
3'b111: FullResult = A & B; // and
endcase
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;
if (`ZBC_SUPPORTED | `ZBB_SUPPORTED) begin: bitreverse
bitreverse #(WIDTH) brA(.a(A), .b(RevA));
end
//NOTE: This looks good and can be merged.
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;
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;
// 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
if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : zbdecoder
always_comb
case (BSelect)
//ZBA_ZBB_ZBC_ZBS
4'b0001: ALUResult = FullResult;
4'b0010: ALUResult = ZBCResult;
4'b1000: ALUResult = FullResult; // NOTE: We don't use ALUResult because ZBA instructions don't sign extend the MSB of the right-hand word.
4'b0100: ALUResult = ZBBResult;
default: ALUResult = CondExtFullResult;
// 00: ALU, 01: ZBA/ZBS, 10: ZBB, 11: ZBC
2'b00: Result = ALUResult;
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.
2'b10: Result = ZBBResult;
2'b11: Result = ZBCResult;
endcase
end else assign ALUResult = CondExtFullResult;
end else assign Result = ALUResult;
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>
// 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 ***
//
@ -37,7 +37,6 @@ module bitreverse #(parameter WIDTH=32) (
for (i=0; i<WIDTH;i++) begin:loop
assign b[WIDTH-i-1] = a[i];
end
endmodule

View File

@ -1,11 +1,11 @@
///////////////////////////////////////////
// controller.sv
// bmuctrl.sv
//
// Written: Kevin Kim <kekim@hmc.edu>
// 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)
//
@ -29,14 +29,13 @@
`include "wally-config.vh"
// NOTE: DO we want to make this XLEN parameterized?
module bmuctrl(
input logic clk, reset,
// Decode stage control signals
input logic StallD, FlushD, // Stall, flush 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 [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 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
@ -46,11 +45,11 @@ module bmuctrl(
// 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 [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 BRegWriteE, // Indicates if it is a R type B instruction in Execute
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
@ -59,12 +58,14 @@ module bmuctrl(
logic [4:0] Rs2D; // Rs2 source register 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 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
logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals
// Extract fields
assign OpD = InstrD[6:0];
assign Funct3D = InstrD[14:12];
@ -74,98 +75,99 @@ module bmuctrl(
// Main Instruction Decoder
always_comb
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
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)
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
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_0_1; // illegal instruction
17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_0001_000_1_0_1_1_0_0; // bexti
BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_1; // illegal instruction
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)
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
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_0_1; // illegal instruction
17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_000_1_0_1_0_0_0; // binvi
BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_1; // illegal instruction
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)
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
BMUControlsD = `BMUCTRLW'b000_0000_000_0_0_0_0_0_1; // illegal instruction
17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_000_1_0_1_0_0_0; // bseti
BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_1; // illegal instruction
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)
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
BMUControlsD = `BMUCTRLW'b000_0000_000_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_101: BMUControlsD = `BMUCTRLW'b101_0001_000_1_0_1_1_0_0; // bext
17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_0001_000_1_0_1_0_0_0; // binv
17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_0001_000_1_0_1_0_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
BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_1; // illegal instruction
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_01_000_1_0_1_1_0_1_0_0; // bext
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_01_000_1_0_1_0_0_1_0_0; // bset
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
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
17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_1000_000_1_0_1_0_0_0; // sh1add
17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_1000_000_1_0_1_0_0_0; // sh2add
17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_1000_000_1_0_1_0_0_0; // sh3add
17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1_0_0_0; // sh1add.uw
17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1_0_0_0; // sh2add.uw
17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1_0_0_0; // sh3add.uw
17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_1000_000_1_1_1_0_0_0; // add.uw
17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_1000_000_1_1_1_0_0_0; // slli.uw
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_01_000_1_0_1_0_0_0_1_0; // sh2add
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_01_000_1_1_1_0_0_0_1_0; // sh1add.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_01_000_1_1_1_0_0_0_1_0; // sh3add.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_01_000_1_1_1_0_0_0_0_0; // slli.uw
// ZBB
17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1_0_1_0; // rol
17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_0100_111_1_1_1_0_1_0; // rolw
17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1_0_1_0; // ror
17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111_1_1_1_0_1_0; // rorw
17'b0010011_0110000_101: BMUControlsD = `BMUCTRLW'b001_0100_111_1_0_1_0_1_0; // rori (rv32)
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_00_111_1_1_1_0_1_0_0_0; // rolw
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_00_111_1_1_1_0_1_0_0_0; // rorw
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)
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
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)
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
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])
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
BMUControlsD = `BMUCTRLW'b000_0100_000_1_0_1_0_0_0; // count instruction
17'b0011011_0110000_001: BMUControlsD = `BMUCTRLW'b000_0100_000_1_1_1_0_0_0; // count word instruction
BMUControlsD = `BMUCTRLW'b000_10_000_1_0_1_0_0_0_0_0; // count 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)
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
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)
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
BMUControlsD = `BMUCTRLW'b000_0000_000_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_110: BMUControlsD = `BMUCTRLW'b110_0100_111_1_0_1_1_0_0; // orn
17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_0100_111_1_0_1_1_0_0; // xnor
BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_1; // illegal instruction
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_01_111_1_0_1_1_0_0_0_0; // orn
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)
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
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)
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
BMUControlsD = `BMUCTRLW'b000_0000_000_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'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_0100_101_1_0_1_0_0_0; // max
17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_0100_101_1_0_1_0_0_0; // maxu
17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_0100_110_1_0_1_0_0_0; // min
17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_0100_110_1_0_1_0_0_0; // minu
default: BMUControlsD = {Funct3D, {12'b0}, {1'b1}}; // not B instruction or shift
BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_1; // illegal instruction
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_10_100_1_0_1_0_0_0_0_0; // max
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_10_011_1_0_1_0_0_0_0_0; // min
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
endcase
// 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
assign BComparatorSignedD = (Funct3D[2]^Funct3D[0]) & ~OpD[6];
// 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

View File

@ -1,11 +1,11 @@
///////////////////////////////////////////
// clmul.sv
// byte.sv
//
// Written: Kevin Kim <kekim@hmc.edu>
// 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 ***
//

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>
// Created: 1 February 2023
// Modified:
//
// Purpose: Carry-Less multiplication top-level unit
// Purpose: Carry-Less multiplication unit
//
// Documentation: RISC-V System on Chip Design Chapter ***
//

View File

@ -31,7 +31,8 @@
`include "wally-config.vh"
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
output logic [WIDTH-1:0] CntResult // count result
);
@ -40,52 +41,25 @@ module cnt #(parameter WIDTH = 32) (
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;
//in both rv64, rv32
bitreverse #(WIDTH) brtz(.a(A), .b(revA));
//only in rv64
if (WIDTH==64) begin
//NOTE: signal widths can be decreased
always_comb begin
//clz input select mux
case({B[4:0],W64})
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
case ({B[4:0],W64})
6'b00010_0: popcntA = A;
6'b00010_1: popcntA = {{32{1'b0}}, A[31:0]};
default: popcntA = A;
endcase
end
//clz input select mux
mux4 #(WIDTH) lzcmux64(A, {A[31:0],{32{1'b1}}}, RevA, {RevA[63:32],{32{1'b1}}}, {B[0],W64}, lzcA);
//cpop select mux
mux2 #(WIDTH) popcntmux64(A, {{32{1'b0}}, A[31:0]}, W64, popcntA);
end
//rv32
else begin
//rv32
assign popcntA = A;
always_comb begin
//clz input slect mux
case(B[4:0])
5'b00000: lzcA = A;
5'b00001: lzcA = revA;
default: lzcA = A;
endcase
end
mux2 #(WIDTH) lzcmux32(A, RevA, B[0], lzcA);
end
lzc #(WIDTH) lzc(.num(lzcA), .ZeroCnt(czResult[$clog2(WIDTH):0]));
popcnt #(WIDTH) popcntw(.num(popcntA), .PopCnt(cpopResult[$clog2(WIDTH):0]));
// zero extend these results to fit into width *** There may be a more elegant way to do this
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 CntResult = (B[1]) ? cpopResult : czResult;
mux2 #(WIDTH) cntresultmux(czResult, cpopResult, B[1], CntResult);
endmodule

View File

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

View File

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

View File

@ -4,9 +4,9 @@
//
// Written: Kevin Kim <kekim@hmc.edu> and Kip Macsai-Goren <kmacsaigoren@hmc.edu>
// 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 ***
//
@ -31,57 +31,25 @@
`include "wally-config.vh"
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 W64, // Indicates word operation
input logic lt, // lt flag
input logic [2:0] ZBBSelect, // Indicates word operation
output logic [WIDTH-1:0] ZBBResult); // ZBB result
// count result
logic [WIDTH-1:0] CntResult;
// min,max result
logic [WIDTH-1:0] MaxResult;
logic [WIDTH-1:0] MinResult;
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
// 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));
cnt #(WIDTH) cnt(.A(A), .RevA(RevA), .B(B[4:0]), .W64(W64), .CntResult(CntResult));
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 MinResult = (lt) ? A : B;
//can replace with structural mux by looking at bit 4 in rs2 field
always_comb begin
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
// ZBB Result select mux
mux5 #(WIDTH) zbbresultmux(CntResult, ExtResult, ByteResult, MinResult, MaxResult, ZBBSelect, ZBBResult);
endmodule

View File

@ -3,9 +3,9 @@
//
// Written: Kevin Kim <kekim@hmc.edu> and Kip Macsai-Goren <kmacsaigoren@hmc.edu>
// 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 ***
//
@ -30,43 +30,25 @@
`include "wally-config.vh"
module zbc #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, B, // Operands
input logic [2:0] Funct3, // Indicates operation to perform
output logic [WIDTH-1:0] ZBCResult); // ZBC result
input logic [WIDTH-1:0] A, RevA, B, // Operands
input logic [2:0] Funct3, // Indicates operation to perform
output logic [WIDTH-1:0] ZBCResult); // ZBC result
logic [WIDTH-1:0] ClmulResult, RevClmulResult;
logic [WIDTH-1:0] RevA, RevB;
logic [WIDTH-1:0] RevB;
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));
// zbc input select mux
always_comb begin
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
mux3 #(WIDTH) xmux({RevA[WIDTH-2:0], {1'b0}}, RevA, A, select, x);
mux3 #(WIDTH) ymux({{1'b0},RevB[WIDTH-2:0]}, RevB, B, select, y);
clmul #(WIDTH) clm(.A(x), .B(y), .ClmulResult(ClmulResult));
bitreverse #(WIDTH) brClmulResult(.a(ClmulResult), .b(RevClmulResult));
assign ZBCResult = (Funct3[1]) ? RevClmulResult : ClmulResult;
mux2 #(WIDTH) zbcresultmux(ClmulResult, RevClmulResult, Funct3[1], ZBCResult);
endmodule

View File

@ -58,9 +58,10 @@ module controller(
output logic BranchE, // Branch instruction
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 [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 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
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
@ -123,7 +124,7 @@ module controller(
logic FenceD, FenceE; // Fence instruction
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 [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 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
@ -256,9 +257,9 @@ module controller(
assign BaseSubArithD = ALUOpD & (subD | sraD | sltD | sltuD);
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
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
// 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])) ;
@ -268,8 +269,8 @@ module controller(
end else begin: bitmanipi
assign ALUSelectD = Funct3D;
assign ALUSelectE = Funct3E;
assign BSelectE = 4'b0000;
assign BSelectD = 4'b0000;
assign BSelectE = 2'b00;
assign BSelectD = 2'b00;
assign ZBBSelectE = 3'b000;
assign BRegWriteD = 1'b0;
assign BW64D = 1'b0;
@ -277,11 +278,10 @@ module controller(
assign BRegWriteE = 1'b0;
assign BSubArithD = 1'b0;
assign BComparatorSignedE = 1'b0;
assign RotateE = 1'b0;
assign BALUControlE = 3'b0;
assign sltD = (Funct3D == 3'b010);
assign IllegalBitmanipInstrD = 1'b1;
end

View File

@ -46,9 +46,9 @@ module datapath (
input logic [2:0] ALUSelectE, // ALU mux select signal
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 [1:0] BSelectE, // One hot encoding of ZBA_ZBB_ZBC_ZBS instruction
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 [`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
@ -60,7 +60,7 @@ module datapath (
output logic [`XLEN-1:0] WriteDataM, // Write data in Memory stage
// Writeback stage signals
input logic StallW, FlushW, // Stall, flush Writeback stage
input logic RegWriteW, IntDivW, // Write register file, integer divide instruction
input logic RegWriteW, IntDivW, // Write register file, integer divide instruction
input logic SquashSCW, // Squash a store conditional when a conflict arose
input logic [2:0] ResultSrcW, // Select source of result to write back to register file
input logic [`XLEN-1:0] FCvtIntResW, // FPU convert fp to integer result
@ -113,7 +113,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, 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) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);

View File

@ -72,7 +72,7 @@ module ieu (
output logic MDUStallD, CSRRdStallD, StoreStallD,
output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction
output logic CSRWriteFenceM, // CSR write or fence instruction needs to flush subsequent instructions
output logic FenceM
output logic FenceM
);
logic [2:0] ImmSrcD; // Select type of immediate extension
@ -85,9 +85,9 @@ module ieu (
logic SCE; // Store Conditional instruction
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 [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 RotateE; // Indicates if Rotate Instruction in Execute Stage
logic [2:0] BALUControlE; // ALU Control signals for B instructions in Execute Stage
// Forwarding signals
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E; // Source and destination registers
@ -101,7 +101,7 @@ controller c(
.clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD,
.IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE,
.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,
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .FenceM, .StoreStallD);
@ -109,7 +109,7 @@ controller c(
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, .ZBBSelectE, .RotateE,
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE,
.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);

View File

@ -30,23 +30,22 @@
`include "wally-config.vh"
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 [`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
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
if (`ZBB_SUPPORTED) begin: rotfunnel
if (`XLEN==32) begin // rv32 with rotates
always_comb // funnel mux
case({Right, Rotate})
2'b00: z = {shA[31:0], 31'b0};
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};
endcase
assign amttrunc = Amt; // shift amount
@ -55,7 +54,7 @@ module shifter (
case ({Right, Rotate})
2'b00: z = {shA[63:0],{63'b0}};
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]};
endcase
assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32- or 64-bit shift
@ -63,12 +62,12 @@ module shifter (
end else begin: norotfunnel
if (`XLEN==32) begin:shifter // RV32
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};
assign amttrunc = Amt; // shift amount
end else begin:shifter // RV64
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}};
assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32- or 64-bit shift
end