IEU cleanup

IEU cleanup
This commit is contained in:
sarah-harris 2023-01-17 06:02:26 -08:00
parent 552aafa15b
commit 3124ebc3e1
9 changed files with 280 additions and 272 deletions

View File

@ -30,38 +30,40 @@
`include "wally-config.vh" `include "wally-config.vh"
module alu #(parameter WIDTH=32) ( module alu #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, B, input logic [WIDTH-1:0] A, B, // Operands
input logic [2:0] ALUControl, input logic [2:0] ALUControl, // With Funct3, indicates operation to perform
input logic [2:0] Funct3, input logic [2:0] Funct3, // With ALUControl, indicates operation to perform
output logic [WIDTH-1:0] Result, output logic [WIDTH-1:0] Result, // ALU result
output logic [WIDTH-1:0] Sum); output logic [WIDTH-1:0] Sum); // Sum of operands
logic [WIDTH-1:0] CondInvB, Shift, SLT, SLTU, FullResult; // CondInvB = ~B when subtracting, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction.
logic Carry, Neg; // FullResult = ALU result before adjusting for a RV64 w-suffix instruction.
logic LT, LTU; logic [WIDTH-1:0] CondInvB, Shift, SLT, SLTU, FullResult; // Intermediate results
logic W64, SubArith, ALUOp; logic Carry, Neg; // Flags: carry out, negative
logic Asign, Bsign; 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
// Extract control signals // Extract control signals from ALUControl.
// W64 indicates RV64 W-suffix instructions acting on lower 32-bit word
// SubArith indicates subtraction or arithmetic right shift
// ALUOp = 0 for address generation addition or 1 for regular ALU
assign {W64, SubArith, ALUOp} = ALUControl; assign {W64, SubArith, ALUOp} = ALUControl;
// addition // Addition
assign CondInvB = SubArith ? ~B : B; assign CondInvB = SubArith ? ~B : B;
assign {Carry, Sum} = A + CondInvB + {{(WIDTH-1){1'b0}}, SubArith}; assign {Carry, Sum} = A + CondInvB + {{(WIDTH-1){1'b0}}, SubArith};
// Shifts // Shifts
shifter sh(.A, .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .Arith(SubArith), .W64, .Y(Shift)); shifter sh(.A, .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .Arith(SubArith), .W64, .Y(Shift));
// condition code flags based on subtract 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
// and the result has the opposite sign of A // and the result has the opposite sign of A.
// LT is simplified from Overflow = Asign & Bsign & Asign & Neg; LT = Neg ^ Overflow
assign Neg = Sum[WIDTH-1]; assign Neg = Sum[WIDTH-1];
assign Asign = A[WIDTH-1]; assign Asign = A[WIDTH-1];
assign Bsign = B[WIDTH-1]; assign Bsign = B[WIDTH-1];
assign LT = Asign & ~Bsign | Asign & Neg | ~Bsign & Neg; // simplified from Overflow = Asign & Bsign & Asign & Neg; LT = Neg ^ Overflow assign LT = Asign & ~Bsign | Asign & Neg | ~Bsign & Neg;
assign LTU = ~Carry; assign LTU = ~Carry;
// SLT // SLT
@ -70,7 +72,7 @@ module alu #(parameter WIDTH=32) (
// Select appropriate ALU Result // Select appropriate ALU Result
always_comb always_comb
if (~ALUOp) FullResult = Sum; // Always add for ALUOp = 0 if (~ALUOp) FullResult = Sum; // Always add for ALUOp = 0 (address generation)
else casez (Funct3) // Otherwise check Funct3 else casez (Funct3) // Otherwise check Funct3
3'b000: FullResult = Sum; // add or sub 3'b000: FullResult = Sum; // add or sub
3'b?01: FullResult = Shift; // sll, sra, or srl 3'b?01: FullResult = Shift; // sll, sra, or srl
@ -81,7 +83,7 @@ module alu #(parameter WIDTH=32) (
3'b111: FullResult = A & B; // and 3'b111: FullResult = A & B; // and
endcase endcase
// support W-type RV64I ADDW/SUBW/ADDIW/Shifts that sign-extend 32-bit result to 64 bits // 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 Result = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult; if (WIDTH == 64) assign Result = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult;
else assign Result = FullResult; else assign Result = FullResult;
endmodule endmodule

View File

