Merge branch 'main' of github.com:davidharrishmc/riscv-wally into boot

This commit is contained in:
Jacob Pease 2023-01-17 15:42:23 -06:00
commit 03c72e5855
10 changed files with 305 additions and 294 deletions

View File

@ -487,11 +487,11 @@ add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RdM
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RdW
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RD1D
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RD2D
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ExtImmD
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ImmExtD
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RdD
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RD1E
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RD2E
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ExtImmE
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ImmExtE
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ForwardedSrcAE
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/SrcAE
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/SrcBE
@ -513,7 +513,7 @@ add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/regf/rd2
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/regf/i
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ext/InstrD
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ext/ImmSrcD
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ext/ExtImmD
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ext/ImmExtD
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RD1EReg/clk
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RD1EReg/reset
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RD1EReg/clear
@ -524,11 +524,11 @@ add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RD2EReg/reset
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RD2EReg/clear
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RD2EReg/d
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/RD2EReg/q
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ExtImmEReg/clk
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ExtImmEReg/reset
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ExtImmEReg/clear
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ExtImmEReg/d
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ExtImmEReg/q
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ImmExtEReg/clk
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ImmExtEReg/reset
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ImmExtEReg/clear
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ImmExtEReg/d
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/ImmExtEReg/q
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/Rs1EReg/clk
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/Rs1EReg/reset
add wave -noupdate -radix hexadecimal /testbench/dut/core/ieu/dp/Rs1EReg/clear

View File

