This commit is contained in:
Rose Thompson 2024-01-23 14:37:11 -06:00
commit d5bbb5ea27
27 changed files with 607 additions and 166 deletions

View File

@ -11,8 +11,8 @@ sources=$(cmbase)/core_main.c $(cmbase)/core_list_join.c $(cmbase)/coremark.h \
$(PORT_DIR)/core_portme.h $(PORT_DIR)/core_portme.c $(PORT_DIR)/core_portme.mak \ $(PORT_DIR)/core_portme.h $(PORT_DIR)/core_portme.c $(PORT_DIR)/core_portme.mak \
$(PORT_DIR)/crt.S $(PORT_DIR)/encoding.h $(PORT_DIR)/util.h $(PORT_DIR)/syscalls.c $(PORT_DIR)/crt.S $(PORT_DIR)/encoding.h $(PORT_DIR)/util.h $(PORT_DIR)/syscalls.c
ABI := $(if $(findstring "64","$(XLEN)"),lp64,ilp32) ABI := $(if $(findstring "64","$(XLEN)"),lp64,ilp32)
ARCH := rv$(XLEN)im_zicsr_zba_zbb_zbc_zbs #ARCH := rv$(XLEN)gc_zba_zbb_zbc
#ARCH := rv$(XLEN)gc_zba_zbb_zbc_zbs ARCH := rv$(XLEN)im_zicsr_zba_zbb_zbc
#ARCH := rv$(XLEN)gc #ARCH := rv$(XLEN)gc
#ARCH := rv$(XLEN)imc_zicsr #ARCH := rv$(XLEN)imc_zicsr
#ARCH := rv$(XLEN)im_zicsr #ARCH := rv$(XLEN)im_zicsr
@ -25,24 +25,6 @@ PORT_CFLAGS = -g -mabi=$(ABI) -march=$(ARCH) -static -falign-functions=16 \
-nostdlib -nostartfiles -ffreestanding -mstrict-align \ -nostdlib -nostartfiles -ffreestanding -mstrict-align \
-DTOTAL_DATA_SIZE=2000 -DMAIN_HAS_NOARGC=1 -DPERFORMANCE_RUN=1 -DITERATIONS=10 -DXLEN=$(XLEN) -DTOTAL_DATA_SIZE=2000 -DMAIN_HAS_NOARGC=1 -DPERFORMANCE_RUN=1 -DITERATIONS=10 -DXLEN=$(XLEN)
# Black Parrott
#PORT_CFLAGS = -O2 -fno-common -funroll-loops -finline-functions --param max-inline-insns-auto=20 -falign-functions=4 -falign-jumps=4 -falign-loops=4 \
-DITERATIONS=10 -DPERFORMANCE_RUN=1
#OPTIMIZE := -O2 -fno-common -funroll-loops -finline-functions --param max-inline-insns-auto=20 -falign-functions=4 -falign-jumps=4 -falign-loops=4
#override CFLAGS += $(OPTIMIZE) -DFLAGS_STR=\""$(OPTIMIZE)"\"
#override CFLAGS += -DITERATIONS=10 -DPERFORMANCE_RUN=1
# try adding the new fields from muntjac coremark build
#PORT_CFLAGS = -g -mabi=$(ABI) -march=$(ARCH) -static -falign-functions=16 \
-fno-common -flto -funswitch-loops -mcmodel=medany \
-falign-functions=4 -falign-jumps=4 -falign-loops=4 \
-mbranch-cost=1 -DSKIP_DEFAULT_MEMSET -mtune=sifive-3-series -O3 -finline-functions --param max-inline-insns-auto=20 -falign-jumps=4 \
-fno-delete-null-pointer-checks -fno-rename-registers --param=loop-max-datarefs-for-datadeps=0 \
-funroll-all-loops --param=uninlined-function-insns=8 -fno-tree-vrp -fwrapv -fipa-pta \
-nostdlib -nostartfiles -ffreestanding -mstrict-align \
-DTOTAL_DATA_SIZE=2000 -DMAIN_HAS_NOARGC=1 -DPERFORMANCE_RUN=1 -DITERATIONS=10 -DXLEN=$(XLEN)
all: $(work_dir)/coremark.bare.riscv.elf.memfile all: $(work_dir)/coremark.bare.riscv.elf.memfile
run: run:

View File

@ -177,6 +177,7 @@ void _init(int cid, int nc)
counters[17] = read_csr(mhpmcounter17) - counters[17]; counters[17] = read_csr(mhpmcounter17) - counters[17];
ee_printf("Load Stalls %d\n", counters[11]); ee_printf("Load Stalls %d\n", counters[11]);
ee_printf("Store Stalls %d\n", counters[12]);
ee_printf("D-Cache Accesses %d\n", counters[13]); ee_printf("D-Cache Accesses %d\n", counters[13]);
ee_printf("D-Cache Misses %d\n", counters[14]); ee_printf("D-Cache Misses %d\n", counters[14]);
ee_printf("I-Cache Accesses %d\n", counters[16]); ee_printf("I-Cache Accesses %d\n", counters[16]);

View File

@ -40,7 +40,7 @@ localparam ZIFENCEI_SUPPORTED = 1;
localparam ZICNTR_SUPPORTED = 1; localparam ZICNTR_SUPPORTED = 1;
localparam ZIHPM_SUPPORTED = 1; localparam ZIHPM_SUPPORTED = 1;
localparam COUNTERS = 12'd32; localparam COUNTERS = 12'd32;
localparam ZFH_SUPPORTED = 0; localparam ZFH_SUPPORTED = 1;
localparam ZFA_SUPPORTED = 0; localparam ZFA_SUPPORTED = 0;
localparam SSTC_SUPPORTED = 1; localparam SSTC_SUPPORTED = 1;
localparam ZICBOM_SUPPORTED = 1; localparam ZICBOM_SUPPORTED = 1;
@ -57,7 +57,7 @@ localparam BUS_SUPPORTED = 1;
localparam DCACHE_SUPPORTED = 1; localparam DCACHE_SUPPORTED = 1;
localparam ICACHE_SUPPORTED = 1; localparam ICACHE_SUPPORTED = 1;
localparam VIRTMEM_SUPPORTED = 1; localparam VIRTMEM_SUPPORTED = 1;
localparam VECTORED_INTERRUPTS_SUPPORTED = 1 ; localparam VECTORED_INTERRUPTS_SUPPORTED = 1;
localparam BIGENDIAN_SUPPORTED = 1; localparam BIGENDIAN_SUPPORTED = 1;
// TLB configuration. Entries should be a power of 2 // TLB configuration. Entries should be a power of 2
@ -163,10 +163,10 @@ localparam RADIX = 32'h4;
localparam DIVCOPIES = 32'h4; localparam DIVCOPIES = 32'h4;
// bit manipulation // bit manipulation
localparam ZBA_SUPPORTED = 0; localparam ZBA_SUPPORTED = 1;
localparam ZBB_SUPPORTED = 0; localparam ZBB_SUPPORTED = 1;
localparam ZBC_SUPPORTED = 0; localparam ZBC_SUPPORTED = 1;
localparam ZBS_SUPPORTED = 0; localparam ZBS_SUPPORTED = 1;
// New compressed instructions // New compressed instructions
localparam ZCB_SUPPORTED = 1; localparam ZCB_SUPPORTED = 1;

View File

@ -41,8 +41,8 @@ localparam ZIFENCEI_SUPPORTED = 1;
localparam COUNTERS = 12'd32; localparam COUNTERS = 12'd32;
localparam ZICNTR_SUPPORTED = 1; localparam ZICNTR_SUPPORTED = 1;
localparam ZIHPM_SUPPORTED = 1; localparam ZIHPM_SUPPORTED = 1;
localparam ZFH_SUPPORTED = 0; localparam ZFH_SUPPORTED = 1;
localparam ZFA_SUPPORTED = 0; localparam ZFA_SUPPORTED = 1;
localparam SSTC_SUPPORTED = 1; localparam SSTC_SUPPORTED = 1;
localparam ZICBOM_SUPPORTED = 1; localparam ZICBOM_SUPPORTED = 1;
localparam ZICBOZ_SUPPORTED = 1; localparam ZICBOZ_SUPPORTED = 1;

View File

@ -111,7 +111,7 @@ localparam LLEN = (($unsigned(FLEN)<$unsigned(XLEN)) ? ($unsigned(XLEN)) : ($uns
localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1)); localparam LOGCVTLEN = $unsigned($clog2(CVTLEN+1));
localparam NORMSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVb + 1 +NF+1) > (3*NF+6) ? (DIVb + 1 +NF+1) : (3*NF+6))); localparam NORMSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVb + 1 +NF+1) > (3*NF+6) ? (DIVb + 1 +NF+1) : (3*NF+6)));
localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ)); localparam LOGNORMSHIFTSZ = ($clog2(NORMSHIFTSZ));
localparam CORRSHIFTSZ = (((CVTLEN+NF+1)>(DIVb + 1 +NF+1) & (CVTLEN+NF+1)>(3*NF+6)) ? (CVTLEN+NF+1) : ((DIVMINb+1+NF) > (3*NF+4) ? (DIVMINb+1+NF) : (3*NF+4))); localparam CORRSHIFTSZ = NORMSHIFTSZ-2;
// Disable spurious Verilator warnings // Disable spurious Verilator warnings

View File

@ -16,8 +16,7 @@ echo \$WALLY set to ${WALLY}
# Must edit these based on your local environment. Ask your sysadmin. # Must edit these based on your local environment. Ask your sysadmin.
export MGLS_LICENSE_FILE=27002@zircon.eng.hmc.edu # Change this to your Siemens license server export MGLS_LICENSE_FILE=27002@zircon.eng.hmc.edu # Change this to your Siemens license server
export SNPSLMD_LICENSE_FILE=27020@zircon.eng.hmc.edu # Change this to your Synopsys license server export SNPSLMD_LICENSE_FILE=27020@zircon.eng.hmc.edu # Change this to your Synopsys license server
export QUESTA_HOME=/cad/mentor/questa_sim-2022.4_2/questasim # Change this for your path to Questa, excluding bin export QUESTA_HOME=/cad/mentor/questa_sim-2023.4/questasim # Change this for your path to Questa, excluding bin
#export QUESTA_HOME=/cad/mentor/questa_sim-2022.4_3/questasim # Change this for your path to Questa, excluding bin
export SNPS_HOME=/cad/synopsys/SYN # Change this for your path to Design Compiler, excluding bin export SNPS_HOME=/cad/synopsys/SYN # Change this for your path to Design Compiler, excluding bin
# Path to RISC-V Tools # Path to RISC-V Tools

