This commit is contained in:
bbracker 2021-05-24 17:09:14 -04:00
commit 920dd7bd8d
14 changed files with 181 additions and 117 deletions

View File

@ -90,4 +90,5 @@ $(TARGET).memfile: $(TARGET)
@echo 'Making memory file' @echo 'Making memory file'
exe2memfile0.pl $< exe2memfile0.pl $<
extractFunctionRadix.sh $<.objdump extractFunctionRadix.sh $<.objdump
cp $(TARGETDIR)/* ../../imperas-riscv-tests/work/rv64BP/ mkdir -p ../../imperas-riscv-tests/work/rv64BP/
cp -f $(TARGETDIR)/* ../../imperas-riscv-tests/work/rv64BP/

View File

@ -1,7 +1,8 @@
#include "header.h" #include "header.h"
int main(){ int main(){
int res = icache_spill_test(); //int res = icache_spill_test();
int res = 1;
if (res < 0) { if (res < 0) {
fail(); fail();
return 0; return 0;

View File

@ -15,6 +15,7 @@ module fctrl (
output logic [2:0] FrmD, output logic [2:0] FrmD,
output logic [1:0] FMemRWD, output logic [1:0] FMemRWD,
output logic OutputInput2D, output logic OutputInput2D,
output logic In2UsedD, In3UsedD,
output logic FWriteIntD); output logic FWriteIntD);
@ -55,50 +56,50 @@ module fctrl (
//(or equivalent) //(or equivalent)
always_comb begin always_comb begin
//checks all but FMA/store/load //checks all but FMA/store/load
IllegalFPUInstr2D = 0; IllegalFPUInstr2D = 0;
if(OpD == 7'b1010011) begin if(OpD == 7'b1010011) begin
casez(Funct7D) casez(Funct7D)
//compare //compare
7'b10100?? : FResultSelD = 3'b001; 7'b10100?? : FResultSelD = 3'b001;
//div/sqrt //div/sqrt
7'b0?011?? : FResultSelD = 3'b000; 7'b0?011?? : FResultSelD = 3'b000;
//add/sub //add/sub
7'b0000??? : FResultSelD = 3'b100; 7'b0000??? : FResultSelD = 3'b100;
//mult //mult
7'b00010?? : FResultSelD = 3'b010; 7'b00010?? : FResultSelD = 3'b010;
//convert (not precision) //convert (not precision)
7'b110?0?? : FResultSelD = 3'b100; 7'b110?0?? : FResultSelD = 3'b100;
//convert (precision) //convert (precision)
7'b010000? : FResultSelD = 3'b100; 7'b010000? : FResultSelD = 3'b100;
//Min/Max //Min/Max
7'b00101?? : FResultSelD = 3'b001; 7'b00101?? : FResultSelD = 3'b001;
//sign injection //sign injection
7'b00100?? : FResultSelD = 3'b011; 7'b00100?? : FResultSelD = 3'b011;
//classify //only if funct3 = 001 //classify //only if funct3 = 001
7'b11100?? : if(Funct3D == 3'b001) FResultSelD = 3'b101; 7'b11100?? : if(Funct3D == 3'b001) FResultSelD = 3'b101;
//output ReadData1 //output ReadData1
else if (Funct7D[1] == 0) FResultSelD = 3'b111; else if (Funct7D[1] == 0) FResultSelD = 3'b111;
//output SrcW //output SrcW
7'b111100? : FResultSelD = 3'b110; 7'b111100? : FResultSelD = 3'b110;
default : begin FResultSelD = 3'b0; IllegalFPUInstr2D = 1'b1; end default : begin FResultSelD = 3'b0; IllegalFPUInstr2D = 1'b1; end
endcase endcase
end end
//FMA/store/load //FMA/store/load
else begin else begin
case(OpD) case(OpD)
//4 FMA instructions //4 FMA instructions
7'b1000011 : FResultSelD = 3'b010; 7'b1000011 : FResultSelD = 3'b010;
7'b1000111 : FResultSelD = 3'b010; 7'b1000111 : FResultSelD = 3'b010;
7'b1001011 : FResultSelD = 3'b010; 7'b1001011 : FResultSelD = 3'b010;
7'b1001111 : FResultSelD = 3'b010; 7'b1001111 : FResultSelD = 3'b010;
//store //store
7'b0100111 : FResultSelD = 3'b111; 7'b0100111 : FResultSelD = 3'b111;
//load //load
7'b0000111 : FResultSelD = 3'b111; 7'b0000111 : FResultSelD = 3'b111;
default : begin FResultSelD = 3'b0; IllegalFPUInstr2D = 1'b1; end default : begin FResultSelD = 3'b0; IllegalFPUInstr2D = 1'b1; end
endcase endcase
end end
end end
assign OutputInput2D = OpD == 7'b0100111; assign OutputInput2D = OpD == 7'b0100111;
@ -151,11 +152,12 @@ module fctrl (
always_comb begin always_comb begin
IllegalFPUInstr1D = 0; IllegalFPUInstr1D = 0;
In3UsedD = 0;
case (FResultSelD) case (FResultSelD)
// div/sqrt // div/sqrt
// fdiv = ???0 // fdiv = ???0
// fsqrt = ???1 // fsqrt = ???1
3'b000 : OpCtrlD = {3'b0, Funct7D[5]}; 3'b000 : begin OpCtrlD = {3'b0, Funct7D[5]}; In2UsedD = ~Funct7D[5]; end
// cmp // cmp
// fmin = ?100 // fmin = ?100
// fmax = ?101 // fmax = ?101
@ -163,7 +165,7 @@ module fctrl (
// flt = ?001 // flt = ?001
// fle = ?011 // fle = ?011
// {?, is min or max, is eq or le, is lt or le} // {?, is min or max, is eq or le, is lt or le}
3'b001 : OpCtrlD = {1'b0, Funct7D[2], ~Funct3D[0], ~(|Funct3D[2:1])}; 3'b001 : begin OpCtrlD = {1'b0, Funct7D[2], ~Funct3D[0], ~(|Funct3D[2:1])}; In2UsedD = 1'b1; end
//fma/mult //fma/mult
// fmadd = ?000 // fmadd = ?000
// fmsub = ?001 // fmsub = ?001
@ -171,12 +173,12 @@ module fctrl (
// fnmsub = ?011 // fnmsub = ?011
// fmul = ?100 // fmul = ?100
// {?, is mul, is negitive, is sub} // {?, is mul, is negitive, is sub}
3'b010 : OpCtrlD = {1'b0, OpD[4:2]}; 3'b010 : begin OpCtrlD = {1'b0, OpD[4:2]}; In2UsedD = 1'b1; In3UsedD = ~OpD[4]; end
// sgn inj // sgn inj
// fsgnj = ??00 // fsgnj = ??00
// fsgnjn = ??01 // fsgnjn = ??01
// fsgnjx = ??10 // fsgnjx = ??10
3'b011 : OpCtrlD = {2'b0, Funct3D[1:0]}; 3'b011 : begin OpCtrlD = {2'b0, Funct3D[1:0]}; In2UsedD = 1'b1; end
// add/sub/cnvt // add/sub/cnvt
// fadd = 0000 // fadd = 0000
// fsub = 0001 // fsub = 0001
@ -191,23 +193,23 @@ module fctrl (
// fcvt.d.wu = 1111 // fcvt.d.wu = 1111
// fcvt.d.s = 1000 // fcvt.d.s = 1000
// { is double and not add/sub, is to/from int, is to int or float to double, is unsigned or sub // { is double and not add/sub, is to/from int, is to int or float to double, is unsigned or sub
3'b100 : OpCtrlD = {Funct7D[0]&Funct7D[5], Funct7D[6], Funct7D[3] | (~Funct7D[6]&Funct7D[5]&~Funct7D[0]), Rs2D[0]|(Funct7D[2]&~Funct7D[5])}; 3'b100 : begin OpCtrlD = {Funct7D[0]&Funct7D[5], Funct7D[6], Funct7D[3] | (~Funct7D[6]&Funct7D[5]&~Funct7D[0]), Rs2D[0]|(Funct7D[2]&~Funct7D[5])}; In2UsedD = ~Funct7D[5]; end
// classify {?, ?, ?, ?} // classify {?, ?, ?, ?}
3'b101 : OpCtrlD = 4'b0; 3'b101 : begin OpCtrlD = 4'b0; In2UsedD = 1'b0; end
// output SrcAW // output SrcAW
// fmv.w.x = ???0 // fmv.w.x = ???0
// fmv.w.d = ???1 // fmv.w.d = ???1
3'b110 : OpCtrlD = {3'b0, Funct7D[0]}; 3'b110 : begin OpCtrlD = {3'b0, Funct7D[0]}; In2UsedD = 1'b0; end
// output Input1 // output Input1
// flw = ?000 // flw = ?000
// fld = ?001 // fld = ?001
// fsw = ?010 // output Input2 // fsw = ?010 // output Input2
// fsd = ?011 // output Input2 // fsd = ?011 // output Input2
// fmv.x.w = ?100 // fmv.x.w = ?100
// fmv.d.w = ?101 // fmv.x.d = ?101
// {?, is mv, is store, is double or fcvt.d.w} // {?, is mv, is store, is double or fcvt.d.w}
3'b111 : OpCtrlD = {1'b0, OpD[6:5], Funct3D[0] | (OpD[6]&Funct7D[0])}; 3'b111 : begin OpCtrlD = {1'b0, OpD[6:5], Funct3D[0] | (OpD[6]&Funct7D[0])}; In2UsedD = OpD[5]; end
default : begin OpCtrlD = 4'b0; IllegalFPUInstr1D = 1'b1; end default : begin OpCtrlD = 4'b0; IllegalFPUInstr1D = 1'b1; In2UsedD = 1'b0; end
endcase endcase
end end

View File

@ -1,14 +1,27 @@
///////////////////////////////////////////
// //
// File name : fpadd // Written: James.Stine@okstate.edu 1 February 2021
// Title : Floating-Point Adder/Subtractor // Modified:
// project : FPU
// Library : fpadd
// Author(s) : James E. Stine, Jr., Brett Mathis
// Purpose : definition of main unit to floating-point add/sub
// notes :
// //
// Copyright Oklahoma State University // Purpose: FP Add/Sub instructions
// Copyright AFRL //
// 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.
///////////////////////////////////////////
// //
// Basic and Denormalized Operations // Basic and Denormalized Operations
// //
@ -26,7 +39,6 @@
// Step 8: Put sum onto output. // Step 8: Put sum onto output.
// //
module fpadd (AS_Result, Flags, Denorm, op1, op2, rm, op_type, P, OvEn, UnEn); module fpadd (AS_Result, Flags, Denorm, op1, op2, rm, op_type, P, OvEn, UnEn);
input [63:0] op1; // 1st input operand (A) input [63:0] op1; // 1st input operand (A)

View File

@ -1,3 +1,26 @@
///////////////////////////////////////////
//
// Written:
// Modified:
//
// Purpose: FPU
//
// 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" `include "wally-config.vh"
// `include "../../config/rv64icfd/wally-config.vh" //debug // `include "../../config/rv64icfd/wally-config.vh" //debug
@ -13,12 +36,14 @@ module fpu (
input logic [`XLEN-1:0] SrcAM, // Integer input being written into fpreg input logic [`XLEN-1:0] SrcAM, // Integer input being written into fpreg
input logic StallE, StallM, StallW, input logic StallE, StallM, StallW,
input logic FlushE, FlushM, FlushW, input logic FlushE, FlushM, FlushW,
input logic [`AHBW-1:0] HRDATA,
input logic RegWriteD, input logic RegWriteD,
output logic [4:0] SetFflagsM, output logic [4:0] SetFflagsM,
output logic [31:0] FSROutW, output logic [31:0] FSROutW,
output logic [1:0] FMemRWM, output logic [1:0] FMemRWM,
output logic FStallE, output logic FStallD,
output logic FWriteIntW, output logic FWriteIntW,
output logic FWriteIntM,
output logic [`XLEN-1:0] FWriteDataM, // Integer input being written into fpreg output logic [`XLEN-1:0] FWriteDataM, // Integer input being written into fpreg
output logic DivSqrtDoneE, output logic DivSqrtDoneE,
output logic IllegalFPUInstrD, output logic IllegalFPUInstrD,
@ -84,7 +109,7 @@ module fpu (
logic DivBusyM; logic DivBusyM;
logic [1:0] Input1MuxD, Input2MuxD; logic [1:0] Input1MuxD, Input2MuxD;
logic Input3MuxD; logic Input3MuxD;
logic In2UsedD, In3UsedD;
//Hazard unit for FPU //Hazard unit for FPU
fpuhazard hazard(.Adr1(InstrD[19:15]), .Adr2(InstrD[24:20]), .Adr3(InstrD[31:27]), .*); fpuhazard hazard(.Adr1(InstrD[19:15]), .Adr2(InstrD[24:20]), .Adr3(InstrD[31:27]), .*);
@ -312,7 +337,6 @@ module fpu (
logic [2:0] FrmM; logic [2:0] FrmM;
logic FmtM; logic FmtM;
logic [3:0] OpCtrlM; logic [3:0] OpCtrlM;
logic FWriteIntM;
//instantiate M stage FMA signals here ***rename fma signals and resize for XLEN //instantiate M stage FMA signals here ***rename fma signals and resize for XLEN
logic [63:0] FmaResultM; logic [63:0] FmaResultM;
@ -346,6 +370,7 @@ module fpu (
//instantiation of M stage regfile signals //instantiation of M stage regfile signals
logic [4:0] RdM; logic [4:0] RdM;
logic [`XLEN-1:0] Input1M, Input2M, Input3M; logic [`XLEN-1:0] Input1M, Input2M, Input3M;
logic [`XLEN-1:0] LoadStoreResultM;
//instantiation of M stage add/cvt signals //instantiation of M stage add/cvt signals
logic [63:0] AddResultM; logic [63:0] AddResultM;
@ -485,6 +510,8 @@ module fpu (
assign FWriteDataM = Input1M; assign FWriteDataM = Input1M;
mux2 #(64) LoadStoreResultMux(HRDATA, Input1M, |OpCtrlM[2:1], LoadStoreResultM);
fma2 fma2(.*); fma2 fma2(.*);
//second instance of two-stage floating-point add/cvt unit //second instance of two-stage floating-point add/cvt unit
@ -519,7 +546,7 @@ module fpu (
logic [4:0] SgnFlagsW; logic [4:0] SgnFlagsW;
//instantiation of W stage regfile signals //instantiation of W stage regfile signals
logic [`XLEN-1:0] Input1W; logic [`XLEN-1:0] LoadStoreResultW;
logic [`XLEN-1:0] SrcAW; logic [`XLEN-1:0] SrcAW;
//instantiation of W stage add/cvt signals //instantiation of W stage add/cvt signals
@ -576,7 +603,7 @@ module fpu (
flopenrc #(1) MWReg3(clk, reset, PipeClearMW, PipeEnableMW, FmtM, FmtW); flopenrc #(1) MWReg3(clk, reset, PipeClearMW, PipeEnableMW, FmtM, FmtW);
flopenrc #(5) MWReg4(clk, reset, PipeClearMW, PipeEnableMW, RdM, RdW); flopenrc #(5) MWReg4(clk, reset, PipeClearMW, PipeEnableMW, RdM, RdW);
flopenrc #(`XLEN) MWReg5(clk, reset, PipeClearMW, PipeEnableMW, SrcAM, SrcAW); flopenrc #(`XLEN) MWReg5(clk, reset, PipeClearMW, PipeEnableMW, SrcAM, SrcAW);
flopenrc #(64) MWReg6(clk, reset, PipeClearMW, PipeEnableMW, Input1M, Input1W); flopenrc #(64) MWReg6(clk, reset, PipeClearMW, PipeEnableMW, LoadStoreResultM, LoadStoreResultW);
flopenrc #(1) MWReg7(clk, reset, PipeClearMW, PipeEnableMW, FWriteIntM, FWriteIntW); flopenrc #(1) MWReg7(clk, reset, PipeClearMW, PipeEnableMW, FWriteIntM, FWriteIntW);
////END M/W PIPE ////END M/W PIPE
@ -628,6 +655,8 @@ module fpu (
// ( (FResultSelW[0]) ? (FmaResultW) : ({62'b0,CmpFCCW}) ) // ( (FResultSelW[0]) ? (FmaResultW) : ({62'b0,CmpFCCW}) )
// : ( (FResultSelW[0]) ? (AddResultW) : (DivResultW) ) // : ( (FResultSelW[0]) ? (AddResultW) : (DivResultW) )
// ); // );
always_comb begin always_comb begin
case (FResultSelW) case (FResultSelW)
// div/sqrt // div/sqrt
@ -644,8 +673,8 @@ module fpu (
3'b101 : FPUResultDirW = ClassResultW; 3'b101 : FPUResultDirW = ClassResultW;
// output SrcAW // output SrcAW
3'b110 : FPUResultDirW = SrcAW; 3'b110 : FPUResultDirW = SrcAW;
// output ReadData1 // Load/Store/Move to FP-register
3'b111 : FPUResultDirW = Input1W; 3'b111 : FPUResultDirW = LoadStoreResultW;
default : FPUResultDirW = {64{1'bx}}; default : FPUResultDirW = {64{1'bx}};
endcase endcase
end end

View File

@ -32,8 +32,10 @@ module fpuhazard(
input logic DivBusyM, input logic DivBusyM,
input logic RegWriteD, input logic RegWriteD,
input logic [2:0] FResultSelD, FResultSelE, input logic [2:0] FResultSelD, FResultSelE,
input logic IllegalFPUInstrD,
input logic In2UsedD, In3UsedD,
// Stall outputs // Stall outputs
output logic FStallE, output logic FStallD,
output logic [1:0] Input1MuxD, Input2MuxD, output logic [1:0] Input1MuxD, Input2MuxD,
output logic Input3MuxD output logic Input3MuxD
); );
@ -44,27 +46,28 @@ module fpuhazard(
Input1MuxD = 2'b00; Input1MuxD = 2'b00;
Input2MuxD = 2'b00; Input2MuxD = 2'b00;
Input3MuxD = 1'b0; Input3MuxD = 1'b0;
FStallE = DivBusyM; FStallD = DivBusyM;
if (~IllegalFPUInstrD) begin
// if taking a value from int register
if ((Adr1 == RdE) & (FRegWriteE | ((FResultSelE == 3'b110) & RegWriteD)))
if (FResultSelE == 3'b110) Input1MuxD = 2'b11; // choose SrcAM
else FStallD = 1'b1; // otherwise stall
else if ((Adr1 == RdM) & FRegWriteM) Input1MuxD = 2'b01; // choose FPUResultDirW
else if ((Adr1 == RdW) & FRegWriteW) Input1MuxD = 2'b11; // choose FPUResultDirE
if ((Adr1 == RdE) & (FRegWriteE | ((FResultSelE == 3'b110) & RegWriteD))) if(In2UsedD)
if (FResultSelE == 3'b110) Input1MuxD = 2'b11; // choose SrcAM if ((Adr2 == RdE) & FRegWriteE) FStallD = 1'b1;
else FStallE = 1'b1; // otherwise stall else if ((Adr2 == RdM) & FRegWriteM) Input2MuxD = 2'b01; // choose FPUResultDirW
else if ((Adr2 == RdW) & FRegWriteW) Input2MuxD = 2'b10; // choose FPUResultDirE
else if ((Adr1 == RdM) & FRegWriteM) Input1MuxD = 2'b01; // choose FPUResultDirW
else if ((Adr1 == RdW) & FRegWriteW) Input1MuxD = 2'b11; // choose FPUResultDirE
else if ((Adr2 == RdE) & FRegWriteE) FStallE = 1'b1;//***add a signals saying whether input 1, 2 or 3 are used
else if ((Adr2 == RdM) & FRegWriteM) Input2MuxD = 2'b01; // choose FPUResultDirW
else if ((Adr2 == RdW) & FRegWriteW) Input2MuxD = 2'b10; // choose FPUResultDirE
if(In3UsedD)
if ((Adr3 == RdE) & FRegWriteE) FStallD = 1'b1;
else if ((Adr3 == RdM) & FRegWriteM) FStallD = 1'b1;
else if ((Adr3 == RdW) & FRegWriteW) Input3MuxD = 1'b1; // choose FPUResultDirE
end
else if ((Adr3 == RdE) & FRegWriteE) FStallE = 1'b1;
else if ((Adr3 == RdM) & FRegWriteM) FStallE = 1'b1;
else if ((Adr3 == RdW) & FRegWriteW) Input3MuxD = 1'b1; // choose FPUResultDirE
end end
endmodule endmodule

View File

@ -32,7 +32,7 @@ module hazard(
input logic BPPredWrongE, CSRWritePendingDEM, RetM, TrapM, input logic BPPredWrongE, CSRWritePendingDEM, RetM, TrapM,
input logic LoadStallD, MulDivStallD, CSRRdStallD, input logic LoadStallD, MulDivStallD, CSRRdStallD,
input logic DataStall, ICacheStallF, input logic DataStall, ICacheStallF,
input logic FStallE, input logic FStallD,
input logic DivBusyE, input logic DivBusyE,
// Stall & flush outputs // Stall & flush outputs
output logic StallF, StallD, StallE, StallM, StallW, output logic StallF, StallD, StallE, StallM, StallW,
@ -59,9 +59,9 @@ module hazard(
assign BranchFlushDE = BPPredWrongE | RetM | TrapM; assign BranchFlushDE = BPPredWrongE | RetM | TrapM;
assign StallFCause = CSRWritePendingDEM & ~(BranchFlushDE); assign StallFCause = CSRWritePendingDEM & ~(BranchFlushDE);
assign StallDCause = (LoadStallD | MulDivStallD | CSRRdStallD) & ~(BranchFlushDE); // stall in decode if instruction is a load/mul/csr dependent on previous assign StallDCause = (LoadStallD | MulDivStallD | CSRRdStallD | FStallD) & ~(BranchFlushDE); // stall in decode if instruction is a load/mul/csr dependent on previous
// assign StallDCause = LoadStallD | MulDivStallD | CSRRdStallD; // stall in decode if instruction is a load/mul/csr dependent on previous // assign StallDCause = LoadStallD | MulDivStallD | CSRRdStallD; // stall in decode if instruction is a load/mul/csr dependent on previous
assign StallECause = DivBusyE | FStallE; assign StallECause = DivBusyE;
assign StallMCause = 0; assign StallMCause = 0;
assign StallWCause = DataStall | ICacheStallF; assign StallWCause = DataStall | ICacheStallF;

View File

@ -44,6 +44,7 @@ module datapath (
output logic [`XLEN-1:0] SrcAE, SrcBE, output logic [`XLEN-1:0] SrcAE, SrcBE,
// Memory stage signals // Memory stage signals
input logic StallM, FlushM, input logic StallM, FlushM,
input logic [`XLEN-1:0] FWriteDataM,
output logic [`XLEN-1:0] SrcAM, output logic [`XLEN-1:0] SrcAM,
output logic [`XLEN-1:0] WriteDataM, MemAdrM, output logic [`XLEN-1:0] WriteDataM, MemAdrM,
// Writeback stage signals // Writeback stage signals
@ -101,8 +102,8 @@ module datapath (
flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E); flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E);
flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE); flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE);
mux3 #(`XLEN) faemux(RD1E, ResultW, ALUResultM, ForwardAE, PreSrcAE); mux4 #(`XLEN) faemux(RD1E, WriteDataW, ALUResultM, FWriteDataM, ForwardAE, PreSrcAE);
mux3 #(`XLEN) fbemux(RD2E, ResultW, ALUResultM, ForwardBE, WriteDataE); mux4 #(`XLEN) fbemux(RD2E, WriteDataW, ALUResultM, FWriteDataM, ForwardBE, WriteDataE);
mux2 #(`XLEN) srcamux(PreSrcAE, PCE, ALUSrcAE, SrcAE); mux2 #(`XLEN) srcamux(PreSrcAE, PCE, ALUSrcAE, SrcAE);
mux2 #(`XLEN) srcamux2(SrcAE, PCLinkE, JumpE, SrcAE2); mux2 #(`XLEN) srcamux2(SrcAE, PCLinkE, JumpE, SrcAE2);
mux2 #(`XLEN) srcbmux(WriteDataE, ExtImmE, ALUSrcBE, SrcBE); mux2 #(`XLEN) srcbmux(WriteDataE, ExtImmE, ALUSrcBE, SrcBE);

View File

@ -31,6 +31,7 @@ module forward(
input logic MemReadE, MulDivE, CSRReadE, input logic MemReadE, MulDivE, CSRReadE,
input logic RegWriteM, RegWriteW, input logic RegWriteM, RegWriteW,
input logic DivDoneE, DivBusyE, input logic DivDoneE, DivBusyE,
input logic FWriteIntM, FWriteIntW,
// Forwarding controls // Forwarding controls
output logic [1:0] ForwardAE, ForwardBE, output logic [1:0] ForwardAE, ForwardBE,
output logic LoadStallD, MulDivStallD, CSRRdStallD output logic LoadStallD, MulDivStallD, CSRRdStallD
@ -41,11 +42,13 @@ module forward(
ForwardBE = 2'b00; ForwardBE = 2'b00;
if (Rs1E != 5'b0) if (Rs1E != 5'b0)
if ((Rs1E == RdM) & RegWriteM) ForwardAE = 2'b10; if ((Rs1E == RdM) & RegWriteM) ForwardAE = 2'b10;
else if ((Rs1E == RdW) & RegWriteW) ForwardAE = 2'b01; else if ((Rs1E == RdW) & (RegWriteW|FWriteIntW)) ForwardAE = 2'b01;
else if ((Rs1E == RdM) & FWriteIntM) ForwardAE = 2'b11;
if (Rs2E != 5'b0) if (Rs2E != 5'b0)
if ((Rs2E == RdM) & RegWriteM) ForwardBE = 2'b10; if ((Rs2E == RdM) & RegWriteM) ForwardBE = 2'b10;
else if ((Rs2E == RdW) & RegWriteW) ForwardBE = 2'b01; else if ((Rs2E == RdW) & (RegWriteW|FWriteIntW)) ForwardBE = 2'b01;
else if ((Rs2E == RdM) & FWriteIntM) ForwardBE = 2'b11;
end end
// Stall on dependent operations that finish in Mem Stage and can't bypass in time // Stall on dependent operations that finish in Mem Stage and can't bypass in time

View File

@ -43,6 +43,8 @@ module ieu (
input logic DataMisalignedM, input logic DataMisalignedM,
input logic DataAccessFaultM, input logic DataAccessFaultM,
input logic SquashSCW, input logic SquashSCW,
input logic FWriteIntM,
input logic [`XLEN-1:0] FWriteDataM,
output logic [1:0] MemRWM, output logic [1:0] MemRWM,
output logic [1:0] AtomicM, output logic [1:0] AtomicM,
output logic [`XLEN-1:0] MemAdrM, WriteDataM, output logic [`XLEN-1:0] MemAdrM, WriteDataM,

View File

@ -447,7 +447,14 @@ module icachecontroller #(parameter LINESIZE = 256) (
// we need to address on that number of bits so the PC is extended to the right by AHBByteLength with zeros. // we need to address on that number of bits so the PC is extended to the right by AHBByteLength with zeros.
// fetch count is already aligned to AHBByteLength, but we need to extend back to the full address width with // fetch count is already aligned to AHBByteLength, but we need to extend back to the full address width with
// more zeros after the addition. This will be the number of offset bits less the AHBByteLength. // more zeros after the addition. This will be the number of offset bits less the AHBByteLength.
assign InstrPAdrF = {{PCPTrunkF, {{LOGWPL}{1'b0}}} + FetchCount, {{OFFSETWIDTH-LOGWPL}{1'b0}}}; logic [`XLEN-1:OFFSETWIDTH-LOGWPL] PCPTrunkExtF, InstrPAdrTrunkF ;
assign PCPTrunkExtF = {PCPTrunkF, {{LOGWPL}{1'b0}}};
assign InstrPAdrTrunkF = PCPTrunkExtF + FetchCount;
//assign InstrPAdrF = {{PCPTrunkF, {{LOGWPL}{1'b0}}} + FetchCount, {{OFFSETWIDTH-LOGWPL}{1'b0}}};
assign InstrPAdrF = {InstrPAdrTrunkF, {{OFFSETWIDTH-LOGWPL}{1'b0}}};
// store read data from memory interface before writing into SRAM. // store read data from memory interface before writing into SRAM.

View File

@ -210,9 +210,9 @@ module ifu (
// the branch predictor needs a compact decoding of the instruction class. // the branch predictor needs a compact decoding of the instruction class.
// *** consider adding in the alternate return address x5 for returns. // *** consider adding in the alternate return address x5 for returns.
assign InstrClassD[4] = (InstrD[6:0] & 7'h77) == 7'h67 && (InstrD[11:07] & 5'h1B) == 5'h01; // jal(r) must link to ra or r5 assign InstrClassD[4] = (InstrD[6:0] & 7'h77) == 7'h67 && (InstrD[11:07] & 5'h1B) == 5'h01; // jal(r) must link to ra or r5
assign InstrClassD[3] = InstrD[6:0] == 7'h67 && (InstrD[19:15] & 5'h1B) == 5'h01; // return must link to ra or r5 assign InstrClassD[3] = InstrD[6:0] == 7'h67 && (InstrD[19:15] & 5'h1B) == 5'h01; // return must return to ra or r5
assign InstrClassD[2] = InstrD[6:0] == 7'h67 && (InstrD[19:15] & 5'h1B) != 5'h01; // jump register, but not return assign InstrClassD[2] = InstrD[6:0] == 7'h67 && (InstrD[19:15] & 5'h1B) != 5'h01 && (InstrD[11:7] & 5'h1B) != 5'h01; // jump register, but not return
assign InstrClassD[1] = InstrD[6:0] == 7'h6F; // jump assign InstrClassD[1] = InstrD[6:0] == 7'h6F && (InstrD[11:7] & 5'h1B) != 5'h01; // jump, RD != x1 or x5
assign InstrClassD[0] = InstrD[6:0] == 7'h63; // branch assign InstrClassD[0] = InstrD[6:0] == 7'h63; // branch
// Misaligned PC logic // Misaligned PC logic

View File

@ -97,8 +97,8 @@ module wallypipelinedhart (
logic RegWriteD; logic RegWriteD;
logic [`XLEN-1:0] FWriteDataM; logic [`XLEN-1:0] FWriteDataM;
logic SquashSCW; logic SquashSCW;
logic FStallE; logic FStallD;
logic FWriteIntW; logic FWriteIntW, FWriteIntM;
logic [31:0] FSROutW; logic [31:0] FSROutW;
logic DivSqrtDoneE; logic DivSqrtDoneE;
logic IllegalFPUInstrD, IllegalFPUInstrE; logic IllegalFPUInstrD, IllegalFPUInstrE;

View File

@ -28,7 +28,6 @@
module testbench(); module testbench();
parameter DEBUG = 0; parameter DEBUG = 0;
parameter TESTSBP = 0;
parameter TESTSPERIPH = 0; // set to 0 for regression parameter TESTSPERIPH = 0; // set to 0 for regression
logic clk; logic clk;
@ -119,7 +118,6 @@ string tests32f[] = '{
}; };
string tests64d[] = '{ string tests64d[] = '{
"rv64d/I-FMV-D-X-01", "2000",
// "rv64d/I-FADD-D-01", "2000", // "rv64d/I-FADD-D-01", "2000",
// "rv64d/I-FCLASS-D-01", "2000", // "rv64d/I-FCLASS-D-01", "2000",
// "rv64d/I-FCVT-D-L-01", "2000", // "rv64d/I-FCVT-D-L-01", "2000",
@ -134,7 +132,8 @@ string tests32f[] = '{
// "rv64d/I-FCVT-WU-D-01", "2000", // "rv64d/I-FCVT-WU-D-01", "2000",
// "rv64d/I-FDIV-D-01", "2000", // "rv64d/I-FDIV-D-01", "2000",
// "rv64d/I-FEQ-D-01", "2000", // "rv64d/I-FEQ-D-01", "2000",
"rv64d/I-FLD-D-01", "2000" "rv64d/I-FSD-01", "2000",
"rv64d/I-FLD-01", "2420",
// "rv64d/I-FLE-D-01", "2000", // "rv64d/I-FLE-D-01", "2000",
// "rv64d/I-FLT-D-01", "2000", // "rv64d/I-FLT-D-01", "2000",
// "rv64d/I-FMADD-D-01", "2000", // "rv64d/I-FMADD-D-01", "2000",
@ -142,10 +141,10 @@ string tests32f[] = '{
// "rv64d/I-FMIN-D-01", "2000", // "rv64d/I-FMIN-D-01", "2000",
// "rv64d/I-FMSUB-D-01", "2000", // "rv64d/I-FMSUB-D-01", "2000",
// "rv64d/I-FMUL-D-01", "2000", // "rv64d/I-FMUL-D-01", "2000",
// "rv64d/I-FMV-X-D-01", "2000", "rv64d/I-FMV-D-X-01", "2000",
"rv64d/I-FMV-X-D-01", "2000"
// "rv64d/I-FNMADD-D-01", "2000", // "rv64d/I-FNMADD-D-01", "2000",
// "rv64d/I-FNMSUB-D-01", "2000", // "rv64d/I-FNMSUB-D-01", "2000",
//"rv64d/I-FSD-01", "2000"
// "rv64d/I-FSGNJ-D-01", "2000", // "rv64d/I-FSGNJ-D-01", "2000",
// "rv64d/I-FSGNJN-D-01", "2000", // "rv64d/I-FSGNJN-D-01", "2000",
// "rv64d/I-FSGNJX-D-01", "2000", // "rv64d/I-FSGNJX-D-01", "2000",
@ -513,10 +512,12 @@ string tests32f[] = '{
initial begin initial begin
if (`XLEN == 64) begin // RV64 if (`XLEN == 64) begin // RV64
if (`TESTSBP) begin if (`TESTSBP) begin
tests = {testsBP64,tests64p}; tests = testsBP64;
end if (TESTSPERIPH) begin // testsbp should not run the other tests. It starts at address 0 rather than
// 0x8000_0000, the next if must remain an else if.
end else if (TESTSPERIPH) begin
tests = tests64periph; tests = tests64periph;
end else begin end else begin
tests = {tests64p,tests64i,tests64periph}; tests = {tests64p,tests64i,tests64periph};
if (`C_SUPPORTED) tests = {tests, tests64ic}; if (`C_SUPPORTED) tests = {tests, tests64ic};
else tests = {tests, tests64iNOc}; else tests = {tests, tests64iNOc};
@ -582,9 +583,11 @@ string tests32f[] = '{
if (`XLEN == 32) meminit = 32'hFEDC0123; if (`XLEN == 32) meminit = 32'hFEDC0123;
else meminit = 64'hFEDCBA9876543210; else meminit = 64'hFEDCBA9876543210;
// *** broken because DTIM also drives RAM // *** broken because DTIM also drives RAM
/*for (i=MemStartAddr; i<MemEndAddr; i = i+1) begin if (`TESTSBP) begin
dut.uncore.dtim.RAM[i] = meminit; for (i=MemStartAddr; i<MemEndAddr; i = i+1) begin
end*/ dut.uncore.dtim.RAM[i] = meminit;
end
end
// read test vectors into memory // read test vectors into memory
memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"}; memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"};
$readmemh(memfilename, dut.uncore.dtim.RAM); $readmemh(memfilename, dut.uncore.dtim.RAM);
@ -873,8 +876,8 @@ module instrNameDecTB(
else if (funct7 == 7'b1101000 && rs2 == 5'b00001) name = "FCVT.S.WU"; else if (funct7 == 7'b1101000 && rs2 == 5'b00001) name = "FCVT.S.WU";
else if (funct7 == 7'b1110000 && rs2 == 5'b00000) name = "FMV.X.W"; else if (funct7 == 7'b1110000 && rs2 == 5'b00000) name = "FMV.X.W";
else if (funct7 == 7'b1111000 && rs2 == 5'b00000) name = "FMV.W.X"; else if (funct7 == 7'b1111000 && rs2 == 5'b00000) name = "FMV.W.X";
else if (funct7 == 7'b1110001 && rs2 == 5'b00000) name = "FMV.X.W"; // DOUBLE else if (funct7 == 7'b1110001 && rs2 == 5'b00000) name = "FMV.X.D"; // DOUBLE
else if (funct7 == 7'b1111001 && rs2 == 5'b00000) name = "FMV.W.X"; // DOUBLE else if (funct7 == 7'b1111001 && rs2 == 5'b00000) name = "FMV.D.X"; // DOUBLE
else if (funct7[6:2] == 5'b00100) name = "FSGNJ"; else if (funct7[6:2] == 5'b00100) name = "FSGNJ";
else if (funct7[6:2] == 5'b00101) name = "FMIN"; else if (funct7[6:2] == 5'b00101) name = "FMIN";
else if (funct7[6:2] == 5'b10100) name = "FLE"; else if (funct7[6:2] == 5'b10100) name = "FLE";