@ -30,38 +30,40 @@
`include "wally-config.vh"
module alu #(parameter WIDTH=32) (
input logic [WIDTH-1:0] A, B,
input logic [2:0] ALUControl,
input logic [2:0] Funct3,
output logic [WIDTH-1:0] Result,
output logic [WIDTH-1:0] Sum);
input logic [WIDTH-1:0] A, B, // Operands
input logic [2:0] ALUControl, // With Funct3, indicates operation to perform
input logic [2:0] Funct3, // With ALUControl, indicates operation to perform
output logic [WIDTH-1:0] Result, // ALU result
output logic [WIDTH-1:0] Sum); // Sum of operands
logic [WIDTH-1:0] CondInvB, Shift, SLT, SLTU, FullResult;
logic Carry, Neg;
logic LT, LTU;
logic W64, SubArith, ALUOp;
logic Asign, Bsign;
// 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; // Intermediate results
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
// Extract control signals
// 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
// Extract control signals from ALUControl.
assign {W64, SubArith, ALUOp} = ALUControl;
// addition
// Addition
assign CondInvB = SubArith ? ~B : B;
assign {Carry, Sum} = A + CondInvB + {{(WIDTH-1){1'b0}}, SubArith};
// Shifts
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
// 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 Asign = A[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;
// SLT
@ -70,7 +72,7 @@ module alu #(parameter WIDTH=32) (
// Select appropriate ALU Result
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
3'b000: FullResult = Sum; // add or sub
3'b?01: FullResult = Shift; // sll, sra, or srl
@ -81,8 +83,8 @@ module alu #(parameter WIDTH=32) (
3'b111: FullResult = A & B; // and
endcase
// support W-type RV64I ADDW/SUBW/ADDIW/Shifts that sign-extend 32-bit result to 64 bits
if (WIDTH==64) assign Result = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult;
else assign Result = FullResult;
// 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;
else assign Result = FullResult;
endmodule

View File

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

View File

@ -1,7 +1,8 @@
///////////////////////////////////////////
// controller.sv
//
// Written: David_Harris@hmc.edu 9 January 2021
// Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu
// Created: 9 January 2021
// Modified:
//
// Purpose: Top level controller module
@ -30,86 +31,87 @@
module controller(
input logic clk, reset,
input logic clk, reset,
// Decode stage control signals
input logic StallD, FlushD,
input logic [31:0] InstrD,
output logic [2:0] ImmSrcD,
input logic IllegalIEUInstrFaultD,
output logic IllegalBaseInstrFaultD,
// Execute stage control signals
input logic StallE, FlushE,
input logic [1:0] FlagsE,
input logic FWriteIntE,
output logic PCSrcE, // for datapath and Hazard Unit
output logic [2:0] ALUControlE,
output logic ALUSrcAE, ALUSrcBE,
output logic ALUResultSrcE,
output logic MemReadE, CSRReadE, // for Hazard Unit
output logic [2:0] Funct3E,
output logic IntDivE, MDUE, W64E,
output logic JumpE,
output logic SCE,
output logic BranchSignedE,
input logic StallD, FlushD, // Stall, flush Decode stage
input logic [31:0] InstrD, // Instruction in Decode stage
output logic [2:0] ImmSrcD, // Type of immediate extension
input logic IllegalIEUInstrFaultD, // Illegal IEU instruction
output logic IllegalBaseInstrFaultD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers
// Execute stage control signals
input logic StallE, FlushE, // Stall, flush Execute stage
input logic [1:0] FlagsE, // Comparison flags ({eq, lt})
input logic FWriteIntE, // Write integer register, coming from FPU controller
output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit)
output logic [2:0] ALUControlE, // ALU operation to perform
output logic ALUSrcAE, ALUSrcBE, // ALU operands
output logic ALUResultSrcE, // Selects result to pass on to Memory stage
output logic MemReadE, CSRReadE, // Instruction reads memory, reads a CSR (needed for Hazard unit)
output logic [2:0] Funct3E, // Instruction's funct3 field
output logic IntDivE, // Integer divide
output logic MDUE, // MDU (multiply/divide) operatio
output logic W64E, // RV64 W-type operation
output logic JumpE, // jump instruction
output logic SCE, // Store Conditional instruction
output logic BranchSignedE, // Branch comparison operands are signed (if it's a branch)
// Memory stage control signals
input logic StallM, FlushM,
output logic [1:0] MemRWM,
output logic CSRReadM, CSRWriteM, PrivilegedM,
output logic [1:0] AtomicM,
output logic [2:0] Funct3M,
output logic RegWriteM, // for Hazard Unit
output logic InvalidateICacheM, FlushDCacheM,
output logic InstrValidM,
output logic FWriteIntM,
input logic StallM, FlushM, // Stall, flush Memory stage
output logic [1:0] MemRWM, // Mem read/write: MemRWM[1] = 1 for read, MemRWM[0] = 1 for write
output logic CSRReadM, CSRWriteM, PrivilegedM, // CSR read, write, or privileged instruction
output logic [1:0] AtomicM, // Atomic (AMO) instruction
output logic [2:0] Funct3M, // Instruction's funct3 field
output logic RegWriteM, // Instruction writes a register (needed for Hazard unit)
output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$
output logic InstrValidM, // Instruction is valid
output logic FWriteIntM, // FPU controller writes integer register file
// Writeback stage control signals
input logic StallW, FlushW,
output logic RegWriteW, IntDivW, // for datapath and Hazard Unit
output logic [2:0] ResultSrcW,
input logic StallW, FlushW, // Stall, flush Writeback stage
output logic RegWriteW, IntDivW, // Instruction writes a register, is an integer divide
output logic [2:0] ResultSrcW, // Select source of result to write back to register file
// Stall during CSRs
//output logic CSRWriteFencePendingDEM,
output logic CSRWriteFenceM,
output logic StoreStallD
output logic CSRWriteFenceM, // CSR write or fence instruction; needs to flush the following instructions
output logic StoreStallD // Store (memory write) causes stall
);
logic [6:0] OpD;
logic [2:0] Funct3D;
logic [6:0] Funct7D;
logic [4:0] Rs1D;
logic [6:0] OpD; // Opcode in Decode stage
logic [2:0] Funct3D; // Funct3 field in Decode stage
logic [6:0] Funct7D; // Funct7 field in Decode stage
logic [4:0] Rs1D; // Rs1 source register in Decode stage
`define CTRLW 23
// pipelined control signals
logic RegWriteD, RegWriteE;
logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM;
logic [1:0] MemRWD, MemRWE;
logic JumpD;
logic BranchD, BranchE;
logic ALUOpD;
logic [2:0] ALUControlD;
logic ALUSrcAD, ALUSrcBD;
logic ALUResultSrcD, W64D, MDUD;
logic CSRZeroSrcD;
logic CSRReadD;
logic [1:0] AtomicD;
logic FenceXD;
logic InvalidateICacheD, FlushDCacheD;
logic CSRWriteD, CSRWriteE;
logic InstrValidD, InstrValidE;
logic PrivilegedD, PrivilegedE;
logic InvalidateICacheE, FlushDCacheE;
logic [`CTRLW-1:0] ControlsD;
logic SubArithD;
logic subD, sraD, sltD, sltuD;
logic BranchTakenE;
logic eqE, ltE;
logic unused;
logic BranchFlagE;
logic IEURegWriteE;
logic IllegalERegAdrD;
logic [1:0] AtomicE;
logic FenceD, FenceE, FenceM;
logic SFenceVmaD;
logic IntDivM;
logic RegWriteD, RegWriteE; // RegWrite (register will be written)
logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; // Select which result to write back to register file
logic [1:0] MemRWD, MemRWE; // Store (write to memory)
logic JumpD; // Jump instruction
logic BranchD, BranchE; // Branch instruction
logic ALUOpD; // 0 for address generation, 1 for all other operations (must use Funct3)
logic [2:0] ALUControlD; // Determines ALU operation
logic ALUSrcAD, ALUSrcBD; // ALU inputs
logic ALUResultSrcD, W64D, MDUD; // ALU result, is RV64 W-type, is multiply/divide instruction
logic CSRZeroSrcD; // Ignore setting and clearing zeros to CSR
logic CSRReadD; // CSR read instruction
logic [1:0] AtomicD; // Atomic (AMO) instruction
logic FenceXD; // Fence instruction
logic InvalidateICacheD, FlushDCacheD;// Invalidate I$, flush D$
logic CSRWriteD, CSRWriteE; // CSR write
logic InstrValidD, InstrValidE; // Instruction is valid
logic PrivilegedD, PrivilegedE; // Privileged instruction
logic InvalidateICacheE, FlushDCacheE;// Invalidate I$, flush D$
logic [`CTRLW-1:0] ControlsD; // Main Instruction Decoder control signals
logic SubArithD; // TRUE for R-type subtracts and sra, slt, sltu
logic subD, sraD, sltD, sltuD; // Indicates if is one of these instructions
logic BranchTakenE; // Branch is taken
logic eqE, ltE; // Comparator outputs
logic unused;
logic BranchFlagE; // Branch flag to use (chosen between eq or lt)
logic IEURegWriteE; // Register write
logic IllegalERegAdrD; // RV32E attempts to write upper 16 registers
logic [1:0] AtomicE; // Atomic instruction
logic FenceD, FenceE, FenceM; // Fence instruction
logic SFenceVmaD; // sfence.vma instruction
logic IntDivM; // Integer divide instruction
// Extract fields
@ -122,58 +124,58 @@ module controller(
always_comb
case(OpD)
// 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'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'b0001111: if(`ZIFENCEI_SUPPORTED)
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0; // fence
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'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)
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0; // fence
else
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_0; // fence treated as nop
7'b0010011: ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU
7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_0_0_0_0_0_0_0_0_00_0; // auipc
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_0; // fence treated as nop
7'b0010011: ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU
7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_0_0_0_0_0_0_0_0_00_0; // auipc
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
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'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
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'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
if (InstrD[31:27] == 5'b00010)
ControlsD = `CTRLW'b1_000_00_10_001_0_0_0_0_0_0_0_0_0_01_0; // lr
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
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
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)
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)
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
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
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'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)
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
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'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
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'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'b1110011: if (`ZICSR_SUPPORTED) begin
if (Funct3D == 3'b000)
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_1_0_0_00_0; // privileged; decoded further in priveleged modules
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_1_0_0_00_0; // privileged; decoded further in priveleged modules
else
ControlsD = `CTRLW'b1_000_00_00_010_0_0_0_0_0_1_0_0_0_00_0; // csrs
ControlsD = `CTRLW'b1_000_00_00_010_0_0_0_0_0_1_0_0_0_00_0; // csrs
end else
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
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
// unswizzle control bits
// squash control signals if coming from an illegal compressed instruction
// Unswizzle control bits
// 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.
assign IllegalERegAdrD = `E_SUPPORTED & `ZICSR_SUPPORTED & ControlsD[`CTRLW-1] & InstrD[11];
assign IllegalBaseInstrFaultD = ControlsD[0] | IllegalERegAdrD;
@ -183,7 +185,7 @@ module controller(
assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source?
assign CSRWriteD = CSRReadD & !(CSRZeroSrcD & InstrD[13]); // Don't write if setting or clearing zeros
assign CSRWriteD = CSRReadD & !(CSRZeroSrcD & InstrD[13]); // Don't write if setting or clearing zeros
assign SFenceVmaD = PrivilegedD & (InstrD[31:25] == 7'b0001001);
assign FenceD = SFenceVmaD | FenceXD; // possible sfence.vma or fence.i
@ -197,7 +199,7 @@ module controller(
// Fences
// 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
logic FenceID;
assign FenceID = FenceXD & (Funct3D == 3'b001); // is it a FENCE.I instruction?
@ -243,7 +245,7 @@ module controller(
// Flush F, D, and E stages on a CSR write or Fence.I or SFence.VMA
assign CSRWriteFenceM = CSRWriteM | FenceM;
// assign CSRWriteFencePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM | FenceD | FenceE | FenceM;
// assign CSRWriteFencePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM | FenceD | FenceE | FenceM;
// the synchronous DTIM cannot read immediately after write
// a cache cannot read or write immediately after a write

View File

@ -1,7 +1,8 @@
///////////////////////////////////////////
// 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:
//
// Purpose: Wally Integer Datapath
@ -29,73 +30,75 @@
`include "wally-config.vh"
module datapath (
input logic clk, reset,
input logic clk, reset,
// Decode stage signals
input logic [2:0] ImmSrcD,
input logic [31:0] InstrD,
input logic [2:0] Funct3E,
input logic [2:0] ImmSrcD, // Selects type of immediate extension
input logic [31:0] InstrD, // Instruction in Decode stage
input logic [2:0] Funct3E, // Funct3 field of instruction in Execute stage
// Execute stage signals
input logic StallE, FlushE,
input logic [1:0] ForwardAE, ForwardBE,
input logic [2:0] ALUControlE,
input logic ALUSrcAE, ALUSrcBE,
input logic ALUResultSrcE,
input logic JumpE,
input logic BranchSignedE,
input logic [`XLEN-1:0] PCE,
input logic [`XLEN-1:0] PCLinkE,
output logic [1:0] FlagsE,
output logic [`XLEN-1:0] IEUAdrE,
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
input logic StallE, FlushE, // Stall, flush Execute stage
input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages
input logic [2:0] ALUControlE, // Indicate operation ALU performs
input logic ALUSrcAE, ALUSrcBE, // ALU operands
input logic ALUResultSrcE, // Selects result to pass on to Memory stage
input logic JumpE, // Is a jump (j) instruction
input logic BranchSignedE, // Branch comparison operands are signed (if it's a branch)
input logic [`XLEN-1:0] PCE, // PC in Execute stage
input logic [`XLEN-1:0] PCLinkE, // PC + 4 (of instruction 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
// Memory stage signals
input logic StallM, FlushM,
input logic FWriteIntM, FCvtIntW,
input logic [`XLEN-1:0] FIntResM,
output logic [`XLEN-1:0] SrcAM,
output logic [`XLEN-1:0] WriteDataM,
input logic StallM, FlushM, // Stall, flush Memory stage
input logic FWriteIntM, FCvtIntW, // FPU writes integer register file, FPU converts float to int
input logic [`XLEN-1:0] FIntResM, // FPU integer result
output logic [`XLEN-1:0] SrcAM, // ALU's Source A in Memory stage to privilege unit for CSR writes
output logic [`XLEN-1:0] WriteDataM, // Write data in Memory stage
// Writeback stage signals
input logic StallW, FlushW,
(* mark_debug = "true" *) input logic RegWriteW, IntDivW,
input logic SquashSCW,
input logic [2:0] ResultSrcW,
input logic [`XLEN-1:0] FCvtIntResW,
input logic [`XLEN-1:0] ReadDataW,
input logic [`XLEN-1:0] CSRReadValW, MDUResultW,
input logic [`XLEN-1:0] FIntDivResultW,
input logic StallW, FlushW, // Stall, flush Writeback stage
(* mark_debug = "true" *) 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
input logic [`XLEN-1:0] ReadDataW, // Read data from LSU
input logic [`XLEN-1:0] CSRReadValW, MDUResultW, // CSR read result, MDU (Multiply/divide unit) result
input logic [`XLEN-1:0] FIntDivResultW, // FPU's integer divide result
// Hazard Unit signals
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E,
output logic [4:0] RdE, RdM, RdW
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, // Register sources to read in Decode or Execute stage
output logic [4:0] RdE, RdM, RdW // Register destinations in Execute, Memory, or Writeback stage
);
// Fetch stage signals
// Decode stage signals
logic [`XLEN-1:0] R1D, R2D;
logic [`XLEN-1:0] ExtImmD;
logic [4:0] RdD;
logic [`XLEN-1:0] R1D, R2D; // Read data from Rs1 (RD1), Rs2 (RD2)
logic [`XLEN-1:0] ImmExtD; // Extended immediate in Decode stage
logic [4:0] RdD; // Destination register in Decode stage
// Execute stage signals
logic [`XLEN-1:0] R1E, R2E;
logic [`XLEN-1:0] ExtImmE;
logic [`XLEN-1:0] SrcAE, SrcBE;
logic [`XLEN-1:0] ALUResultE, AltResultE, IEUResultE;
logic [`XLEN-1:0] R1E, R2E; // Source operands read from register file
logic [`XLEN-1:0] ImmExtE; // Extended immediate in Execute stage
logic [`XLEN-1:0] SrcAE, SrcBE; // ALU operands
logic [`XLEN-1:0] ALUResultE, AltResultE, IEUResultE; // ALU result, Alternative result (ImmExtE or PC+4), computed address *** According to Figure 4.12, IEUResultE should be called IEUAdrE
// Memory stage signals
logic [`XLEN-1:0] IEUResultM;
logic [`XLEN-1:0] IFResultM;
logic [`XLEN-1:0] IEUResultM; // Address computed by ALU *** According to Figure 4.12, IEUResultM should be called IEUAdrM
logic [`XLEN-1:0] IFResultM; // Result from either IEU or single-cycle FPU op writing an integer register
// Writeback stage signals
logic [`XLEN-1:0] SCResultW;
logic [`XLEN-1:0] ResultW;
logic [`XLEN-1:0] IFResultW, IFCvtResultW, MulDivResultW;
logic [`XLEN-1:0] SCResultW; // Store Conditional result
logic [`XLEN-1:0] ResultW; // Result to write to register file
logic [`XLEN-1:0] IFResultW; // Result from either IEU or single-cycle FPU op writing an integer register
logic [`XLEN-1:0] IFCvtResultW; // Result from IEU, signle-cycle FPU op, or 2-cycle FCVT float to int
logic [`XLEN-1:0] MulDivResultW; // Multiply always comes from MDU. Divide could come from MDU or FPU (when using fdivsqrt for integer division)
// Decode stage
assign Rs1D = InstrD[19:15];
assign Rs2D = InstrD[24:20];
assign RdD = InstrD[11:7];
regfile regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, R1D, R2D);
extend ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ExtImmD);
extend ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ImmExtD);
// Execute stage pipeline register and logic
flopenrc #(`XLEN) RD1EReg(clk, reset, FlushE, ~StallE, R1D, R1E);
flopenrc #(`XLEN) RD2EReg(clk, reset, FlushE, ~StallE, R2D, R2E);
flopenrc #(`XLEN) ExtImmEReg(clk, reset, FlushE, ~StallE, ExtImmD, ExtImmE);
flopenrc #(`XLEN) ImmExtEReg(clk, reset, FlushE, ~StallE, ImmExtD, ImmExtE);
flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E);
flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E);
flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE);
@ -104,9 +107,9 @@ module datapath (
mux3 #(`XLEN) fbemux(R2E, ResultW, IFResultM, ForwardBE, ForwardedSrcBE);
comparator_dc_flip #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE);
mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ExtImmE, ALUSrcBE, SrcBE);
mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE);
alu #(`XLEN) alu(SrcAE, SrcBE, ALUControlE, Funct3E, ALUResultE, IEUAdrE);
mux2 #(`XLEN) altresultmux(ExtImmE, PCLinkE, JumpE, AltResultE);
mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE);
mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);
// Memory stage pipeline register

