From acdd2e45041530a5d9ab7a3c272fdba77ee1baa2 Mon Sep 17 00:00:00 2001 From: Katherine Parry Date: Tue, 13 Jul 2021 13:20:30 -0400 Subject: [PATCH] Fixed writting MStatus FS bits --- .../config/rv64icfd/wally-config.vh | 107 ++++++++++++++++++ wally-pipelined/regression/wave-all.do | 8 +- wally-pipelined/src/fpu/convert_inputs.sv | 30 ++--- wally-pipelined/src/fpu/faddcvt.sv | 4 +- wally-pipelined/src/fpu/fclassify.sv | 14 +-- wally-pipelined/src/fpu/fcmp.sv | 5 +- wally-pipelined/src/fpu/fctrl.sv | 6 +- wally-pipelined/src/fpu/fcvt.sv | 34 +++--- wally-pipelined/src/fpu/fhazard.sv | 14 +-- wally-pipelined/src/fpu/fpu.sv | 44 ++++--- wally-pipelined/src/fpu/rounder_denorm.sv | 2 +- wally-pipelined/src/privileged/csr.sv | 3 +- wally-pipelined/src/privileged/csrsr.sv | 7 +- wally-pipelined/src/privileged/csru.sv | 1 + wally-pipelined/src/privileged/privileged.sv | 2 +- .../src/wally/wallypipelinedhart.sv | 6 +- .../testbench/testbench-imperas.sv | 32 +++--- 17 files changed, 213 insertions(+), 106 deletions(-) diff --git a/wally-pipelined/config/rv64icfd/wally-config.vh b/wally-pipelined/config/rv64icfd/wally-config.vh index c6523f815..501895d54 100644 --- a/wally-pipelined/config/rv64icfd/wally-config.vh +++ b/wally-pipelined/config/rv64icfd/wally-config.vh @@ -1,3 +1,109 @@ +// ////////////////////////////////////////// +// // wally-config.vh +// // +// // Written: David_Harris@hmc.edu 4 January 2021 +// // Modified: +// // +// // Purpose: Specify which features are configured +// // Macros to determine which modes are supported based on MISA +// // +// // 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 shared configuration +// `include "wally-shared.vh" + +// `define BUILDROOT 0 +// `define BUSYBEAR 0 + +// // RV32 or RV64: XLEN = 32 or 64 +// `define XLEN 32 + +// `define MISA (32'h00000104 | 1 << 5 | 1 << 20 | 1 << 18 | 1 << 12) +// `define ZCSR_SUPPORTED 1 +// `define COUNTERS 32 +// `define ZCOUNTERS_SUPPORTED 1 + +// // Microarchitectural Features +// `define UARCH_PIPELINED 1 +// `define UARCH_SUPERSCALR 0 +// `define UARCH_SINGLECYCLE 0 +// `define MEM_DCACHE 0 +// `define MEM_DTIM 1 +// `define MEM_ICACHE 0 +// `define MEM_VIRTMEM 1 +// `define VECTORED_INTERRUPTS_SUPPORTED 1 + +// `define ITLB_ENTRIES 32 +// `define DTLB_ENTRIES 32 + +// // Legal number of PMP entries are 0, 16, or 64 +// `define PMP_ENTRIES 16 + +// // Address space +// `define RESET_VECTOR 32'h80000000 + +// // Peripheral Addresses +// // Peripheral memory space extends from BASE to BASE+RANGE +// // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits + +// // *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file? +// `define BOOTTIM_SUPPORTED 1'b1 +// `define BOOTTIM_BASE 34'h00001000 +// `define BOOTTIM_RANGE 34'h00000FFF +// `define TIM_SUPPORTED 1'b1 +// `define TIM_BASE 34'h80000000 +// `define TIM_RANGE 34'h07FFFFFF +// `define CLINT_SUPPORTED 1'b1 +// `define CLINT_BASE 34'h02000000 +// `define CLINT_RANGE 34'h0000FFFF +// `define GPIO_SUPPORTED 1'b1 +// `define GPIO_BASE 34'h10012000 +// `define GPIO_RANGE 34'h000000FF +// `define UART_SUPPORTED 1'b1 +// `define UART_BASE 34'h10000000 +// `define UART_RANGE 34'h00000007 +// `define PLIC_SUPPORTED 1'b1 +// `define PLIC_BASE 34'h0C000000 +// `define PLIC_RANGE 34'h03FFFFFF + +// // Bus Interface width +// `define AHBW 32 + +// // Test modes + +// // Tie GPIO outputs back to inputs +// `define GPIO_LOOPBACK_TEST 1 + +// // Hardware configuration +// `define UART_PRESCALE 1 + +// // Interrupt configuration +// `define PLIC_NUM_SRC 4 +// // comment out the following if >=32 sources +// `define PLIC_NUM_SRC_LT_32 +// `define PLIC_GPIO_ID 3 +// `define PLIC_UART_ID 4 + +// `define TWO_BIT_PRELOAD "../config/rv32ic/twoBitPredictor.txt" +// `define BTB_PRELOAD "../config/rv32ic/BTBPredictor.txt" +// `define BPRED_ENABLED 1 +// `define BPTYPE "BPGSHARE" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE +// `define TESTSBP 0 ////////////////////////////////////////// // wally-config.vh // @@ -101,6 +207,7 @@ `define TWO_BIT_PRELOAD "../config/rv64icfd/twoBitPredictor.txt" `define BTB_PRELOAD "../config/rv64icfd/BTBPredictor.txt" + `define BPRED_ENABLED 1 `define BPTYPE "BPGSHARE" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE `define TESTSBP 0 diff --git a/wally-pipelined/regression/wave-all.do b/wally-pipelined/regression/wave-all.do index cd2b453b4..6adbf226d 100644 --- a/wally-pipelined/regression/wave-all.do +++ b/wally-pipelined/regression/wave-all.do @@ -168,7 +168,7 @@ add wave -noupdate -radix hexadecimal /testbench/dut/hart/CSRWritePendingDEM add wave -noupdate -radix hexadecimal /testbench/dut/hart/LoadStallD add wave -noupdate -radix hexadecimal /testbench/dut/hart/SetFflagsM add wave -noupdate -radix hexadecimal /testbench/dut/hart/FRM_REGW -add wave -noupdate -radix hexadecimal /testbench/dut/hart/FloatRegWriteW +add wave -noupdate -radix hexadecimal /testbench/dut/hart/FRegWriteM add wave -noupdate -radix hexadecimal /testbench/dut/hart/MemRWAlignedM add wave -noupdate -radix hexadecimal /testbench/dut/hart/Funct3M add wave -noupdate -radix hexadecimal /testbench/dut/hart/MemAdrM @@ -741,7 +741,7 @@ add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/PrivilegedNextPCM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/RetM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/TrapM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/InstrValidW -add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/FloatRegWriteW +add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/FRegWriteM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/LoadStallD add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/PrivilegedM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/InstrMisalignedFaultM @@ -843,7 +843,7 @@ add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/TimerIntM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/ExtIntM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/SwIntM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/InstrValidW -add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/FloatRegWriteW +add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/FRegWriteM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/LoadStallD add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/NextPrivilegeModeM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/PrivilegeModeW @@ -937,7 +937,7 @@ add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/genblk1/csrsr add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/genblk1/csrsr/WriteSSTATUSM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/genblk1/csrsr/WriteUSTATUSM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/genblk1/csrsr/TrapM -add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/genblk1/csrsr/FloatRegWriteW +add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/genblk1/csrsr/FRegWriteM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/genblk1/csrsr/NextPrivilegeModeM add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/genblk1/csrsr/PrivilegeModeW add wave -noupdate -radix hexadecimal /testbench/dut/hart/priv/csr/genblk1/csrsr/mretM diff --git a/wally-pipelined/src/fpu/convert_inputs.sv b/wally-pipelined/src/fpu/convert_inputs.sv index e5dc96d79..25f72c496 100755 --- a/wally-pipelined/src/fpu/convert_inputs.sv +++ b/wally-pipelined/src/fpu/convert_inputs.sv @@ -29,23 +29,27 @@ module convert_inputs(Float1, Float2, op1, op2, op_type, P); // Test if the input exponent is zero, because if it is then the // exponent of the converted number should be zero. - assign Zexp1 = ~(op1[62] | op1[61] | op1[60] | op1[59] | - op1[58] | op1[57] | op1[56] | op1[55]); - assign Zexp2 = ~(op2[62] | op2[61] | op2[60] | op2[59] | - op2[58] | op2[57] | op2[56] | op2[55]); - assign Oexp1 = (op1[62] & op1[61] & op1[60] & op1[59] & - op1[58] & op1[57] & op1[56] & op1[55]); - assign Oexp2 = (op2[62] & op2[61] & op2[60] & op2[59] & - op2[58] & op2[57] & op2[56] &op2[55]); + assign Zexp1 = ~(|op1[30:23]); + assign Zexp2 = ~(|op2[30:23]); + assign Oexp1 = (&op1[30:23]); + assign Oexp2 = (&op2[30:23]); + // assign Zexp1 = ~(op1[62] | op1[61] | op1[60] | op1[59] | + // op1[58] | op1[57] | op1[56] | op1[55]); + // assign Zexp2 = ~(op2[62] | op2[61] | op2[60] | op2[59] | + // op2[58] | op2[57] | op2[56] | op2[55]); + // assign Oexp1 = (op1[62] & op1[61] & op1[60] & op1[59] & + // op1[58] & op1[57] & op1[56] & op1[55]); + // assign Oexp2 = (op2[62] & op2[61] & op2[60] & op2[59] & + // op2[58] & op2[57] & op2[56] &op2[55]); // Conditionally convert op1. Lower 29 bits are zero for single precision. - assign Float1[62:29] = conv_SP ? {op1[62], {3{(~op1[62]&~Zexp1)|Oexp1}}, op1[61:32]} + assign Float1[62:29] = conv_SP ? {op1[30], {3{(~op1[30]&~Zexp1)|Oexp1}}, op1[29:0]} : op1[62:29]; assign Float1[28:0] = op1[28:0] & {29{~conv_SP}}; // Conditionally convert op2. Lower 29 bits are zero for single precision. - assign Float2[62:29] = conv_SP ? {op2[62], - {3{(~op2[62]&~Zexp2)|Oexp2}}, op2[61:32]} + assign Float2[62:29] = conv_SP ? {op2[30], + {3{(~op2[30]&~Zexp2)|Oexp2}}, op2[29:0]} : op2[62:29]; assign Float2[28:0] = op2[28:0] & {29{~conv_SP}}; @@ -54,8 +58,8 @@ module convert_inputs(Float1, Float2, op1, op2, op_type, P); assign negate = op_type[2] & ~op_type[1] & op_type[0]; assign abs_val = op_type[2] & ~op_type[1] & ~op_type[0]; - assign Float1[63] = (op1[63] ^ negate) & ~abs_val; - assign Float2[63] = op2[63]; + assign Float1[63] = conv_SP ? (op1[31] ^ negate) & ~abs_val : (op1[63] ^ negate) & ~abs_val; + assign Float2[63] = conv_SP ? op2[31] : op2[63]; endmodule // convert_inputs diff --git a/wally-pipelined/src/fpu/faddcvt.sv b/wally-pipelined/src/fpu/faddcvt.sv index c4122e21c..2b3d2a54c 100755 --- a/wally-pipelined/src/fpu/faddcvt.sv +++ b/wally-pipelined/src/fpu/faddcvt.sv @@ -215,8 +215,8 @@ module fpuaddcvt1 (AddSumE, AddSumTcE, AddSelInvE, AddExpPostSumE, AddCorrSignE, // Place either the sign-extened 32-bit value or the original 64-bit value // into IntValue (to be used for integer to floating point conversion) - assign IntValue [31:0] = SrcXE[31:0]; - assign IntValue [63:32] = FOpCtrlE[0] ? {32{SrcXE[31]}} : SrcXE[63:32]; + // assign IntValue [31:0] = SrcXE[31:0]; + // assign IntValue [63:32] = FOpCtrlE[0] ? {32{SrcXE[31]}} : SrcXE[63:32]; // If doing an integer to floating point conversion, mantissaA3 is set to // IntVal and the prenomalized exponent is set to 1084. Otherwise, diff --git a/wally-pipelined/src/fpu/fclassify.sv b/wally-pipelined/src/fpu/fclassify.sv index a15edcb4a..54f802ded 100644 --- a/wally-pipelined/src/fpu/fclassify.sv +++ b/wally-pipelined/src/fpu/fclassify.sv @@ -7,8 +7,6 @@ module fclassify ( output logic [63:0] ClassResE ); - logic [31:0] Single; - logic [63:0] Double; logic Sgn; logic Inf, NaN, Zero, Norm, Denorm; logic PInf, QNaN, PZero, PNorm, PDenorm; @@ -16,16 +14,14 @@ module fclassify ( logic MaxExp, ExpZero, ManZero, FirstBitFrac; // Single and Double precision layouts - assign Single = SrcXE[63:32]; - assign Double = SrcXE; - assign Sgn = SrcXE[63]; + assign Sgn = FmtE ? SrcXE[63] : SrcXE[31]; // basic calculations for readabillity - assign ExpZero = FmtE ? ~|Double[62:52] : ~|Single[30:23]; - assign MaxExp = FmtE ? &Double[62:52] : &Single[30:23]; - assign ManZero = FmtE ? ~|Double[51:0] : ~|Single[22:0]; - assign FirstBitFrac = FmtE ? Double[51] : Single[22]; + assign ExpZero = FmtE ? ~|SrcXE[62:52] : ~|SrcXE[30:23]; + assign MaxExp = FmtE ? &SrcXE[62:52] : &SrcXE[30:23]; + assign ManZero = FmtE ? ~|SrcXE[51:0] : ~|SrcXE[22:0]; + assign FirstBitFrac = FmtE ? SrcXE[51] : SrcXE[22]; // determine the type of number assign NaN = MaxExp & ~ManZero; diff --git a/wally-pipelined/src/fpu/fcmp.sv b/wally-pipelined/src/fpu/fcmp.sv index f47d7c9ef..3a858aa6a 100755 --- a/wally-pipelined/src/fpu/fcmp.sv +++ b/wally-pipelined/src/fpu/fcmp.sv @@ -58,8 +58,11 @@ module fcmp ( logic Azero, Bzero; logic LT; // magnitude op1 < magnitude op2 logic EQ; // magnitude op1 = magnitude op2 + logic [63:0] PosOp1, PosOp2; - magcompare64b_1 magcomp1 (w, x, {~op1[63], op1[62:0]}, {~op2[63], op2[62:0]}); + assign PosOp1 = FmtE ? {~op1[63], op1[62:0]} : {~op1[31], op1[30:0], 32'b0}; + assign PosOp2 = FmtE ? {~op2[63], op2[62:0]} : {~op2[31], op2[30:0], 32'b0}; + magcompare64b_1 magcomp1 (w, x, PosOp1, PosOp2); // Determine final values based on output of magnitude comparison, // sign bits, and special case testing. diff --git a/wally-pipelined/src/fpu/fctrl.sv b/wally-pipelined/src/fpu/fctrl.sv index 7805e8a36..648a3a793 100755 --- a/wally-pipelined/src/fpu/fctrl.sv +++ b/wally-pipelined/src/fpu/fctrl.sv @@ -6,7 +6,7 @@ module fctrl ( input logic [2:0] Funct3D, input logic [2:0] FRM_REGW, output logic IllegalFPUInstrD, - output logic FWriteEnD, + output logic FRegWriteD, output logic FDivStartD, output logic [2:0] FResultSelD, output logic [3:0] FOpCtrlD, @@ -21,7 +21,7 @@ module fctrl ( // FPU Instruction Decoder always_comb case(OpD) - // FWriteEn_FWriteInt_FResultSel_FOpCtrl_FResSel_FIntResSel_FDivStart_IllegalFPUInstr + // FRegWrite_FWriteInt_FResultSel_FOpCtrl_FResSel_FIntResSel_FDivStart_IllegalFPUInstr 7'b0000111: case(Funct3D) 3'b010: ControlsD = `FCTRLW'b1_0_000_0000_00_00_0_0; // flw 3'b011: ControlsD = `FCTRLW'b1_0_000_0001_00_00_0_0; // fld @@ -101,7 +101,7 @@ module fctrl ( default: ControlsD = `FCTRLW'b0_0_000_0000_00_00_0_1; // non-implemented instruction endcase // unswizzle control bits - assign {FWriteEnD, FWriteIntD, FResultSelD, FOpCtrlD, FResSelD, FIntResSelD, FDivStartD, IllegalFPUInstrD} = ControlsD; + assign {FRegWriteD, FWriteIntD, FResultSelD, FOpCtrlD, FResSelD, FIntResSelD, FDivStartD, IllegalFPUInstrD} = ControlsD; // if dynamic rounding, choose FRM_REGW assign FrmD = &Funct3D ? FRM_REGW : Funct3D; diff --git a/wally-pipelined/src/fpu/fcvt.sv b/wally-pipelined/src/fpu/fcvt.sv index bf652a7fd..3c72b5d09 100644 --- a/wally-pipelined/src/fpu/fcvt.sv +++ b/wally-pipelined/src/fpu/fcvt.sv @@ -20,15 +20,15 @@ module fcvt ( logic [11:0] Bias; // 1023 for double, 127 for single logic [7:0] Bits; // how many bits are in the integer result logic [7:0] SubBits; // subtract these bits from the exponent (FP result) - logic [`XLEN+51:0] ShiftedManTmp; // Shifted mantissa - logic [`XLEN+51:0] ShiftVal; // value being shifted (to int - XMan, to FP - |integer input|) - logic [`XLEN+1:0] ShiftedMan; // shifted mantissa truncated + logic [64+51:0] ShiftedManTmp; // Shifted mantissa + logic [64+51:0] ShiftVal; // value being shifted (to int - XMan, to FP - |integer input|) + logic [64+1:0] ShiftedMan; // shifted mantissa truncated logic [64:0] RoundedTmp; // full size rounded result - in case of overfow logic [63:0] Rounded; // rounded result logic [12:0] ExpVal; // unbiased X exponent logic [12:0] ShiftCnt; // how much is the mantissa shifted - logic [`XLEN-1:0] IntIn; // trimed integer input - logic [`XLEN-1:0] PosInt; // absolute value of the integer input + logic [64-1:0] IntIn; // trimed integer input + logic [64-1:0] PosInt; // absolute value of the integer input logic [63:0] CvtIntRes; // interger result from the fp -> int instructions logic [63:0] CvtFPRes; // floating point result from the int -> fp instructions logic XFracZero; // is the fraction of X zero? @@ -63,9 +63,9 @@ module fcvt ( // {long, unsigned, to int, from int} // split the input into it's various parts - assign XSgn = X[63]; - assign XExp = FmtE ? X[62:52] : {3'b0, X[62:55]}; - assign XFrac = FmtE ? X[51:0] : {X[54:32], 29'b0}; + assign XSgn = FmtE ? X[63] : X[31]; + assign XExp = FmtE ? X[62:52] : {3'b0, X[30:23]}; + assign XFrac = FmtE ? X[51:0] : {X[23:0], 29'b0}; // determine if the exponent and fraction are all zero or ones assign XExpZero = ~|XExp; @@ -91,7 +91,7 @@ module fcvt ( //////////////////////////////////////////////////////// // position the input in the most significant bits - assign IntIn = FOpCtrlE[3] ? SrcAE : {SrcAE[31:0], 32'b0}; + assign IntIn = FOpCtrlE[3] ? {SrcAE, {64-`XLEN{1'b0}}} : {SrcAE[31:0], 32'b0}; // make the integer positive assign PosInt = IntIn[64-1]&~FOpCtrlE[2] ? -IntIn : IntIn; // determine the integer's sign @@ -99,9 +99,9 @@ module fcvt ( // This did not work \/ // generate - // if(`XLEN == 64) + // if(64 == 64) // lz64 lz(LZResP, LZResV, PosInt); - // else if(`XLEN == 32) begin + // else if(64 == 32) begin // assign LZResP[5] = 1'b0; // lz32 lz(LZResP[4:0], LZResV, PosInt); // end @@ -111,12 +111,12 @@ module fcvt ( logic [8:0] i; always_comb begin i = 0; - while (~PosInt[64-1-i] && i <= 64) i = i+1; // search for leading one + while (~PosInt[64-1-i] && i <= `XLEN) i = i+1; // search for leading one LZResP = i+1; // compute shift count end // if no one was found set to zero otherwise calculate the exponent - assign TmpExp = i==64 ? 0 : Bias + SubBits - LZResP; + assign TmpExp = i==`XLEN ? 0 : Bias + SubBits - LZResP; @@ -126,12 +126,12 @@ module fcvt ( // select the shift value and amount based on operation (to fp or int) assign ShiftCnt = FOpCtrlE[1] ? ExpVal : LZResP; - assign ShiftVal = FOpCtrlE[1] ? {{`XLEN-2{1'b0}}, ~(XDenorm|XZero), XFrac} : {PosInt, 52'b0}; + assign ShiftVal = FOpCtrlE[1] ? {{64-2{1'b0}}, ~(XDenorm|XZero), XFrac} : {PosInt, 52'b0}; // if shift = -1 then shift one bit right for gaurd bit (right shifting twice never rounds) // if the shift is negitive add a bit for sticky bit calculation // otherwise shift left - assign ShiftedManTmp = &ShiftCnt ? {{`XLEN-1{1'b0}}, ~(XDenorm|XZero), XFrac[51:1]} : ShiftCnt[12] ? {{`XLEN+51{1'b0}}, ~XZero} : ShiftVal << ShiftCnt; + assign ShiftedManTmp = &ShiftCnt ? {{64-1{1'b0}}, ~(XDenorm|XZero), XFrac[51:1]} : ShiftCnt[12] ? {{64+51{1'b0}}, ~XZero} : ShiftVal << ShiftCnt; // truncate the shifted mantissa assign ShiftedMan = ShiftedManTmp[64+51:50]; @@ -185,12 +185,12 @@ module fcvt ( assign SgnRes = ~FOpCtrlE[3] & FOpCtrlE[1]; // select the integer result - assign CvtIntRes = Of ? FOpCtrlE[2] ? SgnRes ? {32'b0, {32{1'b1}}}: {64{1'b1}} : SgnRes ? {33'b0, {31{1'b1}}}: {1'b0, {63{1'b1}}} : + assign CvtIntRes = Of ? FOpCtrlE[2] ? {64{1'b1}} : SgnRes ? {33'b0, {31{1'b1}}}: {1'b0, {63{1'b1}}} : Uf ? FOpCtrlE[2] ? 64'b0 : SgnRes ? {32'b0, 1'b1, 31'b0} : {1'b1, 63'b0} : Rounded[64-1:0]; // select the floating point result - assign CvtFPRes = FmtE ? {ResSgn, ResExp, ResFrac} : {ResSgn, ResExp[7:0], ResFrac, 3'b0}; + assign CvtFPRes = FmtE ? {ResSgn, ResExp, ResFrac} : {{32{1'b1}}, ResSgn, ResExp[7:0], ResFrac[51:29]}; // select the result assign CvtResE = FOpCtrlE[0] ? CvtFPRes : CvtIntRes; diff --git a/wally-pipelined/src/fpu/fhazard.sv b/wally-pipelined/src/fpu/fhazard.sv index 53f7dde2c..e77d64241 100644 --- a/wally-pipelined/src/fpu/fhazard.sv +++ b/wally-pipelined/src/fpu/fhazard.sv @@ -27,7 +27,7 @@ module fhazard( input logic [4:0] Adr1E, Adr2E, Adr3E, - input logic FWriteEnM, FWriteEnW, + input logic FRegWriteM, FRegWriteW, input logic [4:0] RdM, RdW, input logic [2:0] FResultSelM, output logic FStallD, @@ -42,25 +42,25 @@ module fhazard( ForwardZE = 2'b00; // choose FRD3E FStallD = 0; - if ((Adr1E == RdM) & FWriteEnM) + if ((Adr1E == RdM) & FRegWriteM) // if the result will be FResM if(FResultSelM == 3'b100) ForwardXE = 2'b10; // choose FResM else FStallD = 1; // if the result won't be ready stall - else if ((Adr1E == RdW) & FWriteEnW) ForwardXE = 2'b01; // choose FPUResult64W + else if ((Adr1E == RdW) & FRegWriteW) ForwardXE = 2'b01; // choose FPUResult64W - if ((Adr2E == RdM) & FWriteEnM) + if ((Adr2E == RdM) & FRegWriteM) // if the result will be FResM if(FResultSelM == 3'b100) ForwardYE = 2'b10; // choose FResM else FStallD = 1; // if the result won't be ready stall - else if ((Adr2E == RdW) & FWriteEnW) ForwardYE = 2'b01; // choose FPUResult64W + else if ((Adr2E == RdW) & FRegWriteW) ForwardYE = 2'b01; // choose FPUResult64W - if ((Adr3E == RdM) & FWriteEnM) + if ((Adr3E == RdM) & FRegWriteM) // if the result will be FResM if(FResultSelM == 3'b100) ForwardZE = 2'b10; // choose FResM else FStallD = 1; // if the result won't be ready stall - else if ((Adr3E == RdW) & FWriteEnW) ForwardZE = 2'b01; // choose FPUResult64W + else if ((Adr3E == RdW) & FRegWriteW) ForwardZE = 2'b01; // choose FPUResult64W end diff --git a/wally-pipelined/src/fpu/fpu.sv b/wally-pipelined/src/fpu/fpu.sv index 0ff199129..1f878cb1f 100755 --- a/wally-pipelined/src/fpu/fpu.sv +++ b/wally-pipelined/src/fpu/fpu.sv @@ -34,6 +34,7 @@ module fpu ( input logic [`XLEN-1:0] SrcAM, // Integer input being written into fpreg input logic StallE, StallM, StallW, input logic FlushE, FlushM, FlushW, + output logic FRegWriteM, output logic FStallD, // Stall the decode stage output logic FWriteIntE, FWriteIntM, FWriteIntW, // Write integer register enable output logic [`XLEN-1:0] FWriteDataE, // Data to be written to memory @@ -46,7 +47,7 @@ module fpu ( generate if (`F_SUPPORTED | `D_SUPPORTED) begin // control logic signal instantiation - logic FWriteEnD, FWriteEnE, FWriteEnM, FWriteEnW; // FP register write enable + logic FRegWriteD, FRegWriteE, FRegWriteW; // FP register write enable logic [2:0] FrmD, FrmE, FrmM; // FP rounding mode logic FmtD, FmtE, FmtM, FmtW; // FP precision 0-single 1-double logic FDivStartD, FDivStartE; // Start division @@ -120,11 +121,11 @@ module fpu ( // top-level controller for FPU fctrl fctrl (.Funct7D(InstrD[31:25]), .OpD(InstrD[6:0]), .Rs2D(InstrD[24:20]), .Funct3D(InstrD[14:12]), - .FRM_REGW, .IllegalFPUInstrD, .FWriteEnD, .FDivStartD, .FResultSelD, .FOpCtrlD, .FResSelD, + .FRM_REGW, .IllegalFPUInstrD, .FRegWriteD, .FDivStartD, .FResultSelD, .FOpCtrlD, .FResSelD, .FIntResSelD, .FmtD, .FrmD, .FWriteIntD); // regfile instantiation - fregfile fregfile (clk, reset, FWriteEnW, + fregfile fregfile (clk, reset, FRegWriteW, InstrD[19:15], InstrD[24:20], InstrD[31:27], RdW, FPUResultW, FRD1D, FRD2D, FRD3D); @@ -147,8 +148,8 @@ module fpu ( flopenrc #(15) DECtrlRegE2(clk, reset, FlushE, ~StallE, {InstrD[19:15], InstrD[24:20], InstrD[31:27]}, {Adr1E, Adr2E, Adr3E}); flopenrc #(22) DECtrlReg3(clk, reset, FlushE, ~StallE, - {FWriteEnD, FResultSelD, FResSelD, FIntResSelD, FrmD, FmtD, InstrD[11:7], FOpCtrlD, FWriteIntD}, - {FWriteEnE, FResultSelE, FResSelE, FIntResSelE, FrmE, FmtE, RdE, FOpCtrlE, FWriteIntE}); + {FRegWriteD, FResultSelD, FResSelD, FIntResSelD, FrmD, FmtD, InstrD[11:7], FOpCtrlD, FWriteIntD}, + {FRegWriteE, FResultSelE, FResSelE, FIntResSelE, FrmE, FmtE, RdE, FOpCtrlE, FWriteIntE}); @@ -166,7 +167,7 @@ module fpu ( //EXECUTION STAGE // Hazard unit for FPU - fhazard fhazard(.Adr1E, .Adr2E, .Adr3E, .FWriteEnM, .FWriteEnW, .RdM, .RdW, .FResultSelM, .FStallD, + fhazard fhazard(.Adr1E, .Adr2E, .Adr3E, .FRegWriteM, .FRegWriteW, .RdM, .RdW, .FResultSelM, .FStallD, .ForwardXE, .ForwardYE, .ForwardZE); // forwarding muxs @@ -220,7 +221,8 @@ module fpu ( fcvt fcvt (.X(SrcXE), .SrcAE, .FOpCtrlE, .FmtE, .FrmE, .CvtResE, .CvtFlgE); // output for store instructions - mux2 #(`XLEN) FWriteDataMux({{`XLEN-32{1'b0}}, SrcYE[63:32]}, SrcYE[63:64-`XLEN], FmtE, FWriteDataE); + // mux2 #(`XLEN) FWriteDataMux({{`XLEN-32{1'b0}}, SrcYE[63:32]}, SrcYE[63:64-`XLEN], FmtE, FWriteDataE); + assign FWriteDataE = SrcYE[`XLEN-1:0]; @@ -249,8 +251,8 @@ module fpu ( flopenrc #(5) EMRegCvt2(clk, reset, FlushM, ~StallM, CvtFlgE, CvtFlgM); flopenrc #(22) EMCtrlReg(clk, reset, FlushM, ~StallM, - {FWriteEnE, FResultSelE, FResSelE, FIntResSelE, FrmE, FmtE, RdE, FOpCtrlE, FWriteIntE}, - {FWriteEnM, FResultSelM, FResSelM, FIntResSelM, FrmM, FmtM, RdM, FOpCtrlM, FWriteIntM}); + {FRegWriteE, FResultSelE, FResSelE, FIntResSelE, FrmE, FmtE, RdE, FOpCtrlE, FWriteIntE}, + {FRegWriteM, FResultSelM, FResSelM, FIntResSelM, FrmM, FmtM, RdM, FOpCtrlM, FWriteIntM}); flopenrc #(64) EMRegClass(clk, reset, FlushM, ~StallM, ClassResE, ClassResM); @@ -266,23 +268,15 @@ module fpu ( mux4 #(64) FResMux(AlignedSrcAM, SgnResM, CmpResM, CvtResM, FResSelM, FResM); mux4 #(5) FFlgMux(5'b0, {4'b0, SgnNVM}, {4'b0, CmpNVM}, CvtFlgM, FResSelM, FFlgM); - mux2 #(`XLEN) SrcXAlignedMux({{`XLEN-32{1'b0}}, SrcXM[63:32]}, SrcXM[63:64-`XLEN], FmtM, SrcXMAligned); - mux4 #(`XLEN) IntResMux(CmpResM[`XLEN-1:0], SrcXMAligned, ClassResM[`XLEN-1:0], CvtResM[`XLEN-1:0], FIntResSelM, FIntResM); + // mux2 #(`XLEN) SrcXAlignedMux({{`XLEN-32{1'b0}}, SrcXM[63:32]}, SrcXM[63:64-`XLEN], FmtM, SrcXMAligned); + mux4 #(`XLEN) IntResMux(CmpResM[`XLEN-1:0], SrcXM[`XLEN-1:0], ClassResM[`XLEN-1:0], CvtResM[`XLEN-1:0], FIntResSelM, FIntResM); // Align SrcA to MSB when single precicion - mux2 #(64) SrcAMux({SrcAM[31:0], 32'b0}, {{64-`XLEN{1'b0}}, SrcAM}, FmtM, AlignedSrcAM); + mux2 #(64) SrcAMux({{32{1'b1}}, SrcAM[31:0]}, {{64-`XLEN{1'b1}}, SrcAM}, FmtM, AlignedSrcAM); - always_comb begin - case (FResultSelM) - 3'b000 : SetFflagsM = 5'b0; - 3'b001 : SetFflagsM = FMAFlgM; - 3'b010 : SetFflagsM = FAddFlgM; - 3'b011 : SetFflagsM = FDivSqrtFlgM; - 3'b100 : SetFflagsM = FFlgM; - default : SetFflagsM = 5'bxxxxx; - endcase - end + + mux5 #(5) FPUFlgMux(5'b0, FMAFlgM, FAddFlgM, FDivSqrtFlgM, FFlgM, FResultSelW, SetFflagsM); @@ -305,8 +299,8 @@ module fpu ( flopenrc #(64) MWRegClass2(clk, reset, FlushW, ~StallW, FResM, FResW); flopenrc #(11) MWCtrlReg(clk, reset, FlushW, ~StallW, - {FWriteEnM, FResultSelM, RdM, FmtM, FWriteIntM}, - {FWriteEnW, FResultSelW, RdW, FmtW, FWriteIntW}); + {FRegWriteM, FResultSelM, RdM, FmtM, FWriteIntM}, + {FRegWriteW, FResultSelW, RdW, FmtW, FWriteIntW}); @@ -318,7 +312,7 @@ module fpu ( //######################################### - mux2 #(64) ReadResMux({ReadDataW[31:0], 32'b0}, {ReadDataW, {64-`XLEN{1'b0}}}, FmtW, ReadResW); + mux2 #(64) ReadResMux({{32{1'b1}}, ReadDataW[31:0]}, {{64-`XLEN{1'b1}}, ReadDataW}, FmtW, ReadResW); mux5 #(64) FPUResultMux(ReadResW, FMAResW, FAddResW, FDivResultW, FResW, FResultSelW, FPUResultW); diff --git a/wally-pipelined/src/fpu/rounder_denorm.sv b/wally-pipelined/src/fpu/rounder_denorm.sv index b6793594c..b8128e631 100755 --- a/wally-pipelined/src/fpu/rounder_denorm.sv +++ b/wally-pipelined/src/fpu/rounder_denorm.sv @@ -258,7 +258,7 @@ module rounder (Result, DenormIO, Flags, rm, P, OvEn, // is being performed. assign OvCon = OverFlow & OvEn & convert; - assign Result = (op_type[3]) ? {A[63:0]} : (DenormIn ? {Rsign, Rexp_denorm, ShiftMant} : ((P&~OvCon) ? {Rsign, Rexp[7:0], Rmant[51:29], {32{VSS}}} + assign Result = (op_type[3]) ? {A[63:0]} : (DenormIn ? {Rsign, Rexp_denorm, ShiftMant} : ((P&~OvCon) ? {{32{1'b1}}, Rsign, Rexp[7:0], Rmant[51:29]} : {Rsign, Rexp, Rmant})); endmodule // rounder diff --git a/wally-pipelined/src/privileged/csr.sv b/wally-pipelined/src/privileged/csr.sv index a618e8d6d..3b039f5ca 100644 --- a/wally-pipelined/src/privileged/csr.sv +++ b/wally-pipelined/src/privileged/csr.sv @@ -40,7 +40,7 @@ module csr #(parameter input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM, input logic TimerIntM, ExtIntM, SwIntM, input logic [63:0] MTIME_CLINT, MTIMECMP_CLINT, - input logic InstrValidW, FloatRegWriteW, LoadStallD, + input logic InstrValidW, FRegWriteM, LoadStallD, input logic BPPredDirWrongM, input logic BTBPredPCWrongM, input logic RASPredPCWrongM, @@ -77,6 +77,7 @@ module csr #(parameter logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM; logic CSRMWriteM, CSRSWriteM, CSRUWriteM; logic STATUS_TVM; + logic WriteFRMM, WriteFFLAGSM; logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextCauseM, NextMtvalM; diff --git a/wally-pipelined/src/privileged/csrsr.sv b/wally-pipelined/src/privileged/csrsr.sv index dd492b6f1..6b6eee270 100644 --- a/wally-pipelined/src/privileged/csrsr.sv +++ b/wally-pipelined/src/privileged/csrsr.sv @@ -29,9 +29,10 @@ module csrsr ( input logic clk, reset, StallW, input logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM, - input logic TrapM, FloatRegWriteW, + input logic TrapM, FRegWriteM, input logic [1:0] NextPrivilegeModeM, PrivilegeModeW, input logic mretM, sretM, uretM, + input logic WriteFRMM, WriteFFLAGSM, input logic [`XLEN-1:0] CSRWriteValM, output logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, USTATUS_REGW, output logic [1:0] STATUS_MPP, @@ -125,8 +126,8 @@ module csrsr ( STATUS_SIE <= #1 0; //`S_SUPPORTED; STATUS_UIE <= #1 0; //`U_SUPPORTED; end else if (~StallW) begin - if (FloatRegWriteW) STATUS_FS_INT <= #12'b11; // mark Float State dirty *** this should happen in M stage, be part of if/else; - // *** also, FS_INT needs to be set when any bits of the fcsr are written + if (FRegWriteM | WriteFRMM | WriteFFLAGSM) STATUS_FS_INT <= #12'b11; // mark Float State dirty *** this should happen in M stage, be part of if/else; + if (TrapM) begin // Update interrupt enables per Privileged Spec p. 21 // y = PrivilegeModeW diff --git a/wally-pipelined/src/privileged/csru.sv b/wally-pipelined/src/privileged/csru.sv index 08e682bfd..22ed4dcb3 100644 --- a/wally-pipelined/src/privileged/csru.sv +++ b/wally-pipelined/src/privileged/csru.sv @@ -39,6 +39,7 @@ module csru #(parameter output logic [`XLEN-1:0] CSRUReadValM, input logic [4:0] SetFflagsM, output logic [2:0] FRM_REGW, + output logic WriteFRMM, WriteFFLAGSM, output logic IllegalCSRUAccessM ); diff --git a/wally-pipelined/src/privileged/privileged.sv b/wally-pipelined/src/privileged/privileged.sv index e80c0b851..0c123c5c7 100644 --- a/wally-pipelined/src/privileged/privileged.sv +++ b/wally-pipelined/src/privileged/privileged.sv @@ -39,7 +39,7 @@ module privileged ( output logic RetM, TrapM, NonBusTrapM, output logic ITLBFlushF, DTLBFlushM, input logic InstrValidM,InstrValidW, CommittedM, - input logic FloatRegWriteW, LoadStallD, + input logic FRegWriteM, LoadStallD, input logic BPPredDirWrongM, input logic BTBPredPCWrongM, input logic RASPredPCWrongM, diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index 3b589456f..74e8adbb9 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -100,7 +100,7 @@ module wallypipelinedhart logic [`XLEN-1:0] FIntResM; logic FDivBusyE; logic IllegalFPUInstrD, IllegalFPUInstrE; - logic FloatRegWriteW; + logic FRegWriteM; logic FPUStallD; logic [4:0] SetFflagsM; logic [`XLEN-1:0] FPUResultW; @@ -272,8 +272,8 @@ module wallypipelinedhart fpu fpu(.*); // floating point unit // add FPU here, with SetFflagsM, FRM_REGW - // presently stub out SetFlagsM and FloatRegWriteW + // presently stub out SetFlagsM and FRegWriteM //assign SetFflagsM = 0; - //assign FloatRegWriteW = 0; + //assign FRegWriteM = 0; endmodule diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index b017ef8d8..1fd45595d 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -57,14 +57,14 @@ module testbench(); string tests32f[] = '{ "rv32f/I-FADD-S-01", "2000", "rv32f/I-FCLASS-S-01", "2000", - // "rv32f/I-FCVT-S-L-01", "2000", - // "rv32f/I-FCVT-S-LU-01", "2000", - // "rv32f/I-FCVT-S-W-01", "2000", - // "rv32f/I-FCVT-S-WU-01", "2000", - // "rv32f/I-FCVT-L-S-01", "2000", - // "rv32f/I-FCVT-LU-S-01", "2000", - // "rv32f/I-FCVT-W-S-01", "2000", - // "rv32f/I-FCVT-WU-S-01", "2000", + "rv32f/I-FCVT-S-L-01", "2000", + "rv32f/I-FCVT-S-LU-01", "2000", + "rv32f/I-FCVT-S-W-01", "2000", + "rv32f/I-FCVT-S-WU-01", "2000", + "rv32f/I-FCVT-L-S-01", "2000", + "rv32f/I-FCVT-LU-S-01", "2000", + "rv32f/I-FCVT-W-S-01", "2000", + "rv32f/I-FCVT-WU-S-01", "2000", // "rv32f/I-FDIV-S-01", "2000", "rv32f/I-FEQ-S-01", "2000", "rv32f/I-FLE-S-01", "2000", @@ -121,19 +121,21 @@ string tests32f[] = '{ }; string tests64d[] = '{ + "rv64d/I-FSD-01", "2000", + "rv64d/I-FLD-01", "2420", + "rv64d/I-FMV-X-D-01", "2000", + "rv64d/I-FMV-D-X-01", "2000", // "rv64d/I-FDIV-D-01", "2000", "rv64d/I-FCVT-D-L-01", "2000", "rv64d/I-FCVT-D-LU-01", "2000", - // "rv64d/I-FCVT-D-S-01", "2000", //the number to be converted is in the lower 32 bits need to change the test + "rv64d/I-FCVT-D-S-01", "2000", //the number to be converted is in the lower 32 bits need to change the test "rv64d/I-FCVT-D-W-01", "2000", "rv64d/I-FCVT-D-WU-01", "2000", "rv64d/I-FCVT-L-D-01", "2000", "rv64d/I-FCVT-LU-D-01", "2000", - // "rv64d/I-FCVT-S-D-01", "2000", //the result is in the lower 32 bits needs to be changed in the imperas test + "rv64d/I-FCVT-S-D-01", "2000", //the result is in the lower 32 bits needs to be changed in the imperas test "rv64d/I-FCVT-W-D-01", "2000", - // "rv64d/I-FCVT-WU-D-01", "2000", //this test needs to be fixed it expects 2^64-1 rather then 2^32-1 (specified in spec) - "rv64d/I-FSD-01", "2000", - "rv64d/I-FLD-01", "2420", + "rv64d/I-FCVT-WU-D-01", "2000", //this test needs to be fixed it expects 2^64-1 rather then 2^32-1 (specified in spec) "rv64d/I-FNMADD-D-01", "2000", "rv64d/I-FNMSUB-D-01", "2000", "rv64d/I-FMSUB-D-01", "2000", @@ -146,8 +148,6 @@ string tests32f[] = '{ "rv64d/I-FCLASS-D-01", "2000", "rv64d/I-FMADD-D-01", "2000", "rv64d/I-FMUL-D-01", "2000", - "rv64d/I-FMV-D-X-01", "2000", - "rv64d/I-FMV-X-D-01", "2000", "rv64d/I-FSGNJ-D-01", "2000", "rv64d/I-FSGNJN-D-01", "2000", "rv64d/I-FSGNJX-D-01", "2000", @@ -556,8 +556,8 @@ string tests32f[] = '{ if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic}; else tests = {tests, tests32iNOc}; if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m}; - if (`F_SUPPORTED) tests = {tests32f, tests}; if (`A_SUPPORTED) tests = {tests, tests32a}; + if (`F_SUPPORTED) tests = {tests32f, tests}; //if (`MEM_VIRTMEM) tests = {tests, tests32mmu}; end end