View File

@ -253,3 +253,10 @@ coverage exclude -srcfile priorityonehot.sv
# Excluding pmpadrdecs[0] coverage case for PAgePMPAdrIn being hardwired to 1 # Excluding pmpadrdecs[0] coverage case for PAgePMPAdrIn being hardwired to 1
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker/pmp/pmpadrdecs[0] -linerange [GetLineNum ../src/mmu/pmpadrdec.sv "exclusion-tag: PAgePMPAdrIn"] -item e 1 -fecexprrow 1 coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker/pmp/pmpadrdecs[0] -linerange [GetLineNum ../src/mmu/pmpadrdec.sv "exclusion-tag: PAgePMPAdrIn"] -item e 1 -fecexprrow 1
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmp/pmpchecker/pmp/pmpadrdecs[0] -linerange [GetLineNum ../src/mmu/pmpadrdec.sv "exclusion-tag: PAgePMPAdrIn"] -item e 1 -fecexprrow 1 coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmp/pmpchecker/pmp/pmpadrdecs[0] -linerange [GetLineNum ../src/mmu/pmpadrdec.sv "exclusion-tag: PAgePMPAdrIn"] -item e 1 -fecexprrow 1
####################
# EBU
####################
# Exclude EBU Beat Counter because it is only idle when bus has multicycle latency, but rv64gc has single cycle latency
coverage exclude -scope /core/ebu/ebu/ebufsmarb/BeatCounter

View File

@ -20,6 +20,7 @@
# More extensions # More extensions
--override cpu/Zcb=T --override cpu/Zcb=T
--override cpu/Zicond=T --override cpu/Zicond=T
--override cpu/Zfh=T
# Cache block operations # Cache block operations
--override cpu/Zicbom=T --override cpu/Zicbom=T
@ -36,6 +37,8 @@
# SV39 and SV48 supported # SV39 and SV48 supported
--override cpu/Sv_modes=768 --override cpu/Sv_modes=768
--override cpu/Svinval=T
# clarify # clarify
#--override refRoot/cpu/mtvec_sext=F #--override refRoot/cpu/mtvec_sext=F

View File

@ -36,6 +36,7 @@
module fcmp import cvw::*; #(parameter cvw_t P) ( module fcmp import cvw::*; #(parameter cvw_t P) (
input logic [P.FMTBITS-1:0] Fmt, // format of fp number input logic [P.FMTBITS-1:0] Fmt, // format of fp number
input logic [2:0] OpCtrl, // see above table input logic [2:0] OpCtrl, // see above table
input logic Zfa, // Zfa variants: fminm, fmaxm, fleq, fltq
input logic Xs, Ys, // input signs input logic Xs, Ys, // input signs
input logic [P.NE-1:0] Xe, Ye, // input exponents input logic [P.NE-1:0] Xe, Ye, // input exponents
input logic [P.NF:0] Xm, Ym, // input mantissa input logic [P.NF:0] Xm, Ym, // input mantissa
@ -70,8 +71,8 @@ module fcmp import cvw::*; #(parameter cvw_t P) (
3'b110: CmpNV = EitherSNaN; //min 3'b110: CmpNV = EitherSNaN; //min
3'b101: CmpNV = EitherSNaN; //max 3'b101: CmpNV = EitherSNaN; //max
3'b010: CmpNV = EitherSNaN; //equal 3'b010: CmpNV = EitherSNaN; //equal
3'b001: CmpNV = EitherNaN; //less than 3'b001: CmpNV = Zfa ? EitherSNaN : EitherNaN; // fltq / flt perform CompareQuietLess / CompareSignalingLess differing on when to set invalid
3'b011: CmpNV = EitherNaN; //less than or equal 3'b011: CmpNV = Zfa ? EitherSNaN : EitherNaN; // fleq / fle differ on when to set invalid
default: CmpNV = 1'bx; default: CmpNV = 1'bx;
endcase endcase
end end
@ -128,6 +129,12 @@ module fcmp import cvw::*; #(parameter cvw_t P) (
// - if one is a NaN output the non-NaN // - if one is a NaN output the non-NaN
always_comb always_comb
if(OpCtrl[0]) // MAX if(OpCtrl[0]) // MAX
if (Zfa & P.ZFA_SUPPORTED) // fmaxm perform IEEE754 maxNum that produce NaN if either input is NaN
if (XNaN | YNaN) CmpFpRes = NaNRes; // either input is NaN
else
if (LT) CmpFpRes = Y; // X < Y
else CmpFpRes = X; // X > Y
else // fmax performs IEEE754 maxNumber that produces NaN if both inputs are NaN
if(XNaN) if(XNaN)
if(YNaN) CmpFpRes = NaNRes; // X = NaN Y = NaN if(YNaN) CmpFpRes = NaNRes; // X = NaN Y = NaN
else CmpFpRes = Y; // X = NaN Y != NaN else CmpFpRes = Y; // X = NaN Y != NaN
@ -137,6 +144,12 @@ module fcmp import cvw::*; #(parameter cvw_t P) (
if(LT) CmpFpRes = Y; // X < Y if(LT) CmpFpRes = Y; // X < Y
else CmpFpRes = X; // X > Y else CmpFpRes = X; // X > Y
else // MIN else // MIN
if (Zfa & P.ZFA_SUPPORTED) // fminm perform IEEE754 minNum that produce NaN if either input is NaN
if (XNaN | YNaN) CmpFpRes = NaNRes; // either input is NaN
else
if (LT) CmpFpRes = X; // X < Y
else CmpFpRes = Y; // X > Y
else // fmin performs IEEE754 minNumber that produces NaN if both inputs are NaN
if(XNaN) if(XNaN)
if(YNaN) CmpFpRes = NaNRes; // X = NaN Y = NaN if(YNaN) CmpFpRes = NaNRes; // X = NaN Y = NaN
else CmpFpRes = Y; // X = NaN Y != NaN else CmpFpRes = Y; // X = NaN Y != NaN

View File