View File

@ -1,7 +1,8 @@
///////////////////////////////////////////
// extend.sv
//
// Written: David_Harris@hmc.edu 9 January 2021
// Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu
// Created: 9 January 2021
// Modified:
//
// Purpose: Produce sign-extended immediates from various formats
@ -29,27 +30,27 @@
`include "wally-config.vh"
module extend (
input logic [31:7] InstrD,
input logic [2:0] ImmSrcD,
output logic [`XLEN-1:0 ] ExtImmD);
input logic [31:7] InstrD, // All instruction bits except opcode (lower 7 bits)
input logic [2:0] ImmSrcD, // Select what kind of extension to perform
output logic [`XLEN-1:0 ] ImmExtD); // Extended immediate
localparam [`XLEN-1:0] undefined = {(`XLEN){1'bx}}; // could change to 0 after debug
always_comb
case(ImmSrcD)
// I-type
3'b000: ExtImmD = {{(`XLEN-12){InstrD[31]}}, InstrD[31:20]};
3'b000: ImmExtD = {{(`XLEN-12){InstrD[31]}}, InstrD[31:20]};
// S-type (stores)
3'b001: ExtImmD = {{(`XLEN-12){InstrD[31]}}, InstrD[31:25], InstrD[11:7]};
3'b001: ImmExtD = {{(`XLEN-12){InstrD[31]}}, InstrD[31:25], InstrD[11:7]};
// B-type (branches)
3'b010: ExtImmD = {{(`XLEN-12){InstrD[31]}}, InstrD[7], InstrD[30:25], InstrD[11:8], 1'b0};
3'b010: ImmExtD = {{(`XLEN-12){InstrD[31]}}, InstrD[7], InstrD[30:25], InstrD[11:8], 1'b0};
// J-type (jal)
3'b011: ExtImmD = {{(`XLEN-20){InstrD[31]}}, InstrD[19:12], InstrD[20], InstrD[30:21], 1'b0};
3'b011: ImmExtD = {{(`XLEN-20){InstrD[31]}}, InstrD[19:12], InstrD[20], InstrD[30:21], 1'b0};
// U-type (lui, auipc)
3'b100: ExtImmD = {{(`XLEN-31){InstrD[31]}}, InstrD[30:12], 12'b0};
3'b100: ImmExtD = {{(`XLEN-31){InstrD[31]}}, InstrD[30:12], 12'b0};
// Store Conditional: zero offset
3'b101: if (`A_SUPPORTED) ExtImmD = 0;
else ExtImmD = undefined;
default: ExtImmD = undefined; // undefined
3'b101: if (`A_SUPPORTED) ImmExtD = 0;
else ImmExtD = undefined;
default: ImmExtD = undefined; // undefined
endcase
endmodule

