forked from Github_Repos/cvw
Merge branch 'bit-manip' of github.com:kipmacsaigoren/cvw into bit-manip
This commit is contained in:
commit
47bbe72d1f
111
src/ieu/alu.sv
111
src/ieu/alu.sv
@ -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
|
32
src/ieu/bmu/bitfieldedit.py
Normal file
32
src/ieu/bmu/bitfieldedit.py
Normal 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()
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
@ -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 ***
|
||||
//
|
||||
|
@ -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 ***
|
||||
//
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user