@ -54,6 +54,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
output logic [1:0] PostProcSelE, PostProcSelM, // select result in the post processing unit output logic [1:0] PostProcSelE, PostProcSelM, // select result in the post processing unit
output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage
output logic FPUActiveE, // FP instruction being executed output logic FPUActiveE, // FP instruction being executed
output logic ZfaE, ZfaM, // Zfa variants of instructions (fli, fminm, fmaxm, fround, froundnx, fleq, fltq, fmvh, fmvp, fcvtmod)
// register control signals // register control signals
output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable
output logic FWriteIntE, FWriteIntM, // Write to integer register output logic FWriteIntE, FWriteIntM, // Write to integer register
@ -64,7 +65,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
output logic FDivStartE, IDivStartE // Start division or squareroot output logic FDivStartE, IDivStartE // Start division or squareroot
); );
`define FCTRLW 12 `define FCTRLW 13
logic [`FCTRLW-1:0] ControlsD; // control signals logic [`FCTRLW-1:0] ControlsD; // control signals
logic FRegWriteD; // FP register write enable logic FRegWriteD; // FP register write enable
@ -79,6 +80,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
logic SupportedFmt; // is the format supported logic SupportedFmt; // is the format supported
logic SupportedFmt2; // is the source format supported for fp -> fp logic SupportedFmt2; // is the source format supported for fp -> fp
logic FCvtIntD, FCvtIntM; // convert to integer opperation logic FCvtIntD, FCvtIntM; // convert to integer opperation
logic ZfaD; // Zfa variants of instructions
// FPU Instruction Decoder // FPU Instruction Decoder
assign Fmt = Funct7D[1:0]; assign Fmt = Funct7D[1:0];
@ -91,127 +93,165 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
(Fmt2 == 2'b10 & P.ZFH_SUPPORTED) | (Fmt2 == 2'b11 & P.Q_SUPPORTED)); (Fmt2 == 2'b10 & P.ZFH_SUPPORTED) | (Fmt2 == 2'b11 & P.Q_SUPPORTED));
// decode the instruction // decode the instruction
// FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt // FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt_Zfa
always_comb always_comb
if (STATUS_FS == 2'b00) // FPU instructions are illegal when FPU is disabled if (STATUS_FS == 2'b00) // FPU instructions are illegal when FPU is disabled
ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0; ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0_0;
else if (OpD != 7'b0000111 & OpD != 7'b0100111 & ~SupportedFmt) else if (OpD != 7'b0000111 & OpD != 7'b0100111 & ~SupportedFmt)
ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0; // for anything other than loads and stores, check for supported format ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0_0; // for anything other than loads and stores, check for supported format
else begin else begin
ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0; // default: non-implemented instruction ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0_0; // default: non-implemented instruction
/* verilator lint_off CASEINCOMPLETE */ // default value above has priority so no other default needed /* verilator lint_off CASEINCOMPLETE */ // default value above has priority so no other default needed
case(OpD) case(OpD)
7'b0000111: case(Funct3D) 7'b0000111: case(Funct3D)
3'b010: ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0; // flw 3'b010: ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0_0; // flw
3'b011: if (P.D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0; // fld 3'b011: if (P.D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0_0; // fld
3'b100: if (P.Q_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0; // flq 3'b100: if (P.Q_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0_0; // flq
3'b001: if (P.ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0; // flh 3'b001: if (P.ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0_0; // flh
endcase endcase
7'b0100111: case(Funct3D) 7'b0100111: case(Funct3D)
3'b010: ControlsD = `FCTRLW'b0_0_10_00_0xx_0_0_0; // fsw 3'b010: ControlsD = `FCTRLW'b0_0_10_00_0xx_0_0_0_0; // fsw
3'b011: if (P.D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_00_0xx_0_0_0; // fsd 3'b011: if (P.D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_00_0xx_0_0_0_0; // fsd
3'b100: if (P.Q_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_00_0xx_0_0_0; // fsq 3'b100: if (P.Q_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_00_0xx_0_0_0_0; // fsq
3'b001: if (P.ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_00_0xx_0_0_0; // fsh 3'b001: if (P.ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_00_0xx_0_0_0_0; // fsh
endcase endcase
7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0_0; // fmadd 7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0_0_0; // fmadd
7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0_0; // fmsub 7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0_0_0; // fmsub
7'b1001011: ControlsD = `FCTRLW'b1_0_01_10_010_0_0_0; // fnmsub 7'b1001011: ControlsD = `FCTRLW'b1_0_01_10_010_0_0_0_0; // fnmsub
7'b1001111: ControlsD = `FCTRLW'b1_0_01_10_011_0_0_0; // fnmadd 7'b1001111: ControlsD = `FCTRLW'b1_0_01_10_011_0_0_0_0; // fnmadd
7'b1010011: casez(Funct7D) 7'b1010011: casez(Funct7D)
7'b00000??: ControlsD = `FCTRLW'b1_0_01_10_110_0_0_0; // fadd 7'b00000??: ControlsD = `FCTRLW'b1_0_01_10_110_0_0_0_0; // fadd
7'b00001??: ControlsD = `FCTRLW'b1_0_01_10_111_0_0_0; // fsub 7'b00001??: ControlsD = `FCTRLW'b1_0_01_10_111_0_0_0_0; // fsub
7'b00010??: ControlsD = `FCTRLW'b1_0_01_10_100_0_0_0; // fmul 7'b00010??: ControlsD = `FCTRLW'b1_0_01_10_100_0_0_0_0; // fmul
7'b00011??: ControlsD = `FCTRLW'b1_0_01_01_xx0_1_0_0; // fdiv 7'b00011??: ControlsD = `FCTRLW'b1_0_01_01_xx0_1_0_0_0; // fdiv
7'b01011??: if (Rs2D == 5'b0000) ControlsD = `FCTRLW'b1_0_01_01_xx1_1_0_0; // fsqrt 7'b01011??: if (Rs2D == 5'b0000) ControlsD = `FCTRLW'b1_0_01_01_xx1_1_0_0_0; // fsqrt
7'b00100??: case(Funct3D) 7'b00100??: case(Funct3D)
3'b000: ControlsD = `FCTRLW'b1_0_00_00_000_0_0_0; // fsgnj 3'b000: ControlsD = `FCTRLW'b1_0_00_00_000_0_0_0_0; // fsgnj
3'b001: ControlsD = `FCTRLW'b1_0_00_00_001_0_0_0; // fsgnjn 3'b001: ControlsD = `FCTRLW'b1_0_00_00_001_0_0_0_0; // fsgnjn
3'b010: ControlsD = `FCTRLW'b1_0_00_00_010_0_0_0; // fsgnjx 3'b010: ControlsD = `FCTRLW'b1_0_00_00_010_0_0_0_0; // fsgnjx
endcase endcase
7'b00101??: case(Funct3D) 7'b00101??: case(Funct3D)
3'b000: ControlsD = `FCTRLW'b1_0_00_00_110_0_0_0; // fmin 3'b000: ControlsD = `FCTRLW'b1_0_00_00_110_0_0_0_0; // fmin
3'b001: ControlsD = `FCTRLW'b1_0_00_00_101_0_0_0; // fmax 3'b001: ControlsD = `FCTRLW'b1_0_00_00_101_0_0_0_0; // fmax
3'b010: if (P.ZFA_SUPPORTED) ControlsD = `FCTRLW'b1_0_00_00_110_0_0_0_1; // fminm (Zfa)
3'b011: if (P.ZFA_SUPPORTED) ControlsD = `FCTRLW'b1_0_00_00_101_0_0_0_1; // fmaxm (Zfa)
endcase endcase
7'b10100??: case(Funct3D) 7'b10100??: case(Funct3D)
3'b010: ControlsD = `FCTRLW'b0_1_00_00_010_0_0_0; // feq 3'b000: ControlsD = `FCTRLW'b0_1_00_00_011_0_0_0_0; // fle
3'b001: ControlsD = `FCTRLW'b0_1_00_00_001_0_0_0; // flt 3'b001: ControlsD = `FCTRLW'b0_1_00_00_001_0_0_0_0; // flt
3'b000: ControlsD = `FCTRLW'b0_1_00_00_011_0_0_0; // fle 3'b010: ControlsD = `FCTRLW'b0_1_00_00_010_0_0_0_0; // feq
3'b100: if (P.ZFA_SUPPORTED) ControlsD = `FCTRLW'b0_1_00_00_011_0_0_0_1; // fleq (Zfa)
3'b101: if (P.ZFA_SUPPORTED) ControlsD = `FCTRLW'b0_1_00_00_001_0_0_0_1; // fltq (Zfa)
endcase endcase
7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000) 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000)
ControlsD = `FCTRLW'b0_1_10_00_000_0_0_0; // fclass ControlsD = `FCTRLW'b0_1_10_00_000_0_0_0_0; // fclass
else if (Funct3D == 3'b000 & Rs2D == 5'b00000) else if (Funct3D == 3'b000 & Rs2D == 5'b00000)
ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0; // fmv.x.w/d/h/q fp to int register ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0_0; // fmv.x.w/d/h/q fp to int register
7'b11110??: if (Funct3D == 3'b000 & Rs2D == 5'b00000) else if (P.ZFA_SUPPORTED & P.XLEN == 32 & P.D_SUPPORTED & Funct7D[1:0] == 2'b01 & Funct3D == 3'b000 & Rs2D == 5'b00001)
ControlsD = `FCTRLW'b1_0_00_00_011_0_0_0; // fmv.w/d/h/q.x int to fp reg ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0_1; // fmvh.x.d (Zfa)
7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00) // Q not supported in RV64GC
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h)
7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01)
ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q)
// coverage off // coverage off
// Not covered in testing because rv64gc does not support half or quad precision else if (P.ZFA_SUPPORTED & P.XLEN == 64 & P.Q_SUPPORTED & Funct7D[1:0] == 2'b11 & Funct3D == 3'b000 & Rs2D == 5'b00001)
ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0_1; // fmvh.x.q (Zfa)
// coverage on
7'b11110??: if (Funct3D == 3'b000 & Rs2D == 5'b00000)
ControlsD = `FCTRLW'b1_0_00_00_011_0_0_0_0; // fmv.w/d/h/q.x int to fp reg
else if (P.ZFA_SUPPORTED & Funct3D == 3'b000 & Rs2D == 5'b00001)
ControlsD = `FCTRLW'b1_0_00_00_111_0_0_0_1; // fli (Zfa)
7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00)
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0_0; // fcvt.s.(d/q/h)
else if (Rs2D == 5'b00100 & P.ZFA_SUPPORTED)
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0_1; // fround.s (Zfa) *** needs ctrl for all rounds
else if (Rs2D == 5'b00101 & P.ZFA_SUPPORTED)
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0_1; // froundnx.s (Zfa) *** needs ctrl for all rounds
7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01)
ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0_0; // fcvt.d.(s/h/q)
else if (Rs2D == 5'b00100 & P.ZFA_SUPPORTED)
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0_1; // fround.d (Zfa)
else if (Rs2D == 5'b00101 & P.ZFA_SUPPORTED)
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0_1; // froundnx.d (Zfa)
7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10)
ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0_0; // fcvt.h.(s/d/q)
else if (Rs2D == 5'b00100 & P.ZFA_SUPPORTED)
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0_1; // fround.h (Zfa)
else if (Rs2D == 5'b00101 & P.ZFA_SUPPORTED)
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0_1; // froundnx.h (Zfa)
// coverage off
// Not covered in testing because rv64gc does not support quad precision
7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11)
ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0_0; // fcvt.q.(s/h/d)
else if (Rs2D == 5'b00100 & P.ZFA_SUPPORTED)
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0_1; // fround.q (Zfa)
else if (Rs2D == 5'b00101 & P.ZFA_SUPPORTED)
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0_1; // froundnx.q (Zfa)
// coverage on // coverage on
7'b1101000: case(Rs2D) 7'b1101000: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fcvt.s.w w->s
5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0_0; // fcvt.s.wu wu->s
5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0; // fcvt.s.l l->s
5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0_0; // fcvt.s.lu lu->s
endcase endcase
7'b1100000: case(Rs2D) 7'b1100000: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_0; // fcvt.w.s s->w
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1_0; // fcvt.wu.s s->wu
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0; // fcvt.l.s s->l
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0; // fcvt.lu.s s->lu
endcase endcase
7'b1101001: case(Rs2D) 7'b1101001: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w w->d 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fcvt.d.w w->d
5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0_0; // fcvt.d.wu wu->d
5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l l->d 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0; // fcvt.d.l l->d
5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0_0; // fcvt.d.lu lu->d
endcase endcase
7'b1100001: case(Rs2D) 7'b1100001: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_0; // fcvt.w.d d->w
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1_0; // fcvt.wu.d d->wu
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0; // fcvt.l.d d->l
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0; // fcvt.lu.d d->lu
5'b01000: if (P.ZFA_SUPPORTED & P.D_SUPPORTED & Funct3D == 3'b001)
ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_1; // fcvtmod.w.d (Zfa)
endcase endcase
// coverage off
// Not covered in testing because rv64gc does not support half or quad precision
7'b1101010: case(Rs2D) 7'b1101010: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fcvt.h.w w->h
5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0_0; // fcvt.h.wu wu->h
5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.h.l l->h 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0; // fcvt.h.l l->h
5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.h.lu lu->h 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0_0; // fcvt.h.lu lu->h
endcase endcase
7'b1100010: case(Rs2D) 7'b1100010: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.h h->w 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_0; // fcvt.w.h h->w
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.h h->wu 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1_0; // fcvt.wu.h h->wu
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.h h->l 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0; // fcvt.l.h h->l
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.h h->lu 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0; // fcvt.lu.h h->lu
endcase endcase
// Not covered in testing because rv64gc does not support quad precision
// coverage off
7'b1101011: case(Rs2D) 7'b1101011: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.q.w w->q 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fcvt.q.w w->q
5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.q.wu wu->q 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0_0; // fcvt.q.wu wu->q
5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.q.l l->q 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0; // fcvt.q.l l->q
5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.q.lu lu->q 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0_0; // fcvt.q.lu lu->q
endcase endcase
7'b1100011: case(Rs2D) 7'b1100011: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.q q->w 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_0; // fcvt.w.q q->w
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1_0; // fcvt.wu.q q->wu
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0; // fcvt.l.q q->l
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0; // fcvt.lu.q q->lu
endcase endcase
// coverage on // coverage on
7'b1011001: if (P.ZFA_SUPPORTED & P.XLEN == 32 & P.D_SUPPORTED & Funct3D == 3'b000)
ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fmvp.d.x (Zfa) *** untested, controls could be wrong
// Not covered in testing because rv64gc does not support quad precision
// coverage off
7'b1011011: if (P.ZFA_SUPPORTED & P.XLEN == 64 & P.Q_SUPPORTED & Funct3D == 3'b000)
ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0; // fmvp.q.x (Zfa)
// coverage on
endcase endcase
endcase endcase
end end
/* verilator lint_on CASEINCOMPLETE */ /* verilator lint_on CASEINCOMPLETE */
// unswizzle control bits // unswizzle control bits
assign #1 {FRegWriteD, FWriteIntD, FResSelD, PostProcSelD, OpCtrlD, FDivStartD, IllegalFPUInstrD, FCvtIntD} = ControlsD; assign #1 {FRegWriteD, FWriteIntD, FResSelD, PostProcSelD, OpCtrlD, FDivStartD, IllegalFPUInstrD, FCvtIntD, ZfaD} = ControlsD;
// rounding modes: // rounding modes:
// 000 - round to nearest, ties to even // 000 - round to nearest, ties to even
@ -274,6 +314,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
// 011 - mv to fp 01 // 011 - mv to fp 01
// 110 - min 10 // 110 - min 10
// 101 - max 10 // 101 - max 10
// 111 - fli 11
// OpCtrl: // OpCtrl:
// Fma: {not multiply-add?, negate prod?, negate Z?} // Fma: {not multiply-add?, negate prod?, negate Z?}
@ -310,9 +351,9 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
assign Adr3D = InstrD[31:27]; assign Adr3D = InstrD[31:27];
// D/E pipleine register // D/E pipleine register
flopenrc #(14+P.FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE, flopenrc #(15+P.FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE,
{FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, FCvtIntD, ~IllegalFPUInstrD}, {FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, FCvtIntD, ZfaD, ~IllegalFPUInstrD},
{FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, FPUActiveE}); {FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, ZfaE, FPUActiveE});
flopenrc #(15) DEAdrReg(clk, reset, FlushE, ~StallE, {Adr1D, Adr2D, Adr3D}, {Adr1E, Adr2E, Adr3E}); flopenrc #(15) DEAdrReg(clk, reset, FlushE, ~StallE, {Adr1D, Adr2D, Adr3D}, {Adr1E, Adr2E, Adr3E});
flopenrc #(1) DEFDivStartReg(clk, reset, FlushE, ~StallE|FDivBusyE, FDivStartD, FDivStartE); flopenrc #(1) DEFDivStartReg(clk, reset, FlushE, ~StallE|FDivBusyE, FDivStartD, FDivStartE);
flopenrc #(3) DEEnReg(clk, reset, FlushE, ~StallE, {XEnD, YEnD, ZEnD}, {XEnE, YEnE, ZEnE}); flopenrc #(3) DEEnReg(clk, reset, FlushE, ~StallE, {XEnD, YEnD, ZEnD}, {XEnE, YEnE, ZEnE});
@ -322,9 +363,9 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
else assign IDivStartE = 0; else assign IDivStartE = 0;
// E/M pipleine register // E/M pipleine register
flopenrc #(13+int'(P.FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM, flopenrc #(14+int'(P.FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM,
{FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE}, {FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, ZfaE},
{FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM, FCvtIntM}); {FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM, FCvtIntM, ZfaM});
// renameing for readability // renameing for readability
assign FpLoadStoreM = FResSelM[1]; assign FpLoadStoreM = FResSelM[1];

219
src/fpu/fli.sv Normal file
View File

@ -0,0 +1,219 @@
///////////////////////////////////////////
// fli.sv
//
// Written: David_Harris@hmc.edu
// Modified: 1/16/2024
//
// Purpose: Floating-point float immediate
//
// Documentation: RISC-V System on Chip Design Chapter 16
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
module fli import cvw::*; #(parameter cvw_t P) (
input logic [4:0] Rs1, // Index of immediate to select
input logic [1:0] Fmt, // 00 = single, 01 = double, 10 = half, 11 = quad
output logic [P.FLEN-1:0] Imm // Immediate output
);
logic [P.FLEN-1:0] HImmBox, SImmBox, DImmBox, QImmBox;
// select constant for each immediate size supported
////////////////////////////
// half
////////////////////////////
if (P.ZFH_SUPPORTED) begin
logic [15:0] HImm;
always_comb begin
case(Rs1)
0: HImm = 16'hBC00;
1: HImm = 16'h0400;
2: HImm = 16'h0100;
3: HImm = 16'h0200;
4: HImm = 16'h1C00;
5: HImm = 16'h2000;
6: HImm = 16'h2C00;
7: HImm = 16'h3000;
8: HImm = 16'h3400;
9: HImm = 16'h3500;
10: HImm = 16'h3600;
11: HImm = 16'h3700;
12: HImm = 16'h3800;
13: HImm = 16'h3900;
14: HImm = 16'h3A00;
15: HImm = 16'h3B00;
16: HImm = 16'h3C00;
17: HImm = 16'h3D00;
18: HImm = 16'h3E00;
19: HImm = 16'h3F00;
20: HImm = 16'h4000;
21: HImm = 16'h4100;
22: HImm = 16'h4200;
23: HImm = 16'h4400;
24: HImm = 16'h4800;
25: HImm = 16'h4C00;
26: HImm = 16'h5800;
27: HImm = 16'h5C00;
28: HImm = 16'h7800;
29: HImm = 16'h7C00;
30: HImm = 16'h7C00;
31: HImm = 16'h7E00;
endcase
end
assign HImmBox = {{(P.FLEN-16){1'b1}}, HImm}; // NaN-box HImm
end else assign HImmBox = '0;
////////////////////////////
// single
////////////////////////////
logic [31:0] SImm;
always_comb begin
case(Rs1)
0: SImm = 32'hBF800000;
1: SImm = 32'h00800000;
2: SImm = 32'h37800000;
3: SImm = 32'h38000000;
4: SImm = 32'h3B800000;
5: SImm = 32'h3C000000;
6: SImm = 32'h3D800000;
7: SImm = 32'h3E000000;
8: SImm = 32'h3E800000;
9: SImm = 32'h3EA00000;
10: SImm = 32'h3EC00000;
11: SImm = 32'h3EE00000;
12: SImm = 32'h3F000000;
13: SImm = 32'h3F200000;
14: SImm = 32'h3F400000;
15: SImm = 32'h3F600000;
16: SImm = 32'h3F800000;
17: SImm = 32'h3FA00000;
18: SImm = 32'h3FC00000;
19: SImm = 32'h3FE00000;
20: SImm = 32'h40000000;
21: SImm = 32'h40200000;
22: SImm = 32'h40400000;
23: SImm = 32'h40800000;
24: SImm = 32'h41000000;
25: SImm = 32'h41800000;
26: SImm = 32'h43000000;
27: SImm = 32'h43800000;
28: SImm = 32'h47000000;
29: SImm = 32'h47800000;
30: SImm = 32'h7F800000;
31: SImm = 32'h7FC00000;
endcase
end
assign SImmBox = {{(P.FLEN-32){1'b1}}, SImm}; // NaN-box SImm
////////////////////////////
// double
////////////////////////////
if (P.D_SUPPORTED) begin
logic [63:0] DImm;
always_comb begin
case(Rs1)
0: DImm = 64'hBFF0000000000000;
1: DImm = 64'h0010000000000000;
2: DImm = 64'h3EF0000000000000;
3: DImm = 64'h3F00000000000000;
4: DImm = 64'h3F70000000000000;
5: DImm = 64'h3F80000000000000;
6: DImm = 64'h3FB0000000000000;
7: DImm = 64'h3FC0000000000000;
8: DImm = 64'h3FD0000000000000;
9: DImm = 64'h3FD4000000000000;
10: DImm = 64'h3FD8000000000000;
11: DImm = 64'h3FDC000000000000;
12: DImm = 64'h3FE0000000000000;
13: DImm = 64'h3FE4000000000000;
14: DImm = 64'h3FE8000000000000;
15: DImm = 64'h3FEC000000000000;
16: DImm = 64'h3FF0000000000000;
17: DImm = 64'h3FF4000000000000;
18: DImm = 64'h3FF8000000000000;
19: DImm = 64'h3FFC000000000000;
20: DImm = 64'h4000000000000000;
21: DImm = 64'h4004000000000000;
22: DImm = 64'h4008000000000000;
23: DImm = 64'h4010000000000000;
24: DImm = 64'h4020000000000000;
25: DImm = 64'h4030000000000000;
26: DImm = 64'h4060000000000000;
27: DImm = 64'h4070000000000000;
28: DImm = 64'h40E0000000000000;
29: DImm = 64'h40F0000000000000;
30: DImm = 64'h7FF0000000000000;
31: DImm = 64'h7FF8000000000000;
endcase
end
assign DImmBox = {{(P.FLEN-64){1'b1}}, DImm}; // NaN-box DImm
end else assign DImmBox = '0;
////////////////////////////
// double
////////////////////////////
if (P.Q_SUPPORTED) begin
logic [63:0] QImm;
always_comb begin
case(Rs1)
0: QImm = 128'hBFFF0000000000000000000000000000;
1: QImm = 128'h00010000000000000000000000000000;
2: QImm = 128'h3FEF0000000000000000000000000000;
3: QImm = 128'h3FF00000000000000000000000000000;
4: QImm = 128'h3FF70000000000000000000000000000;
5: QImm = 128'h3FF80000000000000000000000000000;
6: QImm = 128'h3FFB0000000000000000000000000000;
7: QImm = 128'h3FFC0000000000000000000000000000;
8: QImm = 128'h3FFD0000000000000000000000000000;
9: QImm = 128'h3FFD4000000000000000000000000000;
10: QImm = 128'h3FFD8000000000000000000000000000;
11: QImm = 128'h3FFDC000000000000000000000000000;
12: QImm = 128'h3FFE0000000000000000000000000000;
13: QImm = 128'h3FFE4000000000000000000000000000;
14: QImm = 128'h3FFE8000000000000000000000000000;
15: QImm = 128'h3FFEC000000000000000000000000000;
16: QImm = 128'h3FFF0000000000000000000000000000;
17: QImm = 128'h3FFF4000000000000000000000000000;
18: QImm = 128'h3FFF8000000000000000000000000000;
19: QImm = 128'h3FFFC000000000000000000000000000;
20: QImm = 128'h40000000000000000000000000000000;
21: QImm = 128'h40004000000000000000000000000000;
22: QImm = 128'h40008000000000000000000000000000;
23: QImm = 128'h40010000000000000000000000000000;
24: QImm = 128'h40020000000000000000000000000000;
25: QImm = 128'h40030000000000000000000000000000;
26: QImm = 128'h40060000000000000000000000000000;
27: QImm = 128'h40070000000000000000000000000000;
28: QImm = 128'h400E0000000000000000000000000000;
29: QImm = 128'h400F0000000000000000000000000000;
30: QImm = 128'h7FFF0000000000000000000000000000;
31: QImm = 128'h7FFF8000000000000000000000000000;
endcase
end
assign QImmBox = QImm; // NaN-box QImm trivial because Q is longest format
end else assign QImmBox = '0;
mux4 #(P.FLEN) flimux(SImmBox, DImmBox, HImmBox, QImmBox, Fmt, Imm); // select immediate based on format
endmodule

View File

@ -83,6 +83,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
logic XEnE, YEnE, ZEnE; // X, Y, Z inputs used for current operation logic XEnE, YEnE, ZEnE; // X, Y, Z inputs used for current operation
logic FRegWriteE; // Write floating-point register logic FRegWriteE; // Write floating-point register
logic FPUActiveE; // FP instruction being executed logic FPUActiveE; // FP instruction being executed
logic ZfaE, ZfaM; // Zfa variants of instructions (fli, fminm, fmaxm, fround, froundnx, fleq, fltq, fmvh, fmvp, fcvtmod.w.d)
// regfile signals // regfile signals
logic [P.FLEN-1:0] FRD1D, FRD2D, FRD3D; // Read Data from FP register - decode stage logic [P.FLEN-1:0] FRD1D, FRD2D, FRD3D; // Read Data from FP register - decode stage
@ -154,12 +155,13 @@ module fpu import cvw::*; #(parameter cvw_t P) (
logic [P.FLEN-1:0] FResultW; // final FP result being written to the FP register logic [P.FLEN-1:0] FResultW; // final FP result being written to the FP register
// other signals // other signals
logic [P.FLEN-1:0] AlignedSrcAE; // align SrcA from IEU to the floating point format for fmv logic [P.FLEN-1:0] PreIntSrcE, IntSrcE; // align SrcA from IEU to the floating point format for fmv / fmvp
logic [P.FLEN-1:0] BoxedZeroE; // Zero value for Z for multiplication, with NaN boxing if needed logic [P.FLEN-1:0] BoxedZeroE; // Zero value for Z for multiplication, with NaN boxing if needed
logic [P.FLEN-1:0] BoxedOneE; // One value for Z for multiplication, with NaN boxing if needed logic [P.FLEN-1:0] BoxedOneE; // One value for Z for multiplication, with NaN boxing if needed
logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt
logic [P.FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer logic [P.FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer
logic mvsgn; // sign bit for extending move logic mvsgn; // sign bit for extending move
logic [P.FLEN-1:0] FliResE; // Floating-point load immediate value
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Decode Stage: fctrl decoder, read register file // Decode Stage: fctrl decoder, read register file
@ -169,7 +171,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
fctrl #(P) fctrl (.Funct7D(InstrD[31:25]), .OpD(InstrD[6:0]), .Rs2D(InstrD[24:20]), .Funct3D(InstrD[14:12]), fctrl #(P) fctrl (.Funct7D(InstrD[31:25]), .OpD(InstrD[6:0]), .Rs2D(InstrD[24:20]), .Funct3D(InstrD[14:12]),
.IntDivE, .InstrD, .IntDivE, .InstrD,
.StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, .FRM_REGW, .STATUS_FS, .FDivBusyE, .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, .FRM_REGW, .STATUS_FS, .FDivBusyE,
.reset, .clk, .FRegWriteE, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM, .reset, .clk, .FRegWriteE, .FRegWriteM, .FRegWriteW, .ZfaE, .ZfaM, .FrmM, .FmtE, .FmtM,
.FDivStartE, .IDivStartE, .FWriteIntE, .FCvtIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .FpLoadStoreM, .FDivStartE, .IDivStartE, .FWriteIntE, .FCvtIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .FpLoadStoreM,
.IllegalFPUInstrD, .XEnD, .YEnD, .ZEnD, .XEnE, .YEnE, .ZEnE, .IllegalFPUInstrD, .XEnD, .YEnD, .ZEnD, .XEnE, .YEnE, .ZEnE,
.FResSelE, .FResSelM, .FResSelW, .FPUActiveE, .PostProcSelE, .PostProcSelM, .FCvtIntW, .FResSelE, .FResSelM, .FResSelW, .FPUActiveE, .PostProcSelE, .PostProcSelM, .FCvtIntW,
@ -246,7 +248,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
.UmM, .FIntDivResultM); .UmM, .FIntDivResultM);
// compare: fmin/fmax, flt/fle/feq // compare: fmin/fmax, flt/fle/feq
fcmp #(P) fcmp (.Fmt(FmtE), .OpCtrl(OpCtrlE), .Xs(XsE), .Ys(YsE), .Xe(XeE), .Ye(YeE), fcmp #(P) fcmp (.Fmt(FmtE), .OpCtrl(OpCtrlE), .Zfa(ZfaE), .Xs(XsE), .Ys(YsE), .Xe(XeE), .Ye(YeE),
.Xm(XmE), .Ym(YmE), .XZero(XZeroE), .YZero(YZeroE), .XNaN(XNaNE), .YNaN(YNaNE), .Xm(XmE), .Ym(YmE), .XZero(XZeroE), .YZero(YZeroE), .XNaN(XNaNE), .YNaN(YNaNE),
.XSNaN(XSNaNE), .YSNaN(YSNaNE), .X(XE), .Y(YE), .CmpNV(CmpNVE), .XSNaN(XSNaNE), .YSNaN(YSNaNE), .X(XE), .Y(YE), .CmpNV(CmpNVE),
.CmpFpRes(CmpFpResE), .CmpIntRes(CmpIntResE)); .CmpFpRes(CmpFpResE), .CmpIntRes(CmpIntResE));
@ -263,23 +265,35 @@ module fpu import cvw::*; #(parameter cvw_t P) (
.ToInt(FWriteIntE), .XZero(XZeroE), .Fmt(FmtE), .Ce(CeE), .ShiftAmt(CvtShiftAmtE), .ToInt(FWriteIntE), .XZero(XZeroE), .Fmt(FmtE), .Ce(CeE), .ShiftAmt(CvtShiftAmtE),
.ResSubnormUf(CvtResSubnormUfE), .Cs(CsE), .IntZero(IntZeroE), .LzcIn(CvtLzcInE)); .ResSubnormUf(CvtResSubnormUfE), .Cs(CsE), .IntZero(IntZeroE), .LzcIn(CvtLzcInE));
// NaN Box SrcA to convert integer to requested FP size for fmv.*.x // floating-point load immediate: fli
if(P.FPSIZES == 1) assign AlignedSrcAE = {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE}; if (P.ZFA_SUPPORTED) begin
logic [4:0] Rs1E;
flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, InstrD[19:15], Rs1E);
fli #(P) fli(.Rs1(Rs1E), .Fmt(FmtE), .Imm(FliResE));
end else assign FliResE = '0;
// fmv.*.x: NaN Box SrcA to extend integer to requested FP size
if(P.FPSIZES == 1) assign PreIntSrcE = {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE};
else if(P.FPSIZES == 2) else if(P.FPSIZES == 2)
mux2 #(P.FLEN) SrcAMux ({{P.FLEN-P.LEN1{1'b1}}, ForwardedSrcAE[P.LEN1-1:0]}, {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE}, FmtE, AlignedSrcAE); mux2 #(P.FLEN) SrcAMux ({{P.FLEN-P.LEN1{1'b1}}, ForwardedSrcAE[P.LEN1-1:0]}, {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE}, FmtE, PreIntSrcE);
else if(P.FPSIZES == 3 | P.FPSIZES == 4) begin else if(P.FPSIZES == 3 | P.FPSIZES == 4) begin
localparam XD_LEN = P.D_LEN < P.XLEN ? P.D_LEN : P.XLEN; // shorter of D_LEN and XLEN localparam XD_LEN = P.D_LEN < P.XLEN ? P.D_LEN : P.XLEN; // shorter of D_LEN and XLEN
mux3 #(P.FLEN) SrcAMux ({{P.FLEN-P.S_LEN{1'b1}}, ForwardedSrcAE[P.S_LEN-1:0]}, mux3 #(P.FLEN) SrcAMux ({{P.FLEN-P.S_LEN{1'b1}}, ForwardedSrcAE[P.S_LEN-1:0]},
{{P.FLEN-XD_LEN{1'b1}}, ForwardedSrcAE[XD_LEN-1:0]}, {{P.FLEN-XD_LEN{1'b1}}, ForwardedSrcAE[XD_LEN-1:0]},
{{P.FLEN-P.H_LEN{1'b1}}, ForwardedSrcAE[P.H_LEN-1:0]}, {{P.FLEN-P.H_LEN{1'b1}}, ForwardedSrcAE[P.H_LEN-1:0]},
FmtE, AlignedSrcAE); // NaN boxing zeroes FmtE, PreIntSrcE); // NaN boxing zeroes
end end
// fmvp.*.x: Select pair of registers
if (P.ZFA_SUPPORTED & (P.XLEN==32 & P.D_SUPPORTED) | (P.XLEN==64 & P.Q_SUPPORTED))
assign IntSrcE = ZfaE ? {ForwardedSrcBE, ForwardedSrcAE} : PreIntSrcE; // choose pair of integer registers for fmvp.d.x / fmvp.q.x
else assign IntSrcE = PreIntSrcE;
// select a result that may be written to the FP register // select a result that may be written to the FP register
mux3 #(P.FLEN) FResMux(SgnResE, AlignedSrcAE, CmpFpResE, {OpCtrlE[2], &OpCtrlE[1:0]}, PreFpResE); mux4 #(P.FLEN) FResMux(SgnResE, IntSrcE, CmpFpResE, FliResE, {OpCtrlE[2], &OpCtrlE[1:0]}, PreFpResE);
assign PreNVE = CmpNVE&(OpCtrlE[2]|FWriteIntE); assign PreNVE = CmpNVE&(OpCtrlE[2]|FWriteIntE);
// select the result that may be written to the integer register with fmv.x.* // fmv.x.*: select the result that may be written to the integer register
if(P.FPSIZES == 1) begin if(P.FPSIZES == 1) begin
assign mvsgn = XE[P.FLEN-1]; assign mvsgn = XE[P.FLEN-1];
assign SgnExtXE = XE; assign SgnExtXE = XE;
@ -296,7 +310,8 @@ module fpu import cvw::*; #(parameter cvw_t P) (
// sign extend to XLEN if necessary // sign extend to XLEN if necessary
if (P.FLEN>P.XLEN) if (P.FLEN>P.XLEN)
assign IntSrcXE = SgnExtXE[P.XLEN-1:0]; if (P.ZFA_SUPPORTED) assign IntSrcXE = ZfaE ? XE[P.FLEN-1:P.FLEN/2] : SgnExtXE[P.XLEN-1:0]; // either fmvh.x.* or fmv.x.*
else assign IntSrcXE = SgnExtXE[P.XLEN-1:0];
else else
assign IntSrcXE = {{P.XLEN-P.FLEN{mvsgn}}, SgnExtXE}; assign IntSrcXE = {{P.XLEN-P.FLEN{mvsgn}}, SgnExtXE};
mux3 #(P.XLEN) IntResMux (ClassResE, IntSrcXE, CmpIntResE, {~FResSelE[1], FResSelE[0]}, FIntResE); mux3 #(P.XLEN) IntResMux (ClassResE, IntSrcXE, CmpIntResE, {~FResSelE[1], FResSelE[0]}, FIntResE);
@ -333,7 +348,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
.ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM), .ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM),
.FmaSm(SmM), .DivUe(UeM), .FmaAs(AsM), .FmaPs(PsM), .OpCtrl(OpCtrlM), .FmaSCnt(SCntM), .FmaSe(SeM), .FmaSm(SmM), .DivUe(UeM), .FmaAs(AsM), .FmaPs(PsM), .OpCtrl(OpCtrlM), .FmaSCnt(SCntM), .FmaSe(SeM),
.CvtCe(CeM), .CvtResSubnormUf(CvtResSubnormUfM),.CvtShiftAmt(CvtShiftAmtM), .CvtCs(CsM), .CvtCe(CeM), .CvtResSubnormUf(CvtResSubnormUfM),.CvtShiftAmt(CvtShiftAmtM), .CvtCs(CsM),
.ToInt(FWriteIntM), .DivSticky(DivStickyM), .CvtLzcIn(CvtLzcInM), .IntZero(IntZeroM), .ToInt(FWriteIntM), .Zfa(ZfaM), .DivSticky(DivStickyM), .CvtLzcIn(CvtLzcInM), .IntZero(IntZeroM),
.PostProcSel(PostProcSelM), .PostProcRes(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM)); .PostProcSel(PostProcSelM), .PostProcRes(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM));
// FPU flag selection - to privileged // FPU flag selection - to privileged

View File

@ -70,7 +70,7 @@ module flags import cvw::*; #(parameter cvw_t P) (
logic DivInvalid; // integer invalid flag logic DivInvalid; // integer invalid flag
logic Underflow; // Underflow flag logic Underflow; // Underflow flag
logic ResExpGteMax; // is the result greater than or equal to the maximum floating point expoent logic ResExpGteMax; // is the result greater than or equal to the maximum floating point expoent
logic ShiftGtIntSz; // is the shift greater than the the integer size (use Re to account for possible roundning "shift") logic ShiftGtIntSz; // is the shift greater than the the integer size (use Re to account for possible rounding "shift")
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Overflow // Overflow

View File

@ -56,6 +56,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
input logic CvtResSubnormUf, // the convert result is subnormal or underflows input logic CvtResSubnormUf, // the convert result is subnormal or underflows
input logic [P.LOGCVTLEN-1:0] CvtShiftAmt, // how much to shift by input logic [P.LOGCVTLEN-1:0] CvtShiftAmt, // how much to shift by
input logic ToInt, // is fp->int (since it's writting to the integer register) input logic ToInt, // is fp->int (since it's writting to the integer register)
input logic Zfa, // Zfa operation (fcvtmod.w.d)
input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb) input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
input logic IntZero, // is the integer input zero input logic IntZero, // is the integer input zero
// final results // final results
@ -88,7 +89,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
logic [P.NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account Subnormal or zero results logic [P.NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account Subnormal or zero results
logic FmaPreResultSubnorm; // is the result subnormal - calculated before LZA corection logic FmaPreResultSubnorm; // is the result subnormal - calculated before LZA corection
logic [$clog2(3*P.NF+5)-1:0] FmaShiftAmt; // normalization shift amount for fma logic [$clog2(3*P.NF+5)-1:0] FmaShiftAmt; // normalization shift amount for fma
// division singals // division signals
logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount
logic [P.NORMSHIFTSZ-1:0] DivShiftIn; // divsqrt shift input logic [P.NORMSHIFTSZ-1:0] DivShiftIn; // divsqrt shift input
logic [P.NE+1:0] Ue; // divsqrt corrected exponent after corretion shift logic [P.NE+1:0] Ue; // divsqrt corrected exponent after corretion shift
@ -218,7 +219,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
specialcase #(P) specialcase(.Xs, .Xm, .Ym, .Zm, .XZero, .IntInvalid, specialcase #(P) specialcase(.Xs, .Xm, .Ym, .Zm, .XZero, .IntInvalid,
.IntZero, .Frm, .OutFmt, .XNaN, .YNaN, .ZNaN, .CvtResUf, .IntZero, .Frm, .OutFmt, .XNaN, .YNaN, .ZNaN, .CvtResUf,
.NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .CvtNegRes, .NaNIn, .IntToFp, .Int64, .Signed, .Zfa, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .CvtNegRes,
.XInf, .YInf, .DivOp, .DivByZero, .FullRe, .CvtCe, .Rs, .Re, .Rf, .PostProcRes, .FCvtIntRes); .XInf, .YInf, .DivOp, .DivByZero, .FullRe, .CvtCe, .Rs, .Re, .Rf, .PostProcRes, .FCvtIntRes);
endmodule endmodule

View File

@ -44,7 +44,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
output logic [P.NE+1:0] Ue // corrected exponent for divider output logic [P.NE+1:0] Ue // corrected exponent for divider
); );
logic [3*P.NF+3:0] CorrSumShifted; // the shifted sum after LZA correction logic [P.CORRSHIFTSZ-1:0] CorrSumShifted; // the shifted sum after LZA correction
logic [P.CORRSHIFTSZ-1:0] CorrQm0, CorrQm1; // portions of Shifted to select for CorrQmShifted logic [P.CORRSHIFTSZ-1:0] CorrQm0, CorrQm1; // portions of Shifted to select for CorrQmShifted
logic [P.CORRSHIFTSZ-1:0] CorrQmShifted; // the shifted divsqrt result after one bit shift logic [P.CORRSHIFTSZ-1:0] CorrQmShifted; // the shifted divsqrt result after one bit shift
logic ResSubnorm; // is the result Subnormal logic ResSubnorm; // is the result Subnormal
@ -68,7 +68,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
// if the result of the divider was calculated to be subnormal, then the result was correctly normalized, so select the top shifted bits // if the result of the divider was calculated to be subnormal, then the result was correctly normalized, so select the top shifted bits
always_comb always_comb
if(FmaOp) Mf = {CorrSumShifted, {P.CORRSHIFTSZ-(3*P.NF+4){1'b0}}}; if(FmaOp) Mf = {CorrSumShifted};
else if (DivOp&~DivResSubnorm) Mf = CorrQmShifted; else if (DivOp&~DivResSubnorm) Mf = CorrQmShifted;
else Mf = Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.CORRSHIFTSZ]; else Mf = Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.CORRSHIFTSZ];

View File

@ -53,6 +53,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
input logic IntToFp, // is cvt int -> fp opperation input logic IntToFp, // is cvt int -> fp opperation
input logic Int64, // is the integer 64 bits input logic Int64, // is the integer 64 bits
input logic Signed, // is the integer signed input logic Signed, // is the integer signed
input logic Zfa, // Zfa conversion operation: fcvtmod.w.d
input logic [P.NE:0] CvtCe, // the calculated expoent for cvt input logic [P.NE:0] CvtCe, // the calculated expoent for cvt
input logic IntInvalid, // integer invalid flag to choose the result input logic IntInvalid, // integer invalid flag to choose the result
input logic CvtResUf, // does the convert result underflow input logic CvtResUf, // does the convert result underflow
@ -70,10 +71,12 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
logic [P.FLEN-1:0] OfRes; // overflowed result result logic [P.FLEN-1:0] OfRes; // overflowed result result
logic [P.FLEN-1:0] NormRes; // normal result logic [P.FLEN-1:0] NormRes; // normal result
logic [P.XLEN-1:0] OfIntRes; // the overflow result for integer output logic [P.XLEN-1:0] OfIntRes; // the overflow result for integer output
logic [P.XLEN-1:0] OfIntRes2; // the overflow result for integer output after accounting for fcvtmod.w.d
logic [P.XLEN-1:0] Int64Res; // Result for conversion to 64-bit int after accounting for fcvtmod.w.d
logic OfResMax; // does the of result output maximum norm fp number logic OfResMax; // does the of result output maximum norm fp number
logic KillRes; // kill the result for underflow logic KillRes; // kill the result for underflow
logic SelOfRes; // should the overflow result be selected logic SelOfRes; // should the overflow result be selected (excluding convert)
logic SelCvtOfRes; // select overflow result for convert instruction
// does the overflow result output the maximum normalized floating point number // does the overflow result output the maximum normalized floating point number
// output infinity if the input is infinity // output infinity if the input is infinity
@ -329,6 +332,25 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive
end end
// fcvtmod.w.d logic
// fcvtmod.w.d is like fcvt.w.d excep thtat it takes bits [31:0] and sign extends the rest,
// and converts +/-inf and NaN to zero.
if (P.ZFA_SUPPORTED & P.D_SUPPORTED) // fcvtmod.w.d support
always_comb begin
if (Zfa) OfIntRes2 = '0;
else OfIntRes2 = OfIntRes;
if (Zfa) Int64Res = {{(P.XLEN-32){CvtNegRes[P.XLEN-1]}}, CvtNegRes[31:0]};
else Int64Res = CvtNegRes[P.XLEN-1:0];
if (Zfa) SelCvtOfRes = InfIn | NaNIn; // fcvtmod.w.d only overflows to 0 on NaN or Infinity
else SelCvtOfRes = IntInvalid; // regular fcvt gives an overflow if out of range
end
else
always_comb begin // no fcvtmod.w.d support
OfIntRes2 = OfIntRes;
Int64Res = CvtNegRes[P.XLEN-1:0];
SelCvtOfRes = IntInvalid;
end
// select the integer output // select the integer output
// - if the input is invalid (out of bounds NaN or Inf) then output overflow res // - if the input is invalid (out of bounds NaN or Inf) then output overflow res
@ -337,10 +359,10 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
// - otherwise output a rounded 0 // - otherwise output a rounded 0
// - otherwise output the normal res (trmined and sign extended if nessisary) // - otherwise output the normal res (trmined and sign extended if nessisary)
always_comb always_comb
if(IntInvalid) FCvtIntRes = OfIntRes; if(SelCvtOfRes) FCvtIntRes = OfIntRes2;
else if(CvtCe[P.NE]) else if(CvtCe[P.NE])
if(Xs&Signed&Plus1) FCvtIntRes = {{P.XLEN{1'b1}}}; if(Xs&Signed&Plus1) FCvtIntRes = {{P.XLEN{1'b1}}};
else FCvtIntRes = {{P.XLEN-1{1'b0}}, Plus1}; else FCvtIntRes = {{P.XLEN-1{1'b0}}, Plus1};
else if(Int64) FCvtIntRes = CvtNegRes[P.XLEN-1:0]; else if(Int64) FCvtIntRes = Int64Res;
else FCvtIntRes = {{P.XLEN-32{CvtNegRes[31]}}, CvtNegRes[31:0]}; else FCvtIntRes = {{P.XLEN-32{CvtNegRes[31]}}, CvtNegRes[31:0]};
endmodule endmodule

View File

@ -140,7 +140,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
2'b11: DataMisalignedM = |VAdr[2:0]; // ld, sd, fld, fsd 2'b11: DataMisalignedM = |VAdr[2:0]; // ld, sd, fld, fsd
endcase endcase
assign LoadMisalignedFaultM = DataMisalignedM & ReadNoAmoAccessM & ~(P.ZICCLSM_SUPPORTED & Cacheable); assign LoadMisalignedFaultM = DataMisalignedM & ReadNoAmoAccessM & ~(P.ZICCLSM_SUPPORTED & Cacheable);
assign StoreAmoMisalignedFaultM = DataMisalignedM & WriteAccessM & ~(P.ZICCLSM_SUPPORTED & Cacheable); assign StoreAmoMisalignedFaultM = DataMisalignedM & WriteAccessM & (~(P.ZICCLSM_SUPPORTED & Cacheable) | ReadAccessM); // Misaligned AMO faults even if ZICCLSM supported
// Specify which type of page fault is occurring // Specify which type of page fault is occurring
assign InstrPageFaultF = TLBPageFault & ExecuteAccessF; assign InstrPageFaultF = TLBPageFault & ExecuteAccessF;

View File

@ -298,6 +298,18 @@ module instrNameDecTB(
else if (funct7[6:2] == 5'b11100 & funct3 == 3'b001) name = "FCLASS"; else if (funct7[6:2] == 5'b11100 & funct3 == 3'b001) name = "FCLASS";
else if (funct7[6:2] == 5'b00100 & funct3 == 3'b010) name = "FSGNJX"; else if (funct7[6:2] == 5'b00100 & funct3 == 3'b010) name = "FSGNJX";
else if (funct7[6:2] == 5'b10100 & funct3 == 3'b010) name = "FEQ"; else if (funct7[6:2] == 5'b10100 & funct3 == 3'b010) name = "FEQ";
else if (funct7[6:2] == 5'b11110 & funct3 == 3'b000 & rs2 == 5'b00001) name = "FLI";
else if (funct7[6:2] == 5'b00101 & funct3 == 3'b010) name = "FMINM";
else if (funct7[6:2] == 5'b00101 & funct3 == 3'b011) name = "FMAXM";
else if (funct7[6:2] == 5'b01000 & rs2 == 5'b00100) name = "FROUND";
else if (funct7[6:2] == 5'b01000 & rs2 == 5'b00101) name = "FROUNDNX";
else if (funct7[6:2] == 5'b10100 & funct3 == 3'b100) name = "FLEQ";
else if (funct7[6:2] == 5'b10100 & funct3 == 3'b101) name = "FLTQ";
else if (funct7 == 7'b1110001 & funct3 == 3'b000 & rs2 == 5'b00001) name = "FMVH.X.D";
else if (funct7 == 7'b1110011 & funct3 == 3'b000 & rs2 == 5'b00001) name = "FMVH.X.Q";
else if (funct7 == 7'b1011001 & funct3 == 3'b000) name = "FMVP.D.X";
else if (funct7 == 7'b1011011 & funct3 == 3'b000) name = "FMVP.Q.X";
else if (funct7 == 7'b1100001 & funct3 == 3'b001 & rs2 == 5'b01000) name = "FCVTMOD.W.D";
else name = "ILLEGAL"; else name = "ILLEGAL";
10'b0000111_010: name = "FLW"; 10'b0000111_010: name = "FLW";
10'b0100111_010: name = "FSW"; 10'b0100111_010: name = "FSW";

View File

@ -128,7 +128,8 @@ module testbench;
"arch64zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch64zicboz; "arch64zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch64zicboz;
"arch64zcb": if (P.ZCB_SUPPORTED) tests = arch64zcb; "arch64zcb": if (P.ZCB_SUPPORTED) tests = arch64zcb;
"arch64zfh": if (P.ZFH_SUPPORTED) tests = arch64zfh; "arch64zfh": if (P.ZFH_SUPPORTED) tests = arch64zfh;
// "arch64zfa": if (P.ZFA_SUPPORTED) tests = arch64zfa; "arch64zfaf": if (P.ZFA_SUPPORTED) tests = arch64zfaf;
"arch64zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch64zfad;
endcase endcase
end else begin // RV32 end else begin // RV32
case (TEST) case (TEST)
@ -165,6 +166,7 @@ module testbench;
"arch32zcb": if (P.ZCB_SUPPORTED) tests = arch32zcb; "arch32zcb": if (P.ZCB_SUPPORTED) tests = arch32zcb;
"arch32zfh": if (P.ZFH_SUPPORTED) tests = arch32zfh; "arch32zfh": if (P.ZFH_SUPPORTED) tests = arch32zfh;
"arch32zfaf": if (P.ZFA_SUPPORTED) tests = arch32zfaf; "arch32zfaf": if (P.ZFA_SUPPORTED) tests = arch32zfaf;
"arch32zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch32zfad;
endcase endcase
end end
if (tests.size() == 0) begin if (tests.size() == 0) begin
@ -630,8 +632,8 @@ task automatic updateProgramAddrLabelArray;
end end
end end
if(ProgramAddrLabelArray["begin_signature"] == 0) $display("Couldn't find begin_signature in %s", ProgramLabelMapFile); // if(ProgramAddrLabelArray["begin_signature"] == 0) $display("Couldn't find begin_signature in %s", ProgramLabelMapFile);
if(ProgramAddrLabelArray["sig_end_canary"] == 0) $display("Couldn't find sig_end_canary in %s", ProgramLabelMapFile); // if(ProgramAddrLabelArray["sig_end_canary"] == 0) $display("Couldn't find sig_end_canary in %s", ProgramLabelMapFile);
$fclose(ProgramLabelMapFP); $fclose(ProgramLabelMapFP);
$fclose(ProgramAddrMapFP); $fclose(ProgramAddrMapFP);

View File

@ -1999,16 +1999,82 @@ string arch64zbs[] = '{
string arch32zfaf[] = '{ string arch32zfaf[] = '{
`RISCVARCHTEST, `RISCVARCHTEST,
"rv32i_m/F_Zfa/src/fle_b1-01.S", "rv32i_m/F_Zfa/src/fleq_b1-01.S",
"rv32i_m/F_Zfa/src/fle_b19-01.S", "rv32i_m/F_Zfa/src/fleq_b19-01.S",
"rv32i_m/F_Zfa/src/fli_b1-01.S", "rv32i_m/F_Zfa/src/fli.s-01.S",
"rv32i_m/F_Zfa/src/fltq_b1-01.S", "rv32i_m/F_Zfa/src/fltq_b1-01.S",
"rv32i_m/F_Zfa/src/fltq_b19-01.S", "rv32i_m/F_Zfa/src/fltq_b19-01.S",
"rv32i_m/F_Zfa/src/fmin_b1-01.S", "rv32i_m/D_Zfa/src/fltq_b1-01.S", // these D tests are more comprehensive and seem they should replace the F tests. Applies to all F tests duplicated in D
"rv32i_m/F_Zfa/src/fmin_b19-01.S", "rv32i_m/D_Zfa/src/fltq_b19-01.S",
"rv32i_m/F_Zfa/src/fmax_b1-01.S", "rv32i_m/F_Zfa/src/fminm_b1-01.S",
"rv32i_m/F_Zfa/src/fmax_b19-01.S", "rv32i_m/F_Zfa/src/fminm_b19-01.S",
"rv32i_m/F_Zfa/src/fround_b1-01.S" "rv32i_m/F_Zfa/src/fmaxm_b1-01.S",
"rv32i_m/F_Zfa/src/fmaxm_b19-01.S"
/* "rv32i_m/F_Zfa/src/fround_b1-01.S" */
};
string arch32zfad[] = '{
`RISCVARCHTEST,
"rv32i_m/D_Zfa/src/fcvtmod.w.d_b1-01.S",
"rv32i_m/D_Zfa/src/fcvtmod.w.d_b22-01.S",
"rv32i_m/D_Zfa/src/fcvtmod.w.d_b23-01.S",
"rv32i_m/D_Zfa/src/fcvtmod.w.d_b24-01.S",
"rv32i_m/D_Zfa/src/fcvtmod.w.d_b27-01.S",
"rv32i_m/D_Zfa/src/fcvtmod.w.d_b28-01.S",
"rv32i_m/D_Zfa/src/fcvtmod.w.d_b29-01.S",
"rv32i_m/D_Zfa/src/fleq_b1-01.S",
"rv32i_m/D_Zfa/src/fleq_b19-01.S",
"rv32i_m/D_Zfa/src/fleq.d_b1-01.S",
"rv32i_m/D_Zfa/src/fleq.d_b19-01.S",
"rv32i_m/D_Zfa/src/fli.d-01.S",
"rv32i_m/D_Zfa/src/fltq_b1-01.S",
"rv32i_m/D_Zfa/src/fltq_b19-01.S",
"rv32i_m/D_Zfa/src/fltq.d_b1-01.S",
"rv32i_m/D_Zfa/src/fltq.d_b19-01.S",
"rv32i_m/D_Zfa/src/fminm_b1-01.S",
"rv32i_m/D_Zfa/src/fminm_b19-01.S",
"rv32i_m/D_Zfa/src/fminm.d_b1-01.S",
"rv32i_m/D_Zfa/src/fminm.d_b19-01.S",
"rv32i_m/D_Zfa/src/fmaxm_b1-01.S",
"rv32i_m/D_Zfa/src/fmaxm_b19-01.S",
"rv32i_m/D_Zfa/src/fmaxm.d_b1-01.S",
"rv32i_m/D_Zfa/src/fmaxm.d_b19-01.S",
"rv32i_m/D_Zfa/src/fmvh.x.d_b1-01.S",
"rv32i_m/D_Zfa/src/fmvh.x.d_b22-01.S",
"rv32i_m/D_Zfa/src/fmvh.x.d_b23-01.S",
"rv32i_m/D_Zfa/src/fmvh.x.d_b24-01.S",
"rv32i_m/D_Zfa/src/fmvh.x.d_b27-01.S",
"rv32i_m/D_Zfa/src/fmvh.x.d_b28-01.S",
"rv32i_m/D_Zfa/src/fmvh.x.d_b29-01.S"
/* "rv32i_m/D_Zfa/src/fround_b1-01.S" */
};
string arch64zfaf[] = '{
`RISCVARCHTEST,
"rv64i_m/F_Zfa/src/fleq_b1-01.S",
"rv64i_m/F_Zfa/src/fleq_b19-01.S",
"rv64i_m/F_Zfa/src/fli.s-01.S",
"rv64i_m/F_Zfa/src/fltq_b1-01.S",
"rv64i_m/F_Zfa/src/fltq_b19-01.S",
"rv64i_m/F_Zfa/src/fminm_b1-01.S",
"rv64i_m/F_Zfa/src/fminm_b19-01.S",
"rv64i_m/F_Zfa/src/fmaxm_b1-01.S",
"rv64i_m/F_Zfa/src/fmaxm_b19-01.S"
/* "rv64i_m/F_Zfa/src/fround_b1-01.S" */
};
string arch64zfad[] = '{
`RISCVARCHTEST,
"rv64i_m/D_Zfa/src/fleq_b1-01.S",
"rv64i_m/D_Zfa/src/fleq_b19-01.S",
"rv64i_m/D_Zfa/src/fli.d-01.S",
"rv64i_m/D_Zfa/src/fltq_b1-01.S",
"rv64i_m/D_Zfa/src/fltq_b19-01.S",
"rv64i_m/D_Zfa/src/fminm_b1-01.S",
"rv64i_m/D_Zfa/src/fminm_b19-01.S",
"rv64i_m/D_Zfa/src/fmaxm_b1-01.S",
"rv64i_m/D_Zfa/src/fmaxm_b19-01.S"
/* "rv64i_m/D_Zfa/src/fround_b1-01.S" */
}; };
string arch32d_fma[] = '{ string arch32d_fma[] = '{

View File

@ -37,4 +37,31 @@ main:
csrrw t1, menvcfg, t0 csrrw t1, menvcfg, t0
csrrw t2, senvcfg, t0 csrrw t2, senvcfg, t0
# testing FIOM with different privelege modes
# setting environment config (to both 1 and 0) in each privelege mode
csrsi menvcfg, 1
li a0, 1
ecall # enter supervisor mode
li a0, 0
ecall # enter user mode
li a0, 1
ecall # enter supervisor mode
csrsi senvcfg, 1
li a0, 0
ecall # enter user mode
li a0, 3
ecall # enter machine mode
csrci menvcfg, 1
li a0, 1
ecall # enter supervisor mode
li a0, 0
ecall # enter user mode
j done j done

View File

@ -297,7 +297,32 @@ sretdone:
wfi wfi
j done
# Test uncovered privdec instructions
li a0, 3
ecall
# exercise sfence.inval.ir instruction
.word 0x18100073
# exercise sret with rs1 not 0
.word 0x102F8073
# cover mret when mpp = 3 and mprv = 1
li a0, 3
ecall # enter machine mode
bseti t0, zero, 17
csrs mstatus, t0 # set MPRV
li t1, 0x00001800
csrs mstatus, t1 # set MPP=3
la t1, finished
csrr t0, mepc
csrw mepc, t1 # set mepc for mret to jump to
mret
finished: j done

View File

@ -115,6 +115,10 @@ class spike(pluginTemplate):
self.isa += '_Zicond' self.isa += '_Zicond'
if "Zicboz" in ispec["ISA"]: if "Zicboz" in ispec["ISA"]:
self.isa += '_Zicboz' self.isa += '_Zicboz'
if "Zfa" in ispec["ISA"]:
self.isa += '_Zfa'
if "Zfh" in ispec["ISA"]:
self.isa += '_Zfh'
if "Zca" in ispec["ISA"]: if "Zca" in ispec["ISA"]:
self.isa += '_Zca' self.isa += '_Zca'
if "Zcb" in ispec["ISA"]: if "Zcb" in ispec["ISA"]:

View File

@ -1,6 +1,6 @@
hart_ids: [0] hart_ids: [0]
hart0: hart0:
ISA: RV32IMAFDCZicsr_Zicond_Zifencei_Zba_Zbb_Zbc_Zbs ISA: RV32IMAFDCZicsr_Zicond_Zifencei_Zfa_Zfh_Zba_Zbb_Zbc_Zbs
# ISA: RV32IMAFDCZicsr_Zicboz_Zifencei_Zca_Zba_Zbb_Zbc_Zbs # _Zbkb_Zcb # ISA: RV32IMAFDCZicsr_Zicboz_Zifencei_Zca_Zba_Zbb_Zbc_Zbs # _Zbkb_Zcb
physical_addr_sz: 32 physical_addr_sz: 32
User_Spec_Version: '2.3' User_Spec_Version: '2.3'

View File

@ -2,7 +2,7 @@ hart_ids: [0]
hart0: hart0:
# ISA: RV64IMAFDCSUZicsr_Zicboz_Zifencei_Zba_Zbb_Zbc_Zbs # Zkbs_Zcb # ISA: RV64IMAFDCSUZicsr_Zicboz_Zifencei_Zba_Zbb_Zbc_Zbs # Zkbs_Zcb
# ISA: RV64IMAFDCSUZicsr_Zifencei_Zca_Zcb_Zba_Zbb_Zbc_Zbs # Zkbs_Zcb # ISA: RV64IMAFDCSUZicsr_Zifencei_Zca_Zcb_Zba_Zbb_Zbc_Zbs # Zkbs_Zcb
ISA: RV64IMAFDCSUZicsr_Zicond_Zifencei_Zba_Zbb_Zbc_Zbs # Zkbs_Zcb ISA: RV64IMAFDCSUZicsr_Zicond_Zifencei_Zfa_Zfh_Zba_Zbb_Zbc_Zbs # Zkbs_Zcb
physical_addr_sz: 56 physical_addr_sz: 56
User_Spec_Version: '2.3' User_Spec_Version: '2.3'
supported_xlen: [64] supported_xlen: [64]

View File

@ -607,6 +607,7 @@ SETUP_PLIC
.4byte delay1, 0x0000001, write32_test # reset delay1 register .4byte delay1, 0x0000001, write32_test # reset delay1 register
.4byte cs_mode, 0x00000000, write32_test # reset cs_mode .4byte cs_mode, 0x00000000, write32_test # reset cs_mode
.4byte tx_mark, 0x00000001, write32_test # set transmit watermark to 1 (any entry turns mark off) .4byte tx_mark, 0x00000001, write32_test # set transmit watermark to 1 (any entry turns mark off)
.4byte sck_div, 0x00000100, write32_test # lower SPI clock rate so read32_tests trigger at correct times
#.4byte ie, 0x00000000, write32_test # enable transmit interrupt #.4byte ie, 0x00000000, write32_test # enable transmit interrupt
.4byte ip, 0x00000001, read32_test # tx watermark interupt should be pending .4byte ip, 0x00000001, read32_test # tx watermark interupt should be pending
.4byte 0x0, 0x00000000, readmip_test .4byte 0x0, 0x00000000, readmip_test

View File

@ -608,6 +608,7 @@ SETUP_PLIC
.8byte delay1, 0x0000001, write32_test # reset delay1 register .8byte delay1, 0x0000001, write32_test # reset delay1 register
.8byte cs_mode, 0x00000000, write32_test # reset cs_mode .8byte cs_mode, 0x00000000, write32_test # reset cs_mode
.8byte sck_div, 0x00000100, write32_test # lower SPI clock rate so reads are done at correct time when ICACHE not supported
.8byte tx_mark, 0x00000001, write32_test # set transmit watermark to 1 (any entry turns mark off) .8byte tx_mark, 0x00000001, write32_test # set transmit watermark to 1 (any entry turns mark off)
#.8byte ie, 0x00000000, write32_test # enable transmit interrupt #.8byte ie, 0x00000000, write32_test # enable transmit interrupt
.8byte ip, 0x00000001, read32_test # tx watermark interupt should be pending .8byte ip, 0x00000001, read32_test # tx watermark interupt should be pending