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

This commit is contained in:
Ross Thompson 2021-12-13 17:16:20 -06:00
commit 2d662bc4be
22 changed files with 262 additions and 154 deletions

@ -1 +1 @@
Subproject commit be67c99bd461742aa1c100bcc0732657faae2230
Subproject commit 84d043817f75f752c9873326475e11f16e3a6f7c

@ -1 +1 @@
Subproject commit d22b280198e74b871e04fc0ddb622fb825fdae49
Subproject commit ddcfa6cc3d80818140a459e590296c3079c5a3ec

View File

@ -1,2 +1,2 @@
vsim -do "do wally-pipelined.do rv32g arch32f"
vsim -do "do wally-pipelined.do rv64g arch64i"

View File

@ -1,3 +1,3 @@
vsim -c <<!
do wally-pipelined-batch.do rv32g arch32f
do wally-pipelined-batch.do rv64g arch64i
!

View File

@ -25,6 +25,8 @@
`include "wally-config.vh"
// *** this should probably be moved into the LSU because it is instantiated in the D$
module amoalu (
input logic [`XLEN-1:0] srca, srcb,
input logic [6:0] funct,

View File

@ -10,7 +10,7 @@ module fcvt (
input logic XInfE, // is X infinity
input logic XDenormE, // is X denormalized
input logic [10:0] BiasE, // bias - depends on precision (max exponent/2)
input logic [`XLEN-1:0] SrcAE, // integer input
input logic [`XLEN-1:0] ForwardedSrcAE, // integer input
input logic [2:0] FOpCtrlE, // chooses which instruction is done (full list below)
input logic [2:0] FrmE, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
input logic FmtE, // precision 1 = double 0 = single
@ -73,7 +73,7 @@ module fcvt (
////////////////////////////////////////////////////////
// position the input in the most significant bits
assign IntIn = FOpCtrlE[2] ? {SrcAE, {64-`XLEN{1'b0}}} : {SrcAE[31:0], 32'b0};
assign IntIn = FOpCtrlE[2] ? {ForwardedSrcAE, {64-`XLEN{1'b0}}} : {ForwardedSrcAE[31:0], 32'b0};
// make the integer positive
assign PosInt = IntIn[64-1]&~FOpCtrlE[1] ? -IntIn : IntIn;
// determine the integer's sign

View File

@ -30,7 +30,7 @@ module fpu (
input logic [2:0] FRM_REGW, // Rounding mode from CSR
input logic [31:0] InstrD, // instruction from IFU
input logic [`XLEN-1:0] ReadDataW,// Read data from memory
input logic [`XLEN-1:0] SrcAE, // Integer input being processed (from IEU)
input logic [`XLEN-1:0] ForwardedSrcAE, // Integer input being processed (from IEU)
input logic StallE, StallM, StallW, // stall signals from HZU
input logic FlushE, FlushM, FlushW, // flush signals from HZU
input logic [4:0] RdM, RdW, // which FP register to write to (from IEU)
@ -229,7 +229,7 @@ module fpu (
.XSNaNE, .ClassResE);
// Convert
fcvt fcvt (.XSgnE, .XExpE, .XManE, .XZeroE, .XNaNE, .XInfE, .XDenormE, .BiasE, .SrcAE, .FOpCtrlE, .FmtE, .FrmE,
fcvt fcvt (.XSgnE, .XExpE, .XManE, .XZeroE, .XNaNE, .XInfE, .XDenormE, .BiasE, .ForwardedSrcAE, .FOpCtrlE, .FmtE, .FrmE,
.CvtResE, .CvtFlgE);
// data to be stored in memory - to IEU
@ -238,7 +238,7 @@ module fpu (
assign FWriteDataE = FSrcYE[`XLEN-1:0];
// Align SrcA to MSB when single precicion
mux2 #(64) SrcAMux({{32{1'b1}}, SrcAE[31:0]}, {{64-`XLEN{1'b1}}, SrcAE}, FmtE, AlignedSrcAE);
mux2 #(64) SrcAMux({{32{1'b1}}, ForwardedSrcAE[31:0]}, {{64-`XLEN{1'b1}}, ForwardedSrcAE}, FmtE, AlignedSrcAE);
// select a result that may be written to the FP register
mux5 #(64) FResMux(AlignedSrcAE, SgnResE, CmpResE, CvtResE, CvtFpResE, FResSelE, FResE);

View File

@ -27,62 +27,66 @@
module alu #(parameter WIDTH=32) (
input logic [WIDTH-1:0] a, b,
input logic [4:0] alucontrol,
input logic [2:0] ALUControl,
input logic [2:0] Funct3,
output logic [WIDTH-1:0] result,
output logic [2:0] flags);
output logic [WIDTH-1:0] sum);
logic [WIDTH-1:0] condinvb, presum, sum, shift, slt, sltu, bor;
logic right, arith, w64;
logic carry, zero, neg;
logic [WIDTH-1:0] condinvb, sumtrunc, shift, slt, sltu, bor;
logic right; //, arith, w64;
logic carry, neg;
logic lt, ltu;
logic overflow;
logic W64, SubArith, ALUOp;
assign {W64, SubArith, ALUOp} = ALUControl;
// addition
assign condinvb = alucontrol[3] ? ~b : b;
assign {carry, presum} = a + condinvb + {{(WIDTH-1){1'b0}},alucontrol[3]};
// *** make sure condinvb is only applied when it should be (sub, slt/sltu)
assign condinvb = SubArith ? ~b : b;
assign {carry, sum} = a + condinvb + {{(WIDTH-1){1'b0}}, SubArith};
// support W-type RV64I ADDW/SUBW/ADDIW that sign-extend 32-bit result to 64 bits
generate
if (WIDTH==64)
assign sum = w64 ? {{32{presum[31]}}, presum[31:0]} : presum;
assign sumtrunc = W64 ? {{32{sum[31]}}, sum[31:0]} : sum;
else
assign sum = presum;
assign sumtrunc = sum;
endgenerate
// shifts
assign arith = alucontrol[3]; // sra
assign w64 = alucontrol[4];
assign right = (alucontrol[2:0] == 3'b101); // sra or srl
shifter sh(a, b[5:0], right, arith, w64, shift);
// assign arith = alucontrol[3]; // sra
// assign w64 = alucontrol[4];
assign right = (Funct3[2:0] == 3'b101); // sra or srl
shifter sh(a, b[5:0], right, SubArith, W64, shift);
// OR optionally passes zero when ALUControl[3] is set, supporting lui
assign bor = alucontrol[3] ? b : a|b;
// *** not needed anymore; simplify control
//assign bor = alucontrol[3] ? b : a|b;
// condition code flags based on add/subtract output
assign zero = (sum == 0);
assign neg = sum[WIDTH-1];
// overflow occurs when the numbers being added have the same sign
// and the result has the opposite sign
assign overflow = (a[WIDTH-1] ~^ condinvb[WIDTH-1]) & (a[WIDTH-1] ^ sum[WIDTH-1]);
assign lt = neg ^ overflow;
assign ltu = ~carry;
assign flags = {zero, lt, ltu};
// slt
assign slt = {{(WIDTH-1){1'b0}}, lt};
assign sltu = {{(WIDTH-1){1'b0}}, ltu};
always_comb
case (alucontrol[2:0])
3'b000: result = sum; // add or sub
3'b001: result = shift; // sll
3'b010: result = slt; // slt
3'b011: result = sltu; // sltu
3'b100: result = a ^ b; // xor
3'b101: result = shift; // sra or srl
3'b110: result = bor; // or / pass through input b for lui
3'b111: result = a & b; // and
endcase
if (~ALUOp) result = sumtrunc;
else
case (Funct3)
3'b000: result = sumtrunc; // add or sub
3'b001: result = shift; // sll
3'b010: result = slt; // slt
3'b011: result = sltu; // sltu
3'b100: result = a ^ b; // xor
3'b101: result = shift; // sra or srl
3'b110: result = a | b; // or
3'b111: result = a & b; // and
endcase
endmodule

View File

@ -0,0 +1,52 @@
///////////////////////////////////////////
// comparator.sv
//
// Written: David_Harris@hmc.edu 8 December 2021
// Modified:
//
// Purpose: Branch comparison
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
`include "wally-config.vh"
module comparator #(parameter WIDTH=32) (
input logic [WIDTH-1:0] a, b,
output logic [2:0] flags);
logic [WIDTH-1:0] bbar, diff;
logic carry, zero, neg, overflow, lt, ltu;
// NOTE: This can be replaced by some faster logic optimized
// to just compute flags and not the difference.
// subtraction
assign bbar = ~b;
assign {carry, diff} = a + bbar + 1;
// condition code flags based on add/subtract output
assign zero = (diff == 0);
assign neg = diff[WIDTH-1];
// overflow occurs when the numbers being subtracted have the opposite sign
// and the result has the opposite sign fron the first
assign overflow = (a[WIDTH-1] ^ b[WIDTH-1]) & (a[WIDTH-1] ^ diff[WIDTH-1]);
assign lt = neg ^ overflow;
assign ltu = ~carry;
assign flags = {zero, lt, ltu};
endmodule

View File

@ -38,9 +38,9 @@ module controller(
input logic StallE, FlushE,
input logic [2:0] FlagsE,
output logic PCSrcE, // for datapath and Hazard Unit
output logic [4:0] ALUControlE,
output logic [2:0] ALUControlE,
output logic ALUSrcAE, ALUSrcBE,
output logic TargetSrcE,
output logic ALUResultSrcE,
output logic MemReadE, CSRReadE, // for Hazard Unit
output logic [2:0] Funct3E,
output logic MulDivE, W64E,
@ -70,7 +70,7 @@ module controller(
logic [6:0] Funct7D;
logic [4:0] Rs1D;
`define CTRLW 24
`define CTRLW 23
// pipelined control signals
logic RegWriteD, RegWriteE;
@ -78,10 +78,10 @@ module controller(
logic [1:0] MemRWD, MemRWE;
logic JumpD;
logic BranchD, BranchE;
logic [1:0] ALUOpD;
logic [4:0] ALUControlD;
logic ALUOpD;
logic [2:0] ALUControlD;
logic ALUSrcAD, ALUSrcBD;
logic TargetSrcD, W64D, MulDivD;
logic ALUResultSrcD, W64D, MulDivD;
logic CSRZeroSrcD;
logic CSRReadD;
logic [1:0] AtomicD;
@ -92,12 +92,13 @@ module controller(
logic PrivilegedD, PrivilegedE;
logic InvalidateICacheE, FlushDCacheE;
logic [`CTRLW-1:0] ControlsD;
logic aluc3D;
logic SubArithD;
logic subD, sraD, sltD, sltuD;
logic BranchTakenE;
logic zeroE, ltE, ltuE;
logic unused;
logic BranchFlagE;
// Extract fields
assign OpD = InstrD[6:0];
assign Funct3D = InstrD[14:12];
@ -108,50 +109,50 @@ module controller(
generate
always_comb
case(OpD)
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRRead_Privileged_Fence_MulDiv_Atomic_Illegal
7'b0000000: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_00_1; // illegal instruction
7'b0000011: ControlsD = `CTRLW'b1_000_01_10_001_0_00_0_0_0_0_0_0_0_00_0; // lw
7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_00_0_0_0_0_0_0_0_00_0; // flw
7'b0001111: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_1_0_00_0; // fence
7'b0010011: ControlsD = `CTRLW'b1_000_01_00_000_0_10_0_0_0_0_0_0_0_00_0; // I-type ALU
7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_00_0_0_0_0_0_0_0_00_0; // auipc
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MulDiv_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
7'b0001111: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0; // fence
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_10_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_00_0_0_0_0_0_0_0_00_1; // non-implemented instruction
7'b0100011: ControlsD = `CTRLW'b0_001_01_01_000_0_00_0_0_0_0_0_0_0_00_0; // sw
7'b0100111: ControlsD = `CTRLW'b0_001_01_01_000_0_00_0_0_0_0_0_0_0_00_0; // fsw
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
7'b0101111: if (`A_SUPPORTED) begin
if (InstrD[31:27] == 5'b00010)
ControlsD = `CTRLW'b1_000_00_10_001_0_00_0_0_0_0_0_0_0_01_0; // lr
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_00_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
ControlsD = `CTRLW'b1_101_01_11_001_0_00_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_00_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_10_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_00_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_00_0_0_0_0_0_0_0_00_1; // non-implemented instruction
7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_11_0_0_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_10_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_00_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_00_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'b1010011: ControlsD = `CTRLW'b0_000_00_00_101_0_00_0_0_0_0_0_0_0_00_1; // FP
7'b1100011: ControlsD = `CTRLW'b0_010_00_00_000_1_01_0_0_0_0_0_0_0_00_0; // beq
7'b1100111: ControlsD = `CTRLW'b1_000_00_00_000_0_00_1_1_0_0_0_0_0_00_0; // jalr
7'b1101111: ControlsD = `CTRLW'b1_011_00_00_000_0_00_1_0_0_0_0_0_0_00_0; // jal
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 (Funct3D == 3'b000)
ControlsD = `CTRLW'b0_000_00_00_000_0_00_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_00_0_0_0_1_0_0_0_00_0; // csrs
default: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_00_1; // non-implemented instruction
ControlsD = `CTRLW'b1_000_00_00_010_0_0_0_0_0_1_0_0_0_00_0; // csrs
default: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction
endcase
endgenerate
@ -159,7 +160,7 @@ module controller(
// squash control signals if coming from an illegal compressed instruction
assign IllegalBaseInstrFaultD = ControlsD[0];
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
ResultSrcD, BranchD, ALUOpD, JumpD, TargetSrcD, W64D, CSRReadD,
ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, W64D, CSRReadD,
PrivilegedD, FenceD, MulDivD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD;
// *** move Privileged, CSRwrite?? Or move controller out of IEU into datapath and handle all instructions
@ -172,15 +173,19 @@ module controller(
assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]);
assign sraD = (Funct3D == 3'b101 & Funct7D[5]);
assign aluc3D = subD | sraD | sltD | sltuD; // TRUE for R-type subtracts and sra, slt, sltu
assign SubArithD = ALUOpD & (subD | sraD | sltD | sltuD); // TRUE for R-type subtracts and sra, slt, sltu
// assign SubArithD = aluc3D; // ***cleanup
always_comb
// *** replace all of this
assign ALUControlD = {W64D, SubArithD, ALUOpD};
/* always_comb
case(ALUOpD)
2'b00: ALUControlD = 5'b00000; // addition
2'b01: ALUControlD = 5'b01000; // subtraction
2'b11: ALUControlD = 5'b01110; // pass B through for lui
2'b01: ALUControlD = 5'b00000; // add for branch offset
// 2'b01: ALUControlD = 5'b01000; // subtraction
// 2'b11: ALUControlD = 5'b01110; // pass B through for lui ***no longer used
default: ALUControlD = {W64D, aluc3D, Funct3D}; // R-type instructions
endcase
endcase*/
// Fences
// Ordinary fence is presently a nop
@ -201,14 +206,15 @@ module controller(
flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD);
// Execute stage pipeline control register and logic
flopenrc #(29) controlregE(clk, reset, FlushE, ~StallE,
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, AtomicD, InvalidateICacheD, FlushDCacheD, InstrValidD},
{RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE});
flopenrc #(27) controlregE(clk, reset, FlushE, ~StallE,
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, AtomicD, InvalidateICacheD, FlushDCacheD, InstrValidD},
{RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE});
// Branch Logic
assign {zeroE, ltE, ltuE} = FlagsE;
always_comb
mux4 #(1) branchflagmux(zeroE, 1'b0, ltE, ltuE, Funct3E[2:1], BranchFlagE);
assign BranchTakenE = BranchFlagE ^ Funct3E[0];
/* always_comb
case(Funct3E)
3'b000: BranchTakenE = zeroE; // beq
3'b001: BranchTakenE = ~zeroE; // bne
@ -217,7 +223,7 @@ module controller(
3'b110: BranchTakenE = ltuE; // bltu
3'b111: BranchTakenE = ~ltuE; // bgeu
default: BranchTakenE = 1'b0; // undefined mode
endcase
endcase*/
assign PCSrcE = JumpE | BranchE & BranchTakenE;

View File

@ -30,12 +30,13 @@ module datapath (
// Decode stage signals
input logic [2:0] ImmSrcD,
input logic [31:0] InstrD,
input logic [2:0] Funct3E,
// Execute stage signals
input logic StallE, FlushE,
input logic [1:0] ForwardAE, ForwardBE,
input logic [4:0] ALUControlE,
input logic [2:0] ALUControlE,
input logic ALUSrcAE, ALUSrcBE,
input logic TargetSrcE,
input logic ALUResultSrcE,
input logic JumpE,
input logic IllegalFPUInstrE,
input logic [`XLEN-1:0] FWriteDataE,
@ -44,7 +45,6 @@ module datapath (
output logic [2:0] FlagsE,
output logic [`XLEN-1:0] PCTargetE,
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] SrcAE, SrcBE,
// Memory stage signals
input logic StallM, FlushM,
input logic FWriteIntM,
@ -75,11 +75,12 @@ module datapath (
logic [`XLEN-1:0] ExtImmE;
// logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, SrcAE2, SrcBE2; // *** MAde forwardedsrcae an output to get rid of a mux in the critical path.
logic [`XLEN-1:0] SrcAE, SrcBE;
logic [`XLEN-1:0] SrcAE2, SrcBE2;
logic [`XLEN-1:0] ALUResultE;
logic [`XLEN-1:0] ALUResultE, AltResultE, ALUPreResultE;
logic [`XLEN-1:0] WriteDataE;
logic [`XLEN-1:0] TargetBaseE;
logic [`XLEN-1:0] AddressE;
// Memory stage signals
logic [`XLEN-1:0] ALUResultM;
logic [`XLEN-1:0] ResultM;
@ -110,18 +111,18 @@ module datapath (
mux3 #(`XLEN) fbemux(RD2E, WriteDataW, ResultM, ForwardBE, ForwardedSrcBE);
mux2 #(`XLEN) writedatamux(ForwardedSrcBE, FWriteDataE, ~IllegalFPUInstrE, WriteDataE);
mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
mux2 #(`XLEN) srcamux2(SrcAE, PCLinkE, JumpE, SrcAE2);
mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ExtImmE, ALUSrcBE, SrcBE);
mux2 #(`XLEN) srcbmux2(SrcBE, {`XLEN{1'b0}}, JumpE, SrcBE2); // *** May be able to remove this mux.
alu #(`XLEN) alu(SrcAE2, SrcBE2, ALUControlE, ALUResultE, FlagsE);
mux2 #(`XLEN) targetsrcmux(PCE, SrcAE, TargetSrcE, TargetBaseE);
assign PCTargetE = ExtImmE + TargetBaseE;
alu #(`XLEN) alu(SrcAE, SrcBE, ALUControlE, Funct3E, ALUPreResultE, AddressE);
comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, FlagsE);
mux2 #(`XLEN) altresultmux(ExtImmE, PCLinkE, JumpE, AltResultE);
mux2 #(`XLEN) aluresultmux(ALUPreResultE, AltResultE, ALUResultSrcE, ALUResultE);
// Memory stage pipeline register
flopenrc #(`XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM);
flopenrc #(`XLEN) ALUResultMReg(clk, reset, FlushM, ~StallM, ALUResultE, ALUResultM);
assign MemAdrM = ALUResultM;
assign MemAdrE = ALUResultE;
assign MemAdrE = AddressE; // *** clean up this naming
assign PCTargetE = AddressE; // *** clean up this naming
flopenrc #(`XLEN) AddressNReg(clk, reset, FlushM, ~StallM, MemAdrE, MemAdrM);
flopenrc #(`XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, WriteDataE, WriteDataM);
flopenrc #(5) RdMEg(clk, reset, FlushM, ~StallM, RdE, RdM);
mux2 #(`XLEN) resultmuxM(ALUResultM, FIntResM, FWriteIntM, ResultM);

View File

@ -41,7 +41,7 @@ module ieu (
output logic MulDivE, 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
output logic [`XLEN-1:0] SrcAE, SrcBE,
// output logic [`XLEN-1:0] SrcAE, SrcBE,
input logic FWriteIntM,
// Memory stage interface
@ -76,10 +76,10 @@ module ieu (
logic [2:0] ImmSrcD;
logic [2:0] FlagsE;
logic [4:0] ALUControlE;
logic [2:0] ALUControlE;
logic ALUSrcAE, ALUSrcBE;
logic [2:0] ResultSrcW;
logic TargetSrcE;
logic ALUResultSrcE;
logic SCE;
logic [4:0] RdE;
@ -99,7 +99,7 @@ module ieu (
.StallE, .FlushE, .FlagsE,
.PCSrcE, // for datapath and Hazard Unit
.ALUControlE, .ALUSrcAE, .ALUSrcBE,
.TargetSrcE,
.ALUResultSrcE,
.MemReadE, .CSRReadE, // for Hazard Unit
.Funct3E, .MulDivE, .W64E,
.JumpE,
@ -124,12 +124,11 @@ module ieu (
.ImmSrcD, .InstrD,
// Execute stage signals
.StallE, .FlushE, .ForwardAE, .ForwardBE,
.ALUControlE, .ALUSrcAE, .ALUSrcBE,
.TargetSrcE, .JumpE, .IllegalFPUInstrE,
.ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE,
.ALUResultSrcE, .JumpE, .IllegalFPUInstrE,
.FWriteDataE, .PCE, .PCLinkE, .FlagsE,
.PCTargetE,
.ForwardedSrcAE, .ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
.SrcAE, .SrcBE,
// Memory stage signals
.StallM, .FlushM, .FWriteIntM, .FIntResM,
.SrcAM, .WriteDataM, .MemAdrM, .MemAdrE,

View File

@ -21,7 +21,8 @@
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
///////////////////////////////////////////
`include "wally-config.vh"
@ -84,7 +85,7 @@ module privileged (
logic [`XLEN-1:0] CauseM, NextFaultMtvalM;
logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW;
// logic [11:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW;
// logic [11:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW;
logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW;
logic uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM;
@ -111,8 +112,8 @@ module privileged (
///////////////////////////////////////////
// get bits of DELEG registers based on CAUSE
// assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[3:0]];
// assign sd = CauseM[`XLEN-1] ? SIDELEG_REGW[CauseM[3:0]] : SEDELEG_REGW[CauseM[3:0]]; // depricated
// assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[3:0]];
// assign sd = CauseM[`XLEN-1] ? SIDELEG_REGW[CauseM[3:0]] : SEDELEG_REGW[CauseM[3:0]]; // depricated
assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[`LOG_XLEN-1:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]];
assign sd = CauseM[`XLEN-1] ? SIDELEG_REGW[CauseM[`LOG_XLEN-1:0]] : SEDELEG_REGW[CauseM[`LOG_XLEN-1:0]]; // depricated
@ -143,15 +144,44 @@ module privileged (
///////////////////////////////////////////
// decode privileged instructions
///////////////////////////////////////////
privdec pmd(.InstrM(InstrM[31:20]), .*);
///////////////////////////////////////////
//privdec pmd(.InstrM(InstrM[31:20]),.*);
privdec pmd(.InstrM(InstrM[31:20]),
.PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM, .TrappedSRETM,
.PrivilegeModeW, .STATUS_TSR, .IllegalInstrFaultM,
.uretM, .sretM, .mretM, .ecallM, .ebreakM, .wfiM, .sfencevmaM);
///////////////////////////////////////////
// Control and Status Registers
///////////////////////////////////////////
csr csr(.*);
//csr csr(.*);
csr csr(.clk, .reset,
.FlushE, .FlushM, .FlushW,
.StallE, .StallM, .StallW,
.InstrM, .PCM, .SrcAM,
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM, .uretM,
.TimerIntM, .ExtIntM, .SwIntM,
.MTIME_CLINT, .MTIMECMP_CLINT,
.InstrValidM, .FRegWriteM, .LoadStallD,
.BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM,
.BPPredClassNonCFIWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess,
.NextPrivilegeModeM, .PrivilegeModeW,
.CauseM, .NextFaultMtvalM, .STATUS_MPP,
.STATUS_SPP, .STATUS_TSR,
.MEPC_REGW, .SEPC_REGW, .UEPC_REGW, .UTVEC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MEDELEG_REGW, .MIDELEG_REGW, .SEDELEG_REGW, .SIDELEG_REGW,
.SATP_REGW,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW,
.STATUS_MIE, .STATUS_SIE,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW,
.PMPCFG_ARRAY_REGW,
.PMPADDR_ARRAY_REGW,
.SetFflagsM,
.FRM_REGW,
.CSRReadValW,
.IllegalCSRAccessM);
///////////////////////////////////////////
// Extract exceptions by name and handle them
@ -188,12 +218,32 @@ module privileged (
flopenrc #(4) faultregM(clk, reset, FlushM, ~StallM,
{IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE, IllegalFPUInstrE},
{IllegalIEUInstrFaultM, InstrPageFaultM, InstrAccessFaultM, IllegalFPUInstrM});
// *** it should be possible to compbine some of these faults earlier to reduce module boundary crossings and save flops dh 5 july 2021
// *** it should be possible to combine some of these faults earlier to reduce module boundary crossings and save flops dh 5 july 2021
//trap trap(.*);
trap trap(.clk, .reset,
.InstrMisalignedFaultM, .InstrAccessFaultM, .IllegalInstrFaultM,
.BreakpointFaultM, .LoadMisalignedFaultM, .StoreMisalignedFaultM,
.LoadAccessFaultM, .StoreAccessFaultM, .EcallFaultM, .InstrPageFaultM,
.LoadPageFaultM, .StorePageFaultM,
.mretM, .sretM, .uretM,
.PrivilegeModeW, .NextPrivilegeModeM,
.MEPC_REGW, .SEPC_REGW, .UEPC_REGW, .UTVEC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW,
.STATUS_MIE, .STATUS_SIE,
.PCM,
.InstrMisalignedAdrM, .MemAdrM,
.InstrM,
.InstrValidM, .CommittedM,
.TrapM, .MTrapM, .STrapM, .UTrapM, .RetM,
.InterruptM,
.ExceptionM,
.PendingInterruptM,
.PrivilegedNextPCM, .CauseM, .NextFaultMtvalM);
trap trap(.*);
endmodule

View File

@ -60,7 +60,7 @@ module wallypipelinedhart (
logic CSRReadM, CSRWriteM, PrivilegedM;
logic [1:0] AtomicE;
logic [1:0] AtomicM;
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, SrcAE, SrcBE;
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE;
logic [`XLEN-1:0] SrcAM;
logic [2:0] Funct3E;
// logic [31:0] InstrF;
@ -211,7 +211,8 @@ module wallypipelinedhart (
.PCE, .PCLinkE, .FWriteIntE, .IllegalFPUInstrE,
.FWriteDataE, .PCTargetE, .MulDivE, .W64E,
.Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
.SrcAE, .SrcBE, .FWriteIntM,
//.SrcAE, .SrcBE,
.FWriteIntM,
// Memory stage interface
.SquashSCW, // from LSU
@ -364,7 +365,7 @@ module wallypipelinedhart (
.FRM_REGW, // Rounding mode from CSR
.InstrD, // instruction from IFU
.ReadDataW,// Read data from memory
.SrcAE, // Integer input being processed (from IEU)
.ForwardedSrcAE, // Integer input being processed (from IEU)
.StallE, .StallM, .StallW, // stall signals from HZU
.FlushE, .FlushM, .FlushW, // flush signals from HZU
.RdM, .RdW, // which FP register to write to (from IEU)

View File

@ -32,11 +32,12 @@
`include "wally-config.vh"
module wallypipelinedsoc (
input logic clk, reset_ext,
input logic clk, reset_ext,
output logic reset,
// AHB Lite Interface
// inputs from external memory
input logic [`AHBW-1:0] HRDATAEXT,
input logic HREADYEXT, HRESPEXT,
input logic [`AHBW-1:0] HRDATAEXT,
input logic HREADYEXT, HRESPEXT,
output logic HSELEXT,
// outputs to external memory, shared with uncore memory
output logic HCLK, HRESETn,
@ -62,7 +63,7 @@ module wallypipelinedsoc (
);
// Uncore signals
logic reset;
// logic reset;
logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore
logic HRESP;
logic TimerIntM, SwIntM; // from CLINT

View File

@ -118,6 +118,8 @@ module sdModel
reg [3:0] crcDat_in;
wire [15:0] crcDat_out [3:0];
integer sdModel_file_desc;
genvar i;
generate
for(i=0; i<4; i=i+1) begin:CRC_16_gen
@ -1050,8 +1052,6 @@ module sdModel
endcase // case (dataState)
end // always @ (negedge sdClk)
integer sdModel_file_desc;
initial
begin
sdModel_file_desc = $fopen("sd_model.log");

View File

@ -64,7 +64,10 @@ module testbench();
assign HREADYEXT = 1;
assign HRESPEXT = 0;
assign HRDATAEXT = 0;
wallypipelinedsoc dut(.*);
wallypipelinedsoc dut(.clk, .reset_ext, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
.HTRANS, .HMASTLOCK, .HREADY, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
// Track names of instructions
logic [31:0] InstrW;
flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);

View File

@ -72,29 +72,10 @@ module testbench();
assign HREADYEXT = 1;
assign HRESPEXT = 0;
assign HRDATAEXT = 0;
wallypipelinedsoc dut(.clk, .reset_ext,
.HRDATAEXT,
.HREADYEXT, .HRESPEXT,
.HSELEXT,
.HCLK, .HRESETn,
.HADDR,
.HWDATA,
.HWRITE,
.HSIZE,
.HBURST,
.HPROT,
.HTRANS,
.HMASTLOCK,
.HREADY,
.GPIOPinsIn,
.GPIOPinsOut, .GPIOPinsEn,
.UARTSin,
.UARTSout,
.SDCCmdIn,
.SDCCmdOut,
.SDCCmdOE,
.SDCDatIn,
.SDCCLK);
wallypipelinedsoc dut(.clk, .reset_ext, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
.HTRANS, .HMASTLOCK, .HREADY, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
logic [31:0] InstrW;
flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);

View File

@ -596,13 +596,14 @@ string tests32f[] = '{
assign UARTSin = 1;
dtim #(.BASE(`TIM_BASE), .RANGE(`TIM_RANGE))
dtim (.*, .HSELTim(HSELEXT),
.HREADTim(HRDATAEXT),
.HREADYTim(HREADYEXT),
.HRESPTim(HRESPEXT));
dtim (.HCLK, .HRESETn, .HADDR, .HWRITE, .HTRANS, .HWDATA, .HSELTim(HSELEXT),
.HREADTim(HRDATAEXT), .HREADYTim(HREADYEXT), .HRESPTim(HRESPEXT));
wallypipelinedsocwrapper dut(.*);
wallypipelinedsocwrapper dut(.clk, .reset_ext, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
.HTRANS, .HMASTLOCK, .HREADY, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
// Track names of instructions
instrTrackerTB it(clk, reset, dut.wallypipelinedsoc.hart.ieu.dp.FlushE,

View File

@ -91,7 +91,10 @@ module testbench();
assign HRESPEXT = 0;
assign HRDATAEXT = 0;
wallypipelinedsoc dut(.*);
wallypipelinedsoc dut(.clk, .reset_ext, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
.HTRANS, .HMASTLOCK, .HREADY, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);
// Track names of instructions
instrTrackerTBPriv it(clk, reset, dut.hart.ieu.dp.FlushE,

View File

@ -146,7 +146,10 @@ logic [3:0] dummy;
assign HRESPEXT = 0;
assign HRDATAEXT = 0;
wallypipelinedsoc dut(.*);
wallypipelinedsoc dut(.clk, .reset_ext, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
.HTRANS, .HMASTLOCK, .HREADY, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
// Track names of instructions
instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE,

View File

@ -586,6 +586,7 @@ string imperas32f[] = '{
string arch64i[] = '{
`RISCVARCHTEST,
"rv64i_m/I/beq-01", "47010",
"rv64i_m/I/add-01", "9010",
"rv64i_m/I/addi-01", "6010",
"rv64i_m/I/addiw-01", "6010",