mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main
This commit is contained in:
commit
b9c8b808ea
@ -1 +1 @@
|
|||||||
Subproject commit be67c99bd461742aa1c100bcc0732657faae2230
|
Subproject commit 84d043817f75f752c9873326475e11f16e3a6f7c
|
@ -1 +1 @@
|
|||||||
Subproject commit d22b280198e74b871e04fc0ddb622fb825fdae49
|
Subproject commit ddcfa6cc3d80818140a459e590296c3079c5a3ec
|
@ -1,2 +1,2 @@
|
|||||||
vsim -do "do wally-pipelined.do rv32g arch32f"
|
vsim -do "do wally-pipelined.do rv64g arch64i"
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
vsim -c <<!
|
vsim -c <<!
|
||||||
do wally-pipelined-batch.do rv32g arch32f
|
do wally-pipelined-batch.do rv64g arch64i
|
||||||
!
|
!
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
// *** this should probably be moved into the LSU because it is instantiated in the D$
|
||||||
|
|
||||||
module amoalu (
|
module amoalu (
|
||||||
input logic [`XLEN-1:0] srca, srcb,
|
input logic [`XLEN-1:0] srca, srcb,
|
||||||
input logic [6:0] funct,
|
input logic [6:0] funct,
|
||||||
|
@ -10,7 +10,7 @@ module fcvt (
|
|||||||
input logic XInfE, // is X infinity
|
input logic XInfE, // is X infinity
|
||||||
input logic XDenormE, // is X denormalized
|
input logic XDenormE, // is X denormalized
|
||||||
input logic [10:0] BiasE, // bias - depends on precision (max exponent/2)
|
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] 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 [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
|
input logic FmtE, // precision 1 = double 0 = single
|
||||||
@ -73,7 +73,7 @@ module fcvt (
|
|||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// position the input in the most significant bits
|
// 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
|
// make the integer positive
|
||||||
assign PosInt = IntIn[64-1]&~FOpCtrlE[1] ? -IntIn : IntIn;
|
assign PosInt = IntIn[64-1]&~FOpCtrlE[1] ? -IntIn : IntIn;
|
||||||
// determine the integer's sign
|
// determine the integer's sign
|
||||||
|
@ -30,7 +30,7 @@ module fpu (
|
|||||||
input logic [2:0] FRM_REGW, // Rounding mode from CSR
|
input logic [2:0] FRM_REGW, // Rounding mode from CSR
|
||||||
input logic [31:0] InstrD, // instruction from IFU
|
input logic [31:0] InstrD, // instruction from IFU
|
||||||
input logic [`XLEN-1:0] ReadDataW,// Read data from memory
|
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 StallE, StallM, StallW, // stall signals from HZU
|
||||||
input logic FlushE, FlushM, FlushW, // flush 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)
|
input logic [4:0] RdM, RdW, // which FP register to write to (from IEU)
|
||||||
@ -229,7 +229,7 @@ module fpu (
|
|||||||
.XSNaNE, .ClassResE);
|
.XSNaNE, .ClassResE);
|
||||||
|
|
||||||
// Convert
|
// 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);
|
.CvtResE, .CvtFlgE);
|
||||||
|
|
||||||
// data to be stored in memory - to IEU
|
// data to be stored in memory - to IEU
|
||||||
@ -238,7 +238,7 @@ module fpu (
|
|||||||
assign FWriteDataE = FSrcYE[`XLEN-1:0];
|
assign FWriteDataE = FSrcYE[`XLEN-1:0];
|
||||||
|
|
||||||
// Align SrcA to MSB when single precicion
|
// 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
|
// select a result that may be written to the FP register
|
||||||
mux5 #(64) FResMux(AlignedSrcAE, SgnResE, CmpResE, CvtResE, CvtFpResE, FResSelE, FResE);
|
mux5 #(64) FResMux(AlignedSrcAE, SgnResE, CmpResE, CvtResE, CvtFpResE, FResSelE, FResE);
|
||||||
|
@ -27,62 +27,66 @@
|
|||||||
|
|
||||||
module alu #(parameter WIDTH=32) (
|
module alu #(parameter WIDTH=32) (
|
||||||
input logic [WIDTH-1:0] a, b,
|
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 [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 [WIDTH-1:0] condinvb, sumtrunc, shift, slt, sltu, bor;
|
||||||
logic right, arith, w64;
|
logic right; //, arith, w64;
|
||||||
logic carry, zero, neg;
|
logic carry, neg;
|
||||||
logic lt, ltu;
|
logic lt, ltu;
|
||||||
logic overflow;
|
logic overflow;
|
||||||
|
logic W64, SubArith, ALUOp;
|
||||||
|
|
||||||
|
assign {W64, SubArith, ALUOp} = ALUControl;
|
||||||
// addition
|
// addition
|
||||||
assign condinvb = alucontrol[3] ? ~b : b;
|
// *** make sure condinvb is only applied when it should be (sub, slt/sltu)
|
||||||
assign {carry, presum} = a + condinvb + {{(WIDTH-1){1'b0}},alucontrol[3]};
|
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
|
// support W-type RV64I ADDW/SUBW/ADDIW that sign-extend 32-bit result to 64 bits
|
||||||
generate
|
generate
|
||||||
if (WIDTH==64)
|
if (WIDTH==64)
|
||||||
assign sum = w64 ? {{32{presum[31]}}, presum[31:0]} : presum;
|
assign sumtrunc = W64 ? {{32{sum[31]}}, sum[31:0]} : sum;
|
||||||
else
|
else
|
||||||
assign sum = presum;
|
assign sumtrunc = sum;
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
// shifts
|
// shifts
|
||||||
assign arith = alucontrol[3]; // sra
|
// assign arith = alucontrol[3]; // sra
|
||||||
assign w64 = alucontrol[4];
|
// assign w64 = alucontrol[4];
|
||||||
assign right = (alucontrol[2:0] == 3'b101); // sra or srl
|
assign right = (Funct3[2:0] == 3'b101); // sra or srl
|
||||||
shifter sh(a, b[5:0], right, arith, w64, shift);
|
shifter sh(a, b[5:0], right, SubArith, W64, shift);
|
||||||
|
|
||||||
// OR optionally passes zero when ALUControl[3] is set, supporting lui
|
// 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
|
// condition code flags based on add/subtract output
|
||||||
assign zero = (sum == 0);
|
|
||||||
assign neg = sum[WIDTH-1];
|
assign neg = sum[WIDTH-1];
|
||||||
// overflow occurs when the numbers being added have the same sign
|
// overflow occurs when the numbers being added have the same sign
|
||||||
// and the result has the opposite sign
|
// and the result has the opposite sign
|
||||||
assign overflow = (a[WIDTH-1] ~^ condinvb[WIDTH-1]) & (a[WIDTH-1] ^ sum[WIDTH-1]);
|
assign overflow = (a[WIDTH-1] ~^ condinvb[WIDTH-1]) & (a[WIDTH-1] ^ sum[WIDTH-1]);
|
||||||
assign lt = neg ^ overflow;
|
assign lt = neg ^ overflow;
|
||||||
assign ltu = ~carry;
|
assign ltu = ~carry;
|
||||||
assign flags = {zero, lt, ltu};
|
|
||||||
|
|
||||||
// slt
|
// slt
|
||||||
assign slt = {{(WIDTH-1){1'b0}}, lt};
|
assign slt = {{(WIDTH-1){1'b0}}, lt};
|
||||||
assign sltu = {{(WIDTH-1){1'b0}}, ltu};
|
assign sltu = {{(WIDTH-1){1'b0}}, ltu};
|
||||||
|
|
||||||
always_comb
|
always_comb
|
||||||
case (alucontrol[2:0])
|
if (~ALUOp) result = sumtrunc;
|
||||||
3'b000: result = sum; // add or sub
|
else
|
||||||
|
case (Funct3)
|
||||||
|
3'b000: result = sumtrunc; // add or sub
|
||||||
3'b001: result = shift; // sll
|
3'b001: result = shift; // sll
|
||||||
3'b010: result = slt; // slt
|
3'b010: result = slt; // slt
|
||||||
3'b011: result = sltu; // sltu
|
3'b011: result = sltu; // sltu
|
||||||
3'b100: result = a ^ b; // xor
|
3'b100: result = a ^ b; // xor
|
||||||
3'b101: result = shift; // sra or srl
|
3'b101: result = shift; // sra or srl
|
||||||
3'b110: result = bor; // or / pass through input b for lui
|
3'b110: result = a | b; // or
|
||||||
3'b111: result = a & b; // and
|
3'b111: result = a & b; // and
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
52
wally-pipelined/src/ieu/comparator.sv
Normal file
52
wally-pipelined/src/ieu/comparator.sv
Normal 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
|
||||||
|
|
@ -38,9 +38,9 @@ module controller(
|
|||||||
input logic StallE, FlushE,
|
input logic StallE, FlushE,
|
||||||
input logic [2:0] FlagsE,
|
input logic [2:0] FlagsE,
|
||||||
output logic PCSrcE, // for datapath and Hazard Unit
|
output logic PCSrcE, // for datapath and Hazard Unit
|
||||||
output logic [4:0] ALUControlE,
|
output logic [2:0] ALUControlE,
|
||||||
output logic ALUSrcAE, ALUSrcBE,
|
output logic ALUSrcAE, ALUSrcBE,
|
||||||
output logic TargetSrcE,
|
output logic ALUResultSrcE,
|
||||||
output logic MemReadE, CSRReadE, // for Hazard Unit
|
output logic MemReadE, CSRReadE, // for Hazard Unit
|
||||||
output logic [2:0] Funct3E,
|
output logic [2:0] Funct3E,
|
||||||
output logic MulDivE, W64E,
|
output logic MulDivE, W64E,
|
||||||
@ -70,7 +70,7 @@ module controller(
|
|||||||
logic [6:0] Funct7D;
|
logic [6:0] Funct7D;
|
||||||
logic [4:0] Rs1D;
|
logic [4:0] Rs1D;
|
||||||
|
|
||||||
`define CTRLW 24
|
`define CTRLW 23
|
||||||
|
|
||||||
// pipelined control signals
|
// pipelined control signals
|
||||||
logic RegWriteD, RegWriteE;
|
logic RegWriteD, RegWriteE;
|
||||||
@ -78,10 +78,10 @@ module controller(
|
|||||||
logic [1:0] MemRWD, MemRWE;
|
logic [1:0] MemRWD, MemRWE;
|
||||||
logic JumpD;
|
logic JumpD;
|
||||||
logic BranchD, BranchE;
|
logic BranchD, BranchE;
|
||||||
logic [1:0] ALUOpD;
|
logic ALUOpD;
|
||||||
logic [4:0] ALUControlD;
|
logic [2:0] ALUControlD;
|
||||||
logic ALUSrcAD, ALUSrcBD;
|
logic ALUSrcAD, ALUSrcBD;
|
||||||
logic TargetSrcD, W64D, MulDivD;
|
logic ALUResultSrcD, W64D, MulDivD;
|
||||||
logic CSRZeroSrcD;
|
logic CSRZeroSrcD;
|
||||||
logic CSRReadD;
|
logic CSRReadD;
|
||||||
logic [1:0] AtomicD;
|
logic [1:0] AtomicD;
|
||||||
@ -92,11 +92,12 @@ module controller(
|
|||||||
logic PrivilegedD, PrivilegedE;
|
logic PrivilegedD, PrivilegedE;
|
||||||
logic InvalidateICacheE, FlushDCacheE;
|
logic InvalidateICacheE, FlushDCacheE;
|
||||||
logic [`CTRLW-1:0] ControlsD;
|
logic [`CTRLW-1:0] ControlsD;
|
||||||
logic aluc3D;
|
logic SubArithD;
|
||||||
logic subD, sraD, sltD, sltuD;
|
logic subD, sraD, sltD, sltuD;
|
||||||
logic BranchTakenE;
|
logic BranchTakenE;
|
||||||
logic zeroE, ltE, ltuE;
|
logic zeroE, ltE, ltuE;
|
||||||
logic unused;
|
logic unused;
|
||||||
|
logic BranchFlagE;
|
||||||
|
|
||||||
// Extract fields
|
// Extract fields
|
||||||
assign OpD = InstrD[6:0];
|
assign OpD = InstrD[6:0];
|
||||||
@ -108,50 +109,50 @@ module controller(
|
|||||||
generate
|
generate
|
||||||
always_comb
|
always_comb
|
||||||
case(OpD)
|
case(OpD)
|
||||||
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRRead_Privileged_Fence_MulDiv_Atomic_Illegal
|
// 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_00_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_00_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_00_0_0_0_0_0_0_0_00_0; // flw
|
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_00_0_0_0_0_0_1_0_00_0; // fence
|
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_10_0_0_0_0_0_0_0_00_0; // I-type ALU
|
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_00_0_0_0_0_0_0_0_00_0; // auipc
|
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)
|
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
|
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'b0100011: ControlsD = `CTRLW'b0_001_01_01_000_0_00_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_00_0_0_0_0_0_0_0_00_0; // fsw
|
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
|
7'b0101111: if (`A_SUPPORTED) begin
|
||||||
if (InstrD[31:27] == 5'b00010)
|
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)
|
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
|
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
|
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)
|
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)
|
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
|
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'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_11_0_0_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_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)
|
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
|
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'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'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_00_00_000_0_00_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_00_00_000_0_00_1_0_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
|
||||||
7'b1110011: if (Funct3D == 3'b000)
|
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
|
else
|
||||||
ControlsD = `CTRLW'b1_000_00_00_010_0_00_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
|
||||||
default: ControlsD = `CTRLW'b0_000_00_00_000_0_00_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
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
@ -159,7 +160,7 @@ module controller(
|
|||||||
// squash control signals if coming from an illegal compressed instruction
|
// squash control signals if coming from an illegal compressed instruction
|
||||||
assign IllegalBaseInstrFaultD = ControlsD[0];
|
assign IllegalBaseInstrFaultD = ControlsD[0];
|
||||||
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
|
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;
|
PrivilegedD, FenceD, MulDivD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD;
|
||||||
// *** move Privileged, CSRwrite?? Or move controller out of IEU into datapath and handle all instructions
|
// *** 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 subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]);
|
||||||
assign sraD = (Funct3D == 3'b101 & Funct7D[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)
|
case(ALUOpD)
|
||||||
2'b00: ALUControlD = 5'b00000; // addition
|
2'b00: ALUControlD = 5'b00000; // addition
|
||||||
2'b01: ALUControlD = 5'b01000; // subtraction
|
2'b01: ALUControlD = 5'b00000; // add for branch offset
|
||||||
2'b11: ALUControlD = 5'b01110; // pass B through for lui
|
// 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
|
default: ALUControlD = {W64D, aluc3D, Funct3D}; // R-type instructions
|
||||||
endcase
|
endcase*/
|
||||||
|
|
||||||
// Fences
|
// Fences
|
||||||
// Ordinary fence is presently a nop
|
// Ordinary fence is presently a nop
|
||||||
@ -201,14 +206,15 @@ module controller(
|
|||||||
flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD);
|
flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD);
|
||||||
|
|
||||||
// Execute stage pipeline control register and logic
|
// Execute stage pipeline control register and logic
|
||||||
flopenrc #(29) controlregE(clk, reset, FlushE, ~StallE,
|
flopenrc #(27) controlregE(clk, reset, FlushE, ~StallE,
|
||||||
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, AtomicD, InvalidateICacheD, FlushDCacheD, InstrValidD},
|
{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, TargetSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE});
|
{RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE});
|
||||||
|
|
||||||
// Branch Logic
|
// Branch Logic
|
||||||
assign {zeroE, ltE, ltuE} = FlagsE;
|
assign {zeroE, ltE, ltuE} = FlagsE;
|
||||||
|
mux4 #(1) branchflagmux(zeroE, 1'b0, ltE, ltuE, Funct3E[2:1], BranchFlagE);
|
||||||
always_comb
|
assign BranchTakenE = BranchFlagE ^ Funct3E[0];
|
||||||
|
/* always_comb
|
||||||
case(Funct3E)
|
case(Funct3E)
|
||||||
3'b000: BranchTakenE = zeroE; // beq
|
3'b000: BranchTakenE = zeroE; // beq
|
||||||
3'b001: BranchTakenE = ~zeroE; // bne
|
3'b001: BranchTakenE = ~zeroE; // bne
|
||||||
@ -217,7 +223,7 @@ module controller(
|
|||||||
3'b110: BranchTakenE = ltuE; // bltu
|
3'b110: BranchTakenE = ltuE; // bltu
|
||||||
3'b111: BranchTakenE = ~ltuE; // bgeu
|
3'b111: BranchTakenE = ~ltuE; // bgeu
|
||||||
default: BranchTakenE = 1'b0; // undefined mode
|
default: BranchTakenE = 1'b0; // undefined mode
|
||||||
endcase
|
endcase*/
|
||||||
|
|
||||||
assign PCSrcE = JumpE | BranchE & BranchTakenE;
|
assign PCSrcE = JumpE | BranchE & BranchTakenE;
|
||||||
|
|
||||||
|
@ -30,12 +30,13 @@ module datapath (
|
|||||||
// Decode stage signals
|
// Decode stage signals
|
||||||
input logic [2:0] ImmSrcD,
|
input logic [2:0] ImmSrcD,
|
||||||
input logic [31:0] InstrD,
|
input logic [31:0] InstrD,
|
||||||
|
input logic [2:0] Funct3E,
|
||||||
// Execute stage signals
|
// Execute stage signals
|
||||||
input logic StallE, FlushE,
|
input logic StallE, FlushE,
|
||||||
input logic [1:0] ForwardAE, ForwardBE,
|
input logic [1:0] ForwardAE, ForwardBE,
|
||||||
input logic [4:0] ALUControlE,
|
input logic [2:0] ALUControlE,
|
||||||
input logic ALUSrcAE, ALUSrcBE,
|
input logic ALUSrcAE, ALUSrcBE,
|
||||||
input logic TargetSrcE,
|
input logic ALUResultSrcE,
|
||||||
input logic JumpE,
|
input logic JumpE,
|
||||||
input logic IllegalFPUInstrE,
|
input logic IllegalFPUInstrE,
|
||||||
input logic [`XLEN-1:0] FWriteDataE,
|
input logic [`XLEN-1:0] FWriteDataE,
|
||||||
@ -44,7 +45,6 @@ module datapath (
|
|||||||
output logic [2:0] FlagsE,
|
output logic [2:0] FlagsE,
|
||||||
output logic [`XLEN-1:0] PCTargetE,
|
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] 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
|
// Memory stage signals
|
||||||
input logic StallM, FlushM,
|
input logic StallM, FlushM,
|
||||||
input logic FWriteIntM,
|
input logic FWriteIntM,
|
||||||
@ -75,11 +75,12 @@ module datapath (
|
|||||||
logic [`XLEN-1:0] ExtImmE;
|
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] 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] SrcAE2, SrcBE2;
|
||||||
|
|
||||||
logic [`XLEN-1:0] ALUResultE;
|
logic [`XLEN-1:0] ALUResultE, AltResultE, ALUPreResultE;
|
||||||
logic [`XLEN-1:0] WriteDataE;
|
logic [`XLEN-1:0] WriteDataE;
|
||||||
logic [`XLEN-1:0] TargetBaseE;
|
logic [`XLEN-1:0] AddressE;
|
||||||
// Memory stage signals
|
// Memory stage signals
|
||||||
logic [`XLEN-1:0] ALUResultM;
|
logic [`XLEN-1:0] ALUResultM;
|
||||||
logic [`XLEN-1:0] ResultM;
|
logic [`XLEN-1:0] ResultM;
|
||||||
@ -110,18 +111,18 @@ module datapath (
|
|||||||
mux3 #(`XLEN) fbemux(RD2E, WriteDataW, ResultM, ForwardBE, ForwardedSrcBE);
|
mux3 #(`XLEN) fbemux(RD2E, WriteDataW, ResultM, ForwardBE, ForwardedSrcBE);
|
||||||
mux2 #(`XLEN) writedatamux(ForwardedSrcBE, FWriteDataE, ~IllegalFPUInstrE, WriteDataE);
|
mux2 #(`XLEN) writedatamux(ForwardedSrcBE, FWriteDataE, ~IllegalFPUInstrE, WriteDataE);
|
||||||
mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
|
mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
|
||||||
mux2 #(`XLEN) srcamux2(SrcAE, PCLinkE, JumpE, SrcAE2);
|
|
||||||
mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ExtImmE, ALUSrcBE, SrcBE);
|
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(SrcAE, SrcBE, ALUControlE, Funct3E, ALUPreResultE, AddressE);
|
||||||
alu #(`XLEN) alu(SrcAE2, SrcBE2, ALUControlE, ALUResultE, FlagsE);
|
comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, FlagsE);
|
||||||
mux2 #(`XLEN) targetsrcmux(PCE, SrcAE, TargetSrcE, TargetBaseE);
|
mux2 #(`XLEN) altresultmux(ExtImmE, PCLinkE, JumpE, AltResultE);
|
||||||
assign PCTargetE = ExtImmE + TargetBaseE;
|
mux2 #(`XLEN) aluresultmux(ALUPreResultE, AltResultE, ALUResultSrcE, ALUResultE);
|
||||||
|
|
||||||
// Memory stage pipeline register
|
// Memory stage pipeline register
|
||||||
flopenrc #(`XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM);
|
flopenrc #(`XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM);
|
||||||
flopenrc #(`XLEN) ALUResultMReg(clk, reset, FlushM, ~StallM, ALUResultE, ALUResultM);
|
flopenrc #(`XLEN) ALUResultMReg(clk, reset, FlushM, ~StallM, ALUResultE, ALUResultM);
|
||||||
assign MemAdrM = ALUResultM;
|
assign MemAdrE = AddressE; // *** clean up this naming
|
||||||
assign MemAdrE = ALUResultE;
|
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 #(`XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, WriteDataE, WriteDataM);
|
||||||
flopenrc #(5) RdMEg(clk, reset, FlushM, ~StallM, RdE, RdM);
|
flopenrc #(5) RdMEg(clk, reset, FlushM, ~StallM, RdE, RdM);
|
||||||
mux2 #(`XLEN) resultmuxM(ALUResultM, FIntResM, FWriteIntM, ResultM);
|
mux2 #(`XLEN) resultmuxM(ALUResultM, FIntResM, FWriteIntM, ResultM);
|
||||||
|
@ -41,7 +41,7 @@ module ieu (
|
|||||||
output logic MulDivE, W64E,
|
output logic MulDivE, W64E,
|
||||||
output logic [2:0] Funct3E,
|
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] 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,
|
input logic FWriteIntM,
|
||||||
|
|
||||||
// Memory stage interface
|
// Memory stage interface
|
||||||
@ -76,10 +76,10 @@ module ieu (
|
|||||||
|
|
||||||
logic [2:0] ImmSrcD;
|
logic [2:0] ImmSrcD;
|
||||||
logic [2:0] FlagsE;
|
logic [2:0] FlagsE;
|
||||||
logic [4:0] ALUControlE;
|
logic [2:0] ALUControlE;
|
||||||
logic ALUSrcAE, ALUSrcBE;
|
logic ALUSrcAE, ALUSrcBE;
|
||||||
logic [2:0] ResultSrcW;
|
logic [2:0] ResultSrcW;
|
||||||
logic TargetSrcE;
|
logic ALUResultSrcE;
|
||||||
logic SCE;
|
logic SCE;
|
||||||
logic [4:0] RdE;
|
logic [4:0] RdE;
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ module ieu (
|
|||||||
.StallE, .FlushE, .FlagsE,
|
.StallE, .FlushE, .FlagsE,
|
||||||
.PCSrcE, // for datapath and Hazard Unit
|
.PCSrcE, // for datapath and Hazard Unit
|
||||||
.ALUControlE, .ALUSrcAE, .ALUSrcBE,
|
.ALUControlE, .ALUSrcAE, .ALUSrcBE,
|
||||||
.TargetSrcE,
|
.ALUResultSrcE,
|
||||||
.MemReadE, .CSRReadE, // for Hazard Unit
|
.MemReadE, .CSRReadE, // for Hazard Unit
|
||||||
.Funct3E, .MulDivE, .W64E,
|
.Funct3E, .MulDivE, .W64E,
|
||||||
.JumpE,
|
.JumpE,
|
||||||
@ -124,12 +124,11 @@ module ieu (
|
|||||||
.ImmSrcD, .InstrD,
|
.ImmSrcD, .InstrD,
|
||||||
// Execute stage signals
|
// Execute stage signals
|
||||||
.StallE, .FlushE, .ForwardAE, .ForwardBE,
|
.StallE, .FlushE, .ForwardAE, .ForwardBE,
|
||||||
.ALUControlE, .ALUSrcAE, .ALUSrcBE,
|
.ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE,
|
||||||
.TargetSrcE, .JumpE, .IllegalFPUInstrE,
|
.ALUResultSrcE, .JumpE, .IllegalFPUInstrE,
|
||||||
.FWriteDataE, .PCE, .PCLinkE, .FlagsE,
|
.FWriteDataE, .PCE, .PCLinkE, .FlagsE,
|
||||||
.PCTargetE,
|
.PCTargetE,
|
||||||
.ForwardedSrcAE, .ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
.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
|
// Memory stage signals
|
||||||
.StallM, .FlushM, .FWriteIntM, .FIntResM,
|
.StallM, .FlushM, .FWriteIntM, .FIntResM,
|
||||||
.SrcAM, .WriteDataM, .MemAdrM, .MemAdrE,
|
.SrcAM, .WriteDataM, .MemAdrM, .MemAdrE,
|
||||||
|
@ -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
|
// 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
|
// 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
|
// 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"
|
`include "wally-config.vh"
|
||||||
@ -143,15 +144,44 @@ module privileged (
|
|||||||
|
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// decode privileged instructions
|
// 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
|
// 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
|
// Extract exceptions by name and handle them
|
||||||
@ -188,12 +218,32 @@ module privileged (
|
|||||||
flopenrc #(4) faultregM(clk, reset, FlushM, ~StallM,
|
flopenrc #(4) faultregM(clk, reset, FlushM, ~StallM,
|
||||||
{IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE, IllegalFPUInstrE},
|
{IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE, IllegalFPUInstrE},
|
||||||
{IllegalIEUInstrFaultM, InstrPageFaultM, InstrAccessFaultM, IllegalFPUInstrM});
|
{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
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ module wallypipelinedhart (
|
|||||||
logic CSRReadM, CSRWriteM, PrivilegedM;
|
logic CSRReadM, CSRWriteM, PrivilegedM;
|
||||||
logic [1:0] AtomicE;
|
logic [1:0] AtomicE;
|
||||||
logic [1:0] AtomicM;
|
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 [`XLEN-1:0] SrcAM;
|
||||||
logic [2:0] Funct3E;
|
logic [2:0] Funct3E;
|
||||||
// logic [31:0] InstrF;
|
// logic [31:0] InstrF;
|
||||||
@ -211,7 +211,8 @@ module wallypipelinedhart (
|
|||||||
.PCE, .PCLinkE, .FWriteIntE, .IllegalFPUInstrE,
|
.PCE, .PCLinkE, .FWriteIntE, .IllegalFPUInstrE,
|
||||||
.FWriteDataE, .PCTargetE, .MulDivE, .W64E,
|
.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
|
.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
|
// Memory stage interface
|
||||||
.SquashSCW, // from LSU
|
.SquashSCW, // from LSU
|
||||||
@ -364,7 +365,7 @@ module wallypipelinedhart (
|
|||||||
.FRM_REGW, // Rounding mode from CSR
|
.FRM_REGW, // Rounding mode from CSR
|
||||||
.InstrD, // instruction from IFU
|
.InstrD, // instruction from IFU
|
||||||
.ReadDataW,// Read data from memory
|
.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
|
.StallE, .StallM, .StallW, // stall signals from HZU
|
||||||
.FlushE, .FlushM, .FlushW, // flush signals from HZU
|
.FlushE, .FlushM, .FlushW, // flush signals from HZU
|
||||||
.RdM, .RdW, // which FP register to write to (from IEU)
|
.RdM, .RdW, // which FP register to write to (from IEU)
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
module wallypipelinedsoc (
|
module wallypipelinedsoc (
|
||||||
input logic clk, reset_ext,
|
input logic clk, reset_ext,
|
||||||
|
output logic reset,
|
||||||
// AHB Lite Interface
|
// AHB Lite Interface
|
||||||
// inputs from external memory
|
// inputs from external memory
|
||||||
input logic [`AHBW-1:0] HRDATAEXT,
|
input logic [`AHBW-1:0] HRDATAEXT,
|
||||||
@ -62,7 +63,7 @@ module wallypipelinedsoc (
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Uncore signals
|
// Uncore signals
|
||||||
logic reset;
|
// logic reset;
|
||||||
logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore
|
logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore
|
||||||
logic HRESP;
|
logic HRESP;
|
||||||
logic TimerIntM, SwIntM; // from CLINT
|
logic TimerIntM, SwIntM; // from CLINT
|
||||||
|
@ -118,6 +118,8 @@ module sdModel
|
|||||||
reg [3:0] crcDat_in;
|
reg [3:0] crcDat_in;
|
||||||
wire [15:0] crcDat_out [3:0];
|
wire [15:0] crcDat_out [3:0];
|
||||||
|
|
||||||
|
integer sdModel_file_desc;
|
||||||
|
|
||||||
genvar i;
|
genvar i;
|
||||||
generate
|
generate
|
||||||
for(i=0; i<4; i=i+1) begin:CRC_16_gen
|
for(i=0; i<4; i=i+1) begin:CRC_16_gen
|
||||||
@ -1050,8 +1052,6 @@ module sdModel
|
|||||||
endcase // case (dataState)
|
endcase // case (dataState)
|
||||||
end // always @ (negedge sdClk)
|
end // always @ (negedge sdClk)
|
||||||
|
|
||||||
integer sdModel_file_desc;
|
|
||||||
|
|
||||||
initial
|
initial
|
||||||
begin
|
begin
|
||||||
sdModel_file_desc = $fopen("sd_model.log");
|
sdModel_file_desc = $fopen("sd_model.log");
|
||||||
|
@ -64,7 +64,10 @@ module testbench();
|
|||||||
assign HREADYEXT = 1;
|
assign HREADYEXT = 1;
|
||||||
assign HRESPEXT = 0;
|
assign HRESPEXT = 0;
|
||||||
assign HRDATAEXT = 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
|
// Track names of instructions
|
||||||
logic [31:0] InstrW;
|
logic [31:0] InstrW;
|
||||||
flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);
|
flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);
|
||||||
|
@ -72,29 +72,10 @@ module testbench();
|
|||||||
assign HREADYEXT = 1;
|
assign HREADYEXT = 1;
|
||||||
assign HRESPEXT = 0;
|
assign HRESPEXT = 0;
|
||||||
assign HRDATAEXT = 0;
|
assign HRDATAEXT = 0;
|
||||||
wallypipelinedsoc dut(.clk, .reset_ext,
|
wallypipelinedsoc dut(.clk, .reset_ext, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
||||||
.HRDATAEXT,
|
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
|
||||||
.HREADYEXT, .HRESPEXT,
|
.HTRANS, .HMASTLOCK, .HREADY, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
|
||||||
.HSELEXT,
|
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
|
||||||
.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;
|
logic [31:0] InstrW;
|
||||||
flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);
|
flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);
|
||||||
|
@ -596,13 +596,14 @@ string tests32f[] = '{
|
|||||||
assign UARTSin = 1;
|
assign UARTSin = 1;
|
||||||
|
|
||||||
dtim #(.BASE(`TIM_BASE), .RANGE(`TIM_RANGE))
|
dtim #(.BASE(`TIM_BASE), .RANGE(`TIM_RANGE))
|
||||||
dtim (.*, .HSELTim(HSELEXT),
|
dtim (.HCLK, .HRESETn, .HADDR, .HWRITE, .HTRANS, .HWDATA, .HSELTim(HSELEXT),
|
||||||
.HREADTim(HRDATAEXT),
|
.HREADTim(HRDATAEXT), .HREADYTim(HREADYEXT), .HRESPTim(HRESPEXT));
|
||||||
.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
|
// Track names of instructions
|
||||||
instrTrackerTB it(clk, reset, dut.wallypipelinedsoc.hart.ieu.dp.FlushE,
|
instrTrackerTB it(clk, reset, dut.wallypipelinedsoc.hart.ieu.dp.FlushE,
|
||||||
|
@ -91,7 +91,10 @@ module testbench();
|
|||||||
assign HRESPEXT = 0;
|
assign HRESPEXT = 0;
|
||||||
assign HRDATAEXT = 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);
|
flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW);
|
||||||
// Track names of instructions
|
// Track names of instructions
|
||||||
instrTrackerTBPriv it(clk, reset, dut.hart.ieu.dp.FlushE,
|
instrTrackerTBPriv it(clk, reset, dut.hart.ieu.dp.FlushE,
|
||||||
|
@ -146,7 +146,10 @@ logic [3:0] dummy;
|
|||||||
assign HRESPEXT = 0;
|
assign HRESPEXT = 0;
|
||||||
assign HRDATAEXT = 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
|
// Track names of instructions
|
||||||
instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE,
|
instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE,
|
||||||
|
@ -586,6 +586,7 @@ string imperas32f[] = '{
|
|||||||
|
|
||||||
string arch64i[] = '{
|
string arch64i[] = '{
|
||||||
`RISCVARCHTEST,
|
`RISCVARCHTEST,
|
||||||
|
"rv64i_m/I/beq-01", "47010",
|
||||||
"rv64i_m/I/add-01", "9010",
|
"rv64i_m/I/add-01", "9010",
|
||||||
"rv64i_m/I/addi-01", "6010",
|
"rv64i_m/I/addi-01", "6010",
|
||||||
"rv64i_m/I/addiw-01", "6010",
|
"rv64i_m/I/addiw-01", "6010",
|
||||||
|
Loading…
Reference in New Issue
Block a user