View File

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

View File

@ -29,67 +29,66 @@
`include "wally-config.vh"
module ieu (
input logic clk, reset,
// Decode Stage interface
input logic [31:0] InstrD,
input logic IllegalIEUInstrFaultD,
output logic IllegalBaseInstrFaultD,
// Execute Stage interface
input logic [`XLEN-1:0] PCE,
input logic [`XLEN-1:0] PCLinkE,
input logic FWriteIntE, FCvtIntE, FCvtIntW,
output logic [`XLEN-1:0] IEUAdrE,
output logic IntDivE, W64E,
output logic [2:0] Funct3E,
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
// Memory stage interface
input logic SquashSCW, // from LSU
output logic [1:0] MemRWM, // read/write 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 [2:0] Funct3M, // size and signedness to LSU
output logic [`XLEN-1:0] SrcAM, // to privilege and fpu
output logic [4:0] RdE, RdM,
input logic [`XLEN-1:0] FIntResM,
output logic InvalidateICacheM, FlushDCacheM,
// Writeback stage
input logic [`XLEN-1:0] FIntDivResultW,
input logic [`XLEN-1:0] CSRReadValW, MDUResultW,
input logic [`XLEN-1:0] FCvtIntResW,
output logic [4:0] RdW,
input logic [`XLEN-1:0] ReadDataW,
output logic InstrValidM,
// hazards
input logic StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW,
output logic FCvtIntStallD, LoadStallD, MDUStallD, CSRRdStallD,
output logic PCSrcE,
output logic CSRReadM, CSRWriteM, PrivilegedM,
output logic CSRWriteFenceM,
output logic StoreStallD
input logic clk, reset,
// Decode stage signals
input logic [31:0] InstrD, // Instruction
input logic IllegalIEUInstrFaultD, // Illegal instruction
output logic IllegalBaseInstrFaultD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers
// Execute stage signals
input logic [`XLEN-1:0] PCE, // PC
input logic [`XLEN-1:0] PCLinkE, // PC + 4
input logic FWriteIntE, FCvtIntE, // FPU writes to integer register file, FPU converts float to int
output logic [`XLEN-1:0] IEUAdrE, // Memory address
output logic IntDivE, W64E, // Integer divide, RV64 W-type instruction
output logic [2:0] Funct3E, // Funct3 instruction field
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 signals
input logic SquashSCW, // Squash store conditional, from LSU
output logic [1:0] MemRWM, // Read/write 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 [2:0] Funct3M, // Funct3 (size and signedness) to LSU
output logic [`XLEN-1:0] SrcAM, // ALU SrcA to Privileged unit and FPU
output logic [4:0] RdM, // Destination register
input logic [`XLEN-1:0] FIntResM, // Integer result from FPU (fmv, fclass, fcmp)
output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$
output logic InstrValidM, // Instruction is valid
// Writeback stage signals
input logic [`XLEN-1:0] FIntDivResultW, // Integer divide result from FPU fdivsqrt
input logic [`XLEN-1:0] CSRReadValW, MDUResultW, // CSR read value, MDU (multiply/divide unit) result
input logic [`XLEN-1:0] FCvtIntResW, // FPU's float to int conversion result
input logic FCvtIntW, // FPU converts float to int
output logic [4:0] RdW, // Destination register
input logic [`XLEN-1:0] ReadDataW, // LSU's read data
// Hazard unit signals
input logic StallD, StallE, StallM, StallW, // Stall signals from hazard unit
input logic FlushD, FlushE, FlushM, FlushW, // Flush signals
output logic FCvtIntStallD, LoadStallD, // Stall causes from IEU to hazard unit
output logic MDUStallD, CSRRdStallD, StoreStallD,
output logic PCSrcE, // Select next PC (between PC+4 and IEUAdrE)
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
);
logic [2:0] ImmSrcD;
logic [1:0] FlagsE;
logic [2:0] ALUControlE;
logic ALUSrcAE, ALUSrcBE;
logic [2:0] ResultSrcW;
logic ALUResultSrcE;
logic SCE;
logic FWriteIntM;
logic IntDivW;
logic [2:0] ImmSrcD; // Select type of immediate extension
logic [1:0] FlagsE; // Comparison flags ({eq, lt})
logic [2:0] ALUControlE; // ALU Control
logic ALUSrcAE, ALUSrcBE; // ALU source operands
logic [2:0] ResultSrcW; // Source of result in Writeback stage
logic ALUResultSrcE; // ALU result
logic SCE; // Store Conditional instruction
logic FWriteIntM; // FPU writing to integer register file
logic IntDivW; // Integer divide instruction
// forwarding signals
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E;
logic [1:0] ForwardAE, ForwardBE;
logic RegWriteM, RegWriteW;
logic MemReadE, CSRReadE;
logic JumpE;
logic BranchSignedE;
logic MDUE;
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E; // Source and destination registers
logic [1:0] ForwardAE, ForwardBE; // Select signals for forwarding multiplexers
logic RegWriteM, RegWriteW; // Register will be written in Memory, Writeback stages
logic MemReadE, CSRReadE; // Load, CSRRead instruction
logic JumpE; // Jump instruction
logic BranchSignedE; // Branch does signed comparison on operands
logic MDUE; // Multiply/divide instruction
controller c(
.clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD,

View File

@ -1,7 +1,8 @@
///////////////////////////////////////////
// regfile.sv
//
// Written: David_Harris@hmc.edu 9 January 2021
// Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu
// Created: 9 January 2021
// Modified:
//
// Purpose: 3-port register file
@ -30,26 +31,26 @@
module regfile (
input logic clk, reset,
input logic we3,
input logic [ 4:0] a1, a2, a3,
input logic [`XLEN-1:0] wd3,
output logic [`XLEN-1:0] rd1, rd2);
input logic we3, // Write enable
input logic [ 4:0] a1, a2, a3, // Source registers to read (a1, a2), destination register to write (a3)
input logic [`XLEN-1:0] wd3, // Write data for port 3
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
(* mark_debug = "true" *) logic [`XLEN-1:0] rf[NUMREGS-1:1];
integer i;
// three ported register file
// read two ports combinationally (A1/RD1, A2/RD2)
// write third port on rising edge of clock (A3/WD3/WE3)
// write occurs on falling edge of clock
// register 0 hardwired to 0
// Three ported register file
// Read two ports combinationally (a1/rd1, a2/rd2)
// Write third port on rising edge of clock (a3/wd3/we3)
// Write occurs on falling edge of clock
// Register 0 hardwired to 0
// reset is intended for simulation only, not synthesis
// can logic be adjusted to not need resettable registers?
always_ff @(negedge clk) // or posedge reset) // *** make this a preload in testbench rather than reset
always_ff @(negedge clk)
if (reset) for(i=1; i<NUMREGS; i++) rf[i] <= 0;
else if (we3) rf[a3] <= wd3;

View File

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