@ -1,7 +1,8 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// comparator.sv // comparator.sv
// //
// Written: David_Harris@hmc.edu 8 December 2021 // Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu
// Created: 8 December 2021
// Modified: // Modified:
// //
// Purpose: Branch comparison // Purpose: Branch comparison
@ -30,26 +31,26 @@
// This comparator is best // This comparator is best
module comparator_dc_flip #(parameter WIDTH=64) ( module comparator_dc_flip #(parameter WIDTH=64) (
input logic [WIDTH-1:0] a, b, input logic [WIDTH-1:0] a, b, // Operands
input logic sgnd, input logic sgnd, // Signed operands
output logic [1:0] flags); output logic [1:0] flags); // Output flags: {eq, lt}
logic eq, lt, ltu; logic eq, lt; // Flags: equal (eq), less than (lt)
logic [WIDTH-1:0] af, bf; logic [WIDTH-1:0] af, bf; // Operands with msb flipped (inverted) when signed
// For signed numbers, flip most significant bit // For signed numbers, flip most significant bit
assign af = {a[WIDTH-1] ^ sgnd, a[WIDTH-2:0]}; assign af = {a[WIDTH-1] ^ sgnd, a[WIDTH-2:0]};
assign bf = {b[WIDTH-1] ^ sgnd, b[WIDTH-2:0]}; assign bf = {b[WIDTH-1] ^ sgnd, b[WIDTH-2:0]};
// behavioral description gives best results // Behavioral description gives best results
assign eq = (a == b); assign eq = (a == b); // eq = 1 when operands are equal, 0 otherwise
assign lt = (af < bf); assign lt = (af < bf); // lt = 1 when a less than b (taking signed operands into account)
assign flags = {eq, lt}; assign flags = {eq, lt};
endmodule endmodule
/* /*
Other comparators evaluated Other comparators evaluated:
module donedet #(parameter WIDTH=64) ( module donedet #(parameter WIDTH=64) (
input logic [WIDTH-1:0] a, b, input logic [WIDTH-1:0] a, b,

View File

@ -1,7 +1,8 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// controller.sv // controller.sv
// //
// Written: David_Harris@hmc.edu 9 January 2021 // Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu
// Created: 9 January 2021
// Modified: // Modified:
// //
// Purpose: Top level controller module // Purpose: Top level controller module
@ -32,84 +33,84 @@
module controller( module controller(
input logic clk, reset, input logic clk, reset,
// Decode stage control signals // Decode stage control signals
input logic StallD, FlushD, input logic StallD, FlushD, // Stall, flush Decode stage
input logic [31:0] InstrD, input logic [31:0] InstrD, // Instruction in Decode stage
output logic [2:0] ImmSrcD, output logic [2:0] ImmSrcD, // Type of immediate extension
input logic IllegalIEUInstrFaultD, input logic IllegalIEUInstrFaultD, // Illegal instruction ***
output logic IllegalBaseInstrFaultD, output logic IllegalBaseInstrFaultD, // ***
// Execute stage control signals // Execute stage control signals
input logic StallE, FlushE, input logic StallE, FlushE, // Stall, flush Execute stage
input logic [1:0] FlagsE, input logic [1:0] FlagsE, // Comparison flags ({eq, lt})
input logic FWriteIntE, input logic FWriteIntE, // Write integer register, coming from FPU controller
output logic PCSrcE, // for datapath and Hazard Unit output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit)
output logic [2:0] ALUControlE, output logic [2:0] ALUControlE, // ALU operation to perform
output logic ALUSrcAE, ALUSrcBE, output logic ALUSrcAE, ALUSrcBE, // ALU operands
output logic ALUResultSrcE, output logic ALUResultSrcE, // Selects result to pass on to Memory stage
output logic MemReadE, CSRReadE, // for Hazard Unit output logic MemReadE, CSRReadE, // Instruction reads memory, reads a CSR (needed for Hazard unit)
output logic [2:0] Funct3E, output logic [2:0] Funct3E, // Instruction's funct3 field
output logic IntDivE, MDUE, W64E, output logic IntDivE, MDUE, W64E, // Integer divide, MDU (multiply/divide) operation***, or RV64 W-type operation
output logic JumpE, output logic JumpE, // Is a jump (j) instruction
output logic SCE, output logic SCE, // Is a Store Conditional instruction ***
output logic BranchSignedE, output logic BranchSignedE, // Branch comparison operands are signed (if it's a branch)
// Memory stage control signals // Memory stage control signals
input logic StallM, FlushM, input logic StallM, FlushM, // Stall, flush Memory stage
output logic [1:0] MemRWM, output logic [1:0] MemRWM, // Mem read/write: MemRWM[1] = 1 for read, MemRWM[0] = 1 for write
output logic CSRReadM, CSRWriteM, PrivilegedM, output logic CSRReadM, CSRWriteM, PrivilegedM, // CSR read, write, or privileged instruction
output logic [1:0] AtomicM, output logic [1:0] AtomicM, // Atomic (AMO) instruction
output logic [2:0] Funct3M, output logic [2:0] Funct3M, // Instruction's funct3 field
output logic RegWriteM, // for Hazard Unit output logic RegWriteM, // Instruction writes a register (needed for Hazard unit)
output logic InvalidateICacheM, FlushDCacheM, output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$
output logic InstrValidM, output logic InstrValidM, // Instruction is valid
output logic FWriteIntM, output logic FWriteIntM, // FPU controller writes integer register file
// Writeback stage control signals // Writeback stage control signals
input logic StallW, FlushW, input logic StallW, FlushW, // Stall, flush Writeback stage
output logic RegWriteW, IntDivW, // for datapath and Hazard Unit output logic RegWriteW, IntDivW, // Instruction writes a register, is an integer divide
output logic [2:0] ResultSrcW, output logic [2:0] ResultSrcW, // Select source of result to write back to register file
// Stall during CSRs // Stall during CSRs
//output logic CSRWriteFencePendingDEM, //output logic CSRWriteFencePendingDEM, // *** delete line?
output logic CSRWriteFenceM, output logic CSRWriteFenceM, // ***
output logic StoreStallD output logic StoreStallD // Store (memory write) causes stall
); );
logic [6:0] OpD; logic [6:0] OpD; // Opcode in Decode stage
logic [2:0] Funct3D; logic [2:0] Funct3D; // Funct3 field in Decode stage
logic [6:0] Funct7D; logic [6:0] Funct7D; // Funct7 field in Decode stage
logic [4:0] Rs1D; logic [4:0] Rs1D; // Rs1 source register in Decode stage
`define CTRLW 23 `define CTRLW 23
// pipelined control signals // pipelined control signals
logic RegWriteD, RegWriteE; logic RegWriteD, RegWriteE; // RegWrite (register will be written)
logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; // Select which result to write back to register file
logic [1:0] MemRWD, MemRWE; logic [1:0] MemRWD, MemRWE; // Store (write to memory)
logic JumpD; logic JumpD; // Jump instruction
logic BranchD, BranchE; logic BranchD, BranchE; // Branch instruction
logic ALUOpD; logic ALUOpD; // 0 for address generation, 1 for all other operations (must use Funct3)
logic [2:0] ALUControlD; logic [2:0] ALUControlD; // Determines ALU operation
logic ALUSrcAD, ALUSrcBD; logic ALUSrcAD, ALUSrcBD; // ALU inputs
logic ALUResultSrcD, W64D, MDUD; logic ALUResultSrcD, W64D, MDUD; // ALU result, is RV64 W-type, is multiply/divide instruction***
logic CSRZeroSrcD; logic CSRZeroSrcD; // ***
logic CSRReadD; logic CSRReadD; // CSR read instruction
logic [1:0] AtomicD; logic [1:0] AtomicD; // ***Atomic (AMO) instruction
logic FenceXD; logic FenceXD; // ***Fence instruction
logic InvalidateICacheD, FlushDCacheD; logic InvalidateICacheD, FlushDCacheD;// Invalidate I$, flush D$
logic CSRWriteD, CSRWriteE; logic CSRWriteD, CSRWriteE; // CSR write
logic InstrValidD, InstrValidE; logic InstrValidD, InstrValidE; // Instruction is valid
logic PrivilegedD, PrivilegedE; logic PrivilegedD, PrivilegedE; // Privileged instruction
logic InvalidateICacheE, FlushDCacheE; logic InvalidateICacheE, FlushDCacheE;// Invalidate I$, flush D$
logic [`CTRLW-1:0] ControlsD; logic [`CTRLW-1:0] ControlsD; // Main Instruction Decoder control signals
logic SubArithD; logic SubArithD; // TRUE for R-type subtracts and sra, slt, sltu
logic subD, sraD, sltD, sltuD; logic subD, sraD, sltD, sltuD; // Indicates if is one of these instructions
logic BranchTakenE; logic BranchTakenE; // Branch is taken
logic eqE, ltE; logic eqE, ltE; // Comparator outputs
logic unused; logic unused;
logic BranchFlagE; logic BranchFlagE; // Branch flag to use (chosen between eq or lt)
logic IEURegWriteE; logic IEURegWriteE; // Register write
logic IllegalERegAdrD; logic IllegalERegAdrD; // ***
logic [1:0] AtomicE; logic [1:0] AtomicE; // *** Atomic instruction
logic FenceD, FenceE, FenceM; logic FenceD, FenceE, FenceM; // Fence instruction
logic SFenceVmaD; logic SFenceVmaD; // *** Fence virtual memory address ***?
logic IntDivM; logic IntDivM; // Integer divide instruction
// Extract fields // Extract fields
@ -122,7 +123,7 @@ module controller(
always_comb always_comb
case(OpD) case(OpD)
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MDU_Atomic_Illegal // RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MDU_Atomic_Illegal
7'b0000000: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // illegal instruction 7'b0000000: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Illegal instruction
7'b0000011: ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // lw 7'b0000011: ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // lw
7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // flw - only legal if FP supported 7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // flw - only legal if FP supported
7'b0001111: if (`ZIFENCEI_SUPPORTED) 7'b0001111: if (`ZIFENCEI_SUPPORTED)
@ -134,7 +135,7 @@ module controller(
7'b0011011: if (`XLEN == 64) 7'b0011011: if (`XLEN == 64)
ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_1_0_0_0_0_00_0; // IW-type ALU for RV64i ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_1_0_0_0_0_00_0; // IW-type ALU for RV64i
else else
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
7'b0100011: ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // sw 7'b0100011: ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // sw
7'b0100111: ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // fsw - only legal if FP supported 7'b0100111: ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // fsw - only legal if FP supported
7'b0101111: if (`A_SUPPORTED) begin 7'b0101111: if (`A_SUPPORTED) begin
@ -143,22 +144,22 @@ module controller(
else if (InstrD[31:27] == 5'b00011) else if (InstrD[31:27] == 5'b00011)
ControlsD = `CTRLW'b1_101_01_01_100_0_0_0_0_0_0_0_0_0_01_0; // sc ControlsD = `CTRLW'b1_101_01_01_100_0_0_0_0_0_0_0_0_0_01_0; // sc
else else
ControlsD = `CTRLW'b1_101_01_11_001_0_0_0_0_0_0_0_0_0_10_0;; // amo ControlsD = `CTRLW'b1_101_01_11_001_0_0_0_0_0_0_0_0_0_10_0; // amo
end else end else
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
7'b0110011: if (Funct7D == 7'b0000000 | Funct7D == 7'b0100000) 7'b0110011: if (Funct7D == 7'b0000000 | Funct7D == 7'b0100000)
ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_0_0_0_0_0_00_0; // R-type ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_0_0_0_0_0_00_0; // R-type
else if (Funct7D == 7'b0000001 & `M_SUPPORTED) else if (Funct7D == 7'b0000001 & `M_SUPPORTED)
ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_0_0_0_0_1_00_0; // Multiply/Divide ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_0_0_0_0_1_00_0; // Multiply/divide
else else
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_0_0_1_0_0_0_0_0_00_0; // lui 7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_0_0_1_0_0_0_0_0_00_0; // lui
7'b0111011: if ((Funct7D == 7'b0000000 | Funct7D == 7'b0100000) & `XLEN == 64) 7'b0111011: if ((Funct7D == 7'b0000000 | Funct7D == 7'b0100000) & `XLEN == 64)
ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_1_0_0_0_0_00_0; // R-type W instructions for RV64i ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_1_0_0_0_0_00_0; // R-type W instructions for RV64i
else if (Funct7D == 7'b0000001 & `M_SUPPORTED & `XLEN == 64) else if (Funct7D == 7'b0000001 & `M_SUPPORTED & `XLEN == 64)
ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_1_0_0_0_1_00_0; // W-type Multiply/Divide ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_1_0_0_0_1_00_0; // W-type Multiply/Divide
else else
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction
7'b1100011: ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0; // branches 7'b1100011: ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0; // branches
7'b1100111: ControlsD = `CTRLW'b1_000_01_00_000_0_0_1_1_0_0_0_0_0_00_0; // jalr 7'b1100111: ControlsD = `CTRLW'b1_000_01_00_000_0_0_1_1_0_0_0_0_0_00_0; // jalr
7'b1101111: ControlsD = `CTRLW'b1_011_11_00_000_0_0_1_1_0_0_0_0_0_00_0; // jal 7'b1101111: ControlsD = `CTRLW'b1_011_11_00_000_0_0_1_1_0_0_0_0_0_00_0; // jal
@ -172,8 +173,8 @@ module controller(
default: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction default: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction
endcase endcase
// unswizzle control bits // Unswizzle control bits
// squash control signals if coming from an illegal compressed instruction // Squash control signals if coming from an illegal compressed instruction
// On RV32E, can't write to upper 16 registers. Checking reads to upper 16 is more costly so disregard them. // On RV32E, can't write to upper 16 registers. Checking reads to upper 16 is more costly so disregard them.
assign IllegalERegAdrD = `E_SUPPORTED & `ZICSR_SUPPORTED & ControlsD[`CTRLW-1] & InstrD[11]; assign IllegalERegAdrD = `E_SUPPORTED & `ZICSR_SUPPORTED & ControlsD[`CTRLW-1] & InstrD[11];
assign IllegalBaseInstrFaultD = ControlsD[0] | IllegalERegAdrD; assign IllegalBaseInstrFaultD = ControlsD[0] | IllegalERegAdrD;
@ -197,7 +198,7 @@ module controller(
// Fences // Fences
// Ordinary fence is presently a nop // Ordinary fence is presently a nop
// FENCE.I flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented // fence.i flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented
if (`ZIFENCEI_SUPPORTED & `ICACHE) begin:fencei if (`ZIFENCEI_SUPPORTED & `ICACHE) begin:fencei
logic FenceID; logic FenceID;
assign FenceID = FenceXD & (Funct3D == 3'b001); // is it a FENCE.I instruction? assign FenceID = FenceXD & (Funct3D == 3'b001); // is it a FENCE.I instruction?

View File

@ -1,7 +1,8 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// datapath.sv // datapath.sv
// //
// Written: sarahleilani@gmail.com and David_Harris@hmc.edu 9 January 2021 // Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu
// Created: 9 January 2021
// Modified: // Modified:
// //
// Purpose: Wally Integer Datapath // Purpose: Wally Integer Datapath
@ -31,59 +32,59 @@
module datapath ( module datapath (
input logic clk, reset, input logic clk, reset,
// Decode stage signals // Decode stage signals
input logic [2:0] ImmSrcD, input logic [2:0] ImmSrcD, // Selects type of immediate extension
input logic [31:0] InstrD, input logic [31:0] InstrD, // Instruction in Decode stage
input logic [2:0] Funct3E, input logic [2:0] Funct3E, // Funct3 field of instruction in Execute stage
// Execute stage signals // Execute stage signals
input logic StallE, FlushE, input logic StallE, FlushE, // Stall, flush Execute stage
input logic [1:0] ForwardAE, ForwardBE, input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages
input logic [2:0] ALUControlE, input logic [2:0] ALUControlE, // Indicate operation ALU performs
input logic ALUSrcAE, ALUSrcBE, input logic ALUSrcAE, ALUSrcBE, // ALU operands
input logic ALUResultSrcE, input logic ALUResultSrcE, // Selects result to pass on to Memory stage
input logic JumpE, input logic JumpE, // Is a jump (j) instruction
input logic BranchSignedE, input logic BranchSignedE, // Branch comparison operands are signed (if it's a branch)
input logic [`XLEN-1:0] PCE, input logic [`XLEN-1:0] PCE, // PC in Execute stage
input logic [`XLEN-1:0] PCLinkE, input logic [`XLEN-1:0] PCLinkE, // PC + 4 (of instruction in Execute stage)
output logic [1:0] FlagsE, output logic [1:0] FlagsE, // Comparison flags ({eq, lt})
output logic [`XLEN-1:0] IEUAdrE, output logic [`XLEN-1:0] IEUAdrE, // Address computed by ALU
output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing 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
// Memory stage signals // Memory stage signals
input logic StallM, FlushM, input logic StallM, FlushM, // Stall, flush Memory stage
input logic FWriteIntM, FCvtIntW, input logic FWriteIntM, FCvtIntW, // FPU writes register file, FPU converts float to int ***
input logic [`XLEN-1:0] FIntResM, input logic [`XLEN-1:0] FIntResM, // FPU integer result ***
output logic [`XLEN-1:0] SrcAM, output logic [`XLEN-1:0] SrcAM, // ALU's Source A in Memory stage *** say why needed?***
output logic [`XLEN-1:0] WriteDataM, output logic [`XLEN-1:0] WriteDataM, // Write data in Memory stage
// Writeback stage signals // Writeback stage signals
input logic StallW, FlushW, input logic StallW, FlushW, // Stall, flush Writeback stage
(* mark_debug = "true" *) input logic RegWriteW, IntDivW, (* mark_debug = "true" *) input logic RegWriteW, IntDivW, // Write register file, integer divide instruction
input logic SquashSCW, input logic SquashSCW, // ***
input logic [2:0] ResultSrcW, input logic [2:0] ResultSrcW, // Select source of result to write back to register file
input logic [`XLEN-1:0] FCvtIntResW, input logic [`XLEN-1:0] FCvtIntResW, // FPU integer result ***
input logic [`XLEN-1:0] ReadDataW, input logic [`XLEN-1:0] ReadDataW, // Read data from LSU
input logic [`XLEN-1:0] CSRReadValW, MDUResultW, input logic [`XLEN-1:0] CSRReadValW, MDUResultW, // CSR read result, MDU (Multiply/divide unit) result ***
input logic [`XLEN-1:0] FIntDivResultW, input logic [`XLEN-1:0] FIntDivResultW, // FPU's integer divide result ***
// Hazard Unit signals // Hazard Unit signals
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, // Register sources to read in Decode or Execute stage
output logic [4:0] RdE, RdM, RdW output logic [4:0] RdE, RdM, RdW // Register destinations in Execute, Memory, or Writeback stage
); );
// Fetch stage signals // Fetch stage signals
// Decode stage signals // Decode stage signals
logic [`XLEN-1:0] R1D, R2D; logic [`XLEN-1:0] R1D, R2D; // Read data from Rs1 (RD1), Rs2 (RD2)
logic [`XLEN-1:0] ExtImmD; logic [`XLEN-1:0] ExtImmD; // Extended immediate in Decode stage *** According to Figure 4.12, should be ImmExtD
logic [4:0] RdD; logic [4:0] RdD; // Destination register in Decode stage
// Execute stage signals // Execute stage signals
logic [`XLEN-1:0] R1E, R2E; logic [`XLEN-1:0] R1E, R2E; // Source operands read from register file
logic [`XLEN-1:0] ExtImmE; logic [`XLEN-1:0] ExtImmE; // Extended immediate in Execute stage ***According to Figure 4.12, should be ImmExtE
logic [`XLEN-1:0] SrcAE, SrcBE; logic [`XLEN-1:0] SrcAE, SrcBE; // ALU operands
logic [`XLEN-1:0] ALUResultE, AltResultE, IEUResultE; logic [`XLEN-1:0] ALUResultE, AltResultE, IEUResultE; // ALU result, Alternative result (ExtImmE or PC+4), computed address *** According to Figure 4.12, IEUResultE should be called IEUAdrE
// Memory stage signals // Memory stage signals
logic [`XLEN-1:0] IEUResultM; logic [`XLEN-1:0] IEUResultM; // Address computed by ALU *** According to Figure 4.12, IEUResultM should be called IEUAdrM
logic [`XLEN-1:0] IFResultM; logic [`XLEN-1:0] IFResultM; // ***
// Writeback stage signals // Writeback stage signals
logic [`XLEN-1:0] SCResultW; logic [`XLEN-1:0] SCResultW; // Store Conditional result
logic [`XLEN-1:0] ResultW; logic [`XLEN-1:0] ResultW; // Result to write to register file
logic [`XLEN-1:0] IFResultW, IFCvtResultW, MulDivResultW; logic [`XLEN-1:0] IFResultW, IFCvtResultW, MulDivResultW; // ***
// Decode stage // Decode stage
assign Rs1D = InstrD[19:15]; assign Rs1D = InstrD[19:15];

View File

@ -1,7 +1,8 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// extend.sv // extend.sv
// //
// Written: David_Harris@hmc.edu 9 January 2021 // Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu
// Created: 9 January 2021
// Modified: // Modified:
// //
// Purpose: Produce sign-extended immediates from various formats // Purpose: Produce sign-extended immediates from various formats
@ -29,9 +30,9 @@
`include "wally-config.vh" `include "wally-config.vh"
module extend ( module extend (
input logic [31:7] InstrD, input logic [31:7] InstrD, // All instruction bits except opcode (lower 7 bits)
input logic [2:0] ImmSrcD, input logic [2:0] ImmSrcD, // Select what kind of extension to perform
output logic [`XLEN-1:0 ] ExtImmD); output logic [`XLEN-1:0 ] ExtImmD); // Extended immediate ***According to Figure 4.12, should be ImmExtD
localparam [`XLEN-1:0] undefined = {(`XLEN){1'bx}}; // could change to 0 after debug localparam [`XLEN-1:0] undefined = {(`XLEN){1'bx}}; // could change to 0 after debug

View File

@ -1,7 +1,8 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// forward.sv // forward.sv
// //
// Written: David_Harris@hmc.edu 9 January 2021 // Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu
// Created: 9 January 2021
// Modified: // Modified:
// //
// Purpose: Determine datapath forwarding // Purpose: Determine datapath forwarding
@ -30,17 +31,17 @@
module forward( module forward(
// Detect hazards // Detect hazards
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, // Source and destination registers
input logic MemReadE, MDUE, CSRReadE, input logic MemReadE, MDUE, CSRReadE, // Execute stage instruction is a load (MemReadE), divide (MDUE), or CSR read (CSRReadE)
input logic RegWriteM, RegWriteW, input logic RegWriteM, RegWriteW, // Instruction in Memory or Writeback stage writes register file
input logic FCvtIntE, input logic FCvtIntE, // *** FPU (Floating-point unit) converting float to int
input logic SCE, input logic SCE, // *** Store Conditional instruction
// Forwarding controls // Forwarding controls
output logic [1:0] ForwardAE, ForwardBE, output logic [1:0] ForwardAE, ForwardBE, // Select signals for forwarding multiplexers
output logic FCvtIntStallD, LoadStallD, MDUStallD, CSRRdStallD output logic FCvtIntStallD, LoadStallD, MDUStallD, CSRRdStallD // Stall due to conversion, load, multiply/divide, CSR read
); );
logic MatchDE; logic MatchDE; // Match between a source register in Decode stage and destination register in Execute stage
always_comb begin always_comb begin
ForwardAE = 2'b00; ForwardAE = 2'b00;

View File

@ -30,66 +30,65 @@
module ieu ( module ieu (
input logic clk, reset, input logic clk, reset,
// Decode Stage interface // Decode stage signals
input logic [31:0] InstrD, input logic [31:0] InstrD, // Instruction
input logic IllegalIEUInstrFaultD, input logic IllegalIEUInstrFaultD, // Illegal instruction
output logic IllegalBaseInstrFaultD, output logic IllegalBaseInstrFaultD, // ***
// Execute Stage interface // Execute stage signals
input logic [`XLEN-1:0] PCE, input logic [`XLEN-1:0] PCE, // PC
input logic [`XLEN-1:0] PCLinkE, input logic [`XLEN-1:0] PCLinkE, // PC + 4
input logic FWriteIntE, FCvtIntE, FCvtIntW, input logic FWriteIntE, FCvtIntE, // FPU writes to integer register file, FPU converts float to int
output logic [`XLEN-1:0] IEUAdrE, output logic [`XLEN-1:0] IEUAdrE, // Memory address
output logic IntDivE, W64E, output logic IntDivE, W64E, // Integer divide, RV64 W-type instruction
output logic [2:0] Funct3E, output logic [2:0] Funct3E, // Funct3 instruction field
output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // these are the src outputs before the mux choosing between them and PCE to put in srcA/B output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU src inputs before the mux choosing between them and PCE to put in srcA/B
output logic [4:0] RdE, // Destination register
// Memory stage interface // Memory stage signals
input logic SquashSCW, // from LSU input logic SquashSCW, // From LSU ***
output logic [1:0] MemRWM, // read/write control goes to LSU output logic [1:0] MemRWM, // Read/write control goes to LSU
output logic [1:0] AtomicM, // atomic control goes to LSU output logic [1:0] AtomicM, // Atomic control goes to LSU
output logic [`XLEN-1:0] WriteDataM, // write data to LSU output logic [`XLEN-1:0] WriteDataM, // Write data to LSU
output logic [2:0] Funct3M, // Funct3 (size and signedness) to LSU
output logic [2:0] Funct3M, // size and signedness to LSU output logic [`XLEN-1:0] SrcAM, // ALU SrcA to Privileged unit and FPU
output logic [`XLEN-1:0] SrcAM, // to privilege and fpu output logic [4:0] RdM, // Destination register
output logic [4:0] RdE, RdM, input logic [`XLEN-1:0] FIntResM, // ***
input logic [`XLEN-1:0] FIntResM, output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$
output logic InvalidateICacheM, FlushDCacheM, output logic InstrValidM, // Instruction is valid
// Writeback stage signals
// Writeback stage input logic [`XLEN-1:0] FIntDivResultW, // Integer divide result *** why F?
input logic [`XLEN-1:0] FIntDivResultW, input logic [`XLEN-1:0] CSRReadValW, MDUResultW, // CSR read value, MDU (multiply/divide unit) result
input logic [`XLEN-1:0] CSRReadValW, MDUResultW, input logic [`XLEN-1:0] FCvtIntResW, // FPU's float to int conversion result ***
input logic [`XLEN-1:0] FCvtIntResW, input logic FCvtIntW, // FPU converts float to int
output logic [4:0] RdW, output logic [4:0] RdW, // Destination register
input logic [`XLEN-1:0] ReadDataW, input logic [`XLEN-1:0] ReadDataW, // LSU's read data
output logic InstrValidM, // Hazard unit signals
// hazards input logic StallD, StallE, StallM, StallW, // Final stall signals ***
input logic StallD, StallE, StallM, StallW, input logic FlushD, FlushE, FlushM, FlushW, // Flush signals
input logic FlushD, FlushE, FlushM, FlushW, output logic FCvtIntStallD, LoadStallD, // Intermediate stall signals ***
output logic FCvtIntStallD, LoadStallD, MDUStallD, CSRRdStallD, output logic MDUStallD, CSRRdStallD, StoreStallD
output logic PCSrcE, output logic PCSrcE, // Select next PC (between PC+4 and IEUAdrE)
output logic CSRReadM, CSRWriteM, PrivilegedM, output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction ***
output logic CSRWriteFenceM, output logic CSRWriteFenceM // CSR write is a fence instruction ***
output logic StoreStallD
); );
logic [2:0] ImmSrcD; logic [2:0] ImmSrcD; // Select type of immediate extension
logic [1:0] FlagsE; logic [1:0] FlagsE; // Comparison flags ({eq, lt})
logic [2:0] ALUControlE; logic [2:0] ALUControlE; // ALU Control
logic ALUSrcAE, ALUSrcBE; logic ALUSrcAE, ALUSrcBE; // ALU source operands
logic [2:0] ResultSrcW; logic [2:0] ResultSrcW; // Source of result in Writeback stage
logic ALUResultSrcE; logic ALUResultSrcE; // ALU result
logic SCE; logic SCE; // Store Conditional instruction ***
logic FWriteIntM; logic FWriteIntM; // FPU writing to integer register file ***
logic IntDivW; logic IntDivW; // Integer divide instruction
// forwarding signals // forwarding signals
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E; logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E; // Source and destination registers
logic [1:0] ForwardAE, ForwardBE; logic [1:0] ForwardAE, ForwardBE; // Select signals for forwarding multiplexers
logic RegWriteM, RegWriteW; logic RegWriteM, RegWriteW; // Register will be written in Memory, Writeback stages
logic MemReadE, CSRReadE; logic MemReadE, CSRReadE; // Load, CSRRead instruction
logic JumpE; logic JumpE; // Jump instruction
logic BranchSignedE; logic BranchSignedE; // Branch does signed comparison on operands
logic MDUE; logic MDUE; // Multiply/divide instruction ***
controller c( controller c(
.clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD, .clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD,

View File

@ -1,7 +1,8 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// regfile.sv // regfile.sv
// //
// Written: David_Harris@hmc.edu 9 January 2021 // Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu
// Created: 9 January 2021
// Modified: // Modified:
// //
// Purpose: 3-port register file // Purpose: 3-port register file
@ -30,21 +31,21 @@
module regfile ( module regfile (
input logic clk, reset, input logic clk, reset,
input logic we3, input logic we3, // Write enable
input logic [ 4:0] a1, a2, a3, input logic [ 4:0] a1, a2, a3, // Source registers to read (a1, a2), destination register to write (a3)
input logic [`XLEN-1:0] wd3, input logic [`XLEN-1:0] wd3, // Write data for port 3
output logic [`XLEN-1:0] rd1, rd2); output logic [`XLEN-1:0] rd1, rd2); // Read data for ports 1, 2
localparam NUMREGS = `E_SUPPORTED ? 16 : 32; // only 16 registers in E mode localparam NUMREGS = `E_SUPPORTED ? 16 : 32; // only 16 registers in E mode
(* mark_debug = "true" *) logic [`XLEN-1:0] rf[NUMREGS-1:1]; (* mark_debug = "true" *) logic [`XLEN-1:0] rf[NUMREGS-1:1];
integer i; integer i;
// three ported register file // Three ported register file
// read two ports combinationally (A1/RD1, A2/RD2) // Read two ports combinationally (a1/rd1, a2/rd2)
// write third port on rising edge of clock (A3/WD3/WE3) // Write third port on rising edge of clock (a3/wd3/we3)
// write occurs on falling edge of clock // Write occurs on falling edge of clock
// register 0 hardwired to 0 // Register 0 hardwired to 0
// reset is intended for simulation only, not synthesis // reset is intended for simulation only, not synthesis
// can logic be adjusted to not need resettable registers? // can logic be adjusted to not need resettable registers?

View File

@ -1,7 +1,8 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// shifter.sv // shifter.sv
// //
// Written: David_Harris@hmc.edu 9 January 2021 // Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu
// Created: 9 January 2021
// Modified: // Modified:
// //
// Purpose: RISC-V 32/64 bit shifter // Purpose: RISC-V 32/64 bit shifter
@ -29,19 +30,19 @@
`include "wally-config.vh" `include "wally-config.vh"
module shifter ( module shifter (
input logic [`XLEN-1:0] A, input logic [`XLEN-1:0] A, // Source
input logic [`LOG_XLEN-1:0] Amt, input logic [`LOG_XLEN-1:0] Amt, // Shift amount
input logic Right, Arith, W64, input logic Right, Arith, W64, // Shift right, arithmetic, RV64 W-type shift
output logic [`XLEN-1:0] Y); output logic [`XLEN-1:0] Y); // Shifted result
logic [2*`XLEN-2:0] z, zshift; 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; logic [`LOG_XLEN-1:0] amttrunc, offset; // Shift amount adjusted for RV64, right-shift amount
// Handle left and right shifts with a funnel shifter. // Handle left and right shifts with a funnel shifter.
// For RV32, only 32-bit shifts are needed. // For RV32, only 32-bit shifts are needed.
// For RV64, 32 and 64-bit shifts are needed, with sign extension. // For RV64, 32- and 64-bit shifts are needed, with sign extension.
// funnel shifter input (see CMOS VLSI Design 4e Section 11.8.1, note Table 11.11 shift types wrong) // Funnel shifter input (see CMOS VLSI Design 4e Section 11.8.1, note Table 11.11 shift types wrong)
if (`XLEN==32) begin:shifter // RV32 if (`XLEN==32) begin:shifter // RV32
always_comb // funnel mux always_comb // funnel mux
if (Right) if (Right)
@ -62,13 +63,13 @@ module shifter (
else z = {63'b0, A}; else z = {63'b0, A};
else z = {A, 63'b0}; else z = {A, 63'b0};
end end
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
// opposite offset for right shfits // Opposite offset for right shifts
assign offset = Right ? amttrunc : ~amttrunc; assign offset = Right ? amttrunc : ~amttrunc;
// funnel operation // Funnel operation
assign zshift = z >> offset; assign zshift = z >> offset;
assign Y = zshift[`XLEN-1:0]; assign Y = zshift[`XLEN-1:0];
endmodule endmodule