mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
mergingMerge branch 'main' of github.com:Thomas-J-Kidd/cvw
This commit is contained in:
commit
7871b1a43b
@ -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)/crt.S $(PORT_DIR)/encoding.h $(PORT_DIR)/util.h $(PORT_DIR)/syscalls.c
|
||||
ABI := $(if $(findstring "64","$(XLEN)"),lp64,ilp32)
|
||||
ARCH := rv$(XLEN)im_zicsr_zba_zbb_zbc_zbs
|
||||
#ARCH := rv$(XLEN)gc_zba_zbb_zbc_zbs
|
||||
#ARCH := rv$(XLEN)gc_zba_zbb_zbc
|
||||
ARCH := rv$(XLEN)im_zicsr_zba_zbb_zbc
|
||||
#ARCH := rv$(XLEN)gc
|
||||
#ARCH := rv$(XLEN)imc_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 \
|
||||
-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
|
||||
|
||||
run:
|
||||
|
@ -177,6 +177,7 @@ void _init(int cid, int nc)
|
||||
counters[17] = read_csr(mhpmcounter17) - counters[17];
|
||||
|
||||
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 Misses %d\n", counters[14]);
|
||||
ee_printf("I-Cache Accesses %d\n", counters[16]);
|
||||
|
@ -40,7 +40,8 @@ localparam ZIFENCEI_SUPPORTED = 1;
|
||||
localparam ZICNTR_SUPPORTED = 1;
|
||||
localparam ZIHPM_SUPPORTED = 1;
|
||||
localparam COUNTERS = 12'd32;
|
||||
localparam ZFH_SUPPORTED = 0;
|
||||
localparam ZFH_SUPPORTED = 1;
|
||||
localparam ZFA_SUPPORTED = 0;
|
||||
localparam SSTC_SUPPORTED = 1;
|
||||
localparam ZICBOM_SUPPORTED = 1;
|
||||
localparam ZICBOZ_SUPPORTED = 1;
|
||||
@ -56,7 +57,7 @@ localparam BUS_SUPPORTED = 1;
|
||||
localparam DCACHE_SUPPORTED = 1;
|
||||
localparam ICACHE_SUPPORTED = 1;
|
||||
localparam VIRTMEM_SUPPORTED = 1;
|
||||
localparam VECTORED_INTERRUPTS_SUPPORTED = 1 ;
|
||||
localparam VECTORED_INTERRUPTS_SUPPORTED = 1;
|
||||
localparam BIGENDIAN_SUPPORTED = 1;
|
||||
|
||||
// TLB configuration. Entries should be a power of 2
|
||||
@ -162,10 +163,10 @@ localparam RADIX = 32'h4;
|
||||
localparam DIVCOPIES = 32'h4;
|
||||
|
||||
// bit manipulation
|
||||
localparam ZBA_SUPPORTED = 0;
|
||||
localparam ZBB_SUPPORTED = 0;
|
||||
localparam ZBC_SUPPORTED = 0;
|
||||
localparam ZBS_SUPPORTED = 0;
|
||||
localparam ZBA_SUPPORTED = 1;
|
||||
localparam ZBB_SUPPORTED = 1;
|
||||
localparam ZBC_SUPPORTED = 1;
|
||||
localparam ZBS_SUPPORTED = 1;
|
||||
|
||||
// New compressed instructions
|
||||
localparam ZCB_SUPPORTED = 1;
|
||||
|
@ -41,6 +41,7 @@ localparam COUNTERS = 12'd0;
|
||||
localparam ZICNTR_SUPPORTED = 0;
|
||||
localparam ZIHPM_SUPPORTED = 0;
|
||||
localparam ZFH_SUPPORTED = 0;
|
||||
localparam ZFA_SUPPORTED = 0;
|
||||
localparam SSTC_SUPPORTED = 0;
|
||||
localparam ZICBOM_SUPPORTED = 0;
|
||||
localparam ZICBOZ_SUPPORTED = 0;
|
||||
|
@ -41,7 +41,8 @@ localparam ZIFENCEI_SUPPORTED = 1;
|
||||
localparam COUNTERS = 12'd32;
|
||||
localparam ZICNTR_SUPPORTED = 1;
|
||||
localparam ZIHPM_SUPPORTED = 1;
|
||||
localparam ZFH_SUPPORTED = 0;
|
||||
localparam ZFH_SUPPORTED = 1;
|
||||
localparam ZFA_SUPPORTED = 1;
|
||||
localparam SSTC_SUPPORTED = 1;
|
||||
localparam ZICBOM_SUPPORTED = 1;
|
||||
localparam ZICBOZ_SUPPORTED = 1;
|
||||
|
@ -41,6 +41,7 @@ localparam COUNTERS = 0;
|
||||
localparam ZICNTR_SUPPORTED = 0;
|
||||
localparam ZIHPM_SUPPORTED = 0;
|
||||
localparam ZFH_SUPPORTED = 0;
|
||||
localparam ZFA_SUPPORTED = 0;
|
||||
localparam SSTC_SUPPORTED = 0;
|
||||
localparam ZICBOM_SUPPORTED = 0;
|
||||
localparam ZICBOZ_SUPPORTED = 0;
|
||||
|
@ -40,6 +40,7 @@ localparam COUNTERS = 12'd32;
|
||||
localparam ZICNTR_SUPPORTED = 1;
|
||||
localparam ZIHPM_SUPPORTED = 1;
|
||||
localparam ZFH_SUPPORTED = 0;
|
||||
localparam ZFA_SUPPORTED = 0;
|
||||
localparam SSTC_SUPPORTED = 0;
|
||||
localparam ZICBOM_SUPPORTED = 0;
|
||||
localparam ZICBOZ_SUPPORTED = 0;
|
||||
|
@ -31,7 +31,7 @@
|
||||
localparam XLEN = 32'd64;
|
||||
|
||||
// IEEE 754 compliance
|
||||
localparam IEEE754 = 0;
|
||||
localparam IEEE754 = 1;
|
||||
|
||||
// MISA RISC-V configuration per specification
|
||||
localparam MISA = (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 16 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0 );
|
||||
@ -41,6 +41,7 @@ localparam COUNTERS = 12'd32;
|
||||
localparam ZICNTR_SUPPORTED = 1;
|
||||
localparam ZIHPM_SUPPORTED = 1;
|
||||
localparam ZFH_SUPPORTED = 1;
|
||||
localparam ZFA_SUPPORTED = 0;
|
||||
localparam SSTC_SUPPORTED = 0;
|
||||
localparam ZICBOM_SUPPORTED = 0;
|
||||
localparam ZICBOZ_SUPPORTED = 0;
|
||||
|
@ -40,7 +40,8 @@ localparam ZIFENCEI_SUPPORTED = 1;
|
||||
localparam COUNTERS = 12'd32;
|
||||
localparam ZICNTR_SUPPORTED = 1;
|
||||
localparam ZIHPM_SUPPORTED = 1;
|
||||
localparam ZFH_SUPPORTED = 0;
|
||||
localparam ZFH_SUPPORTED = 1;
|
||||
localparam ZFA_SUPPORTED = 0;
|
||||
localparam SSTC_SUPPORTED = 1;
|
||||
localparam ZICBOM_SUPPORTED = 1;
|
||||
localparam ZICBOZ_SUPPORTED = 1;
|
||||
|
@ -41,6 +41,7 @@ localparam COUNTERS = 0;
|
||||
localparam ZICNTR_SUPPORTED = 0;
|
||||
localparam ZIHPM_SUPPORTED = 0;
|
||||
localparam ZFH_SUPPORTED = 0;
|
||||
localparam ZFA_SUPPORTED = 0;
|
||||
localparam SSTC_SUPPORTED = 0;
|
||||
localparam ZICBOM_SUPPORTED = 0;
|
||||
localparam ZICBOZ_SUPPORTED = 0;
|
||||
|
@ -65,33 +65,29 @@ localparam H_NF = 32'd10;
|
||||
localparam H_BIAS = 32'd15;
|
||||
localparam H_FMT = 2'd2;
|
||||
|
||||
// Floating point length FLEN and number of exponent (NE) and fraction (NF) bits
|
||||
localparam FLEN = (Q_SUPPORTED ? Q_LEN : D_SUPPORTED ? D_LEN : S_LEN);
|
||||
localparam NE = (Q_SUPPORTED ? Q_NE : D_SUPPORTED ? D_NE : S_NE);
|
||||
localparam NF = (Q_SUPPORTED ? Q_NF : D_SUPPORTED ? D_NF : S_NF);
|
||||
localparam FMT = (Q_SUPPORTED ? 2'd3 : D_SUPPORTED ? 2'd1 : 2'd0);
|
||||
localparam BIAS = (Q_SUPPORTED ? Q_BIAS : D_SUPPORTED ? D_BIAS : S_BIAS);
|
||||
/* Delete once tested dh 10/10/22
|
||||
|
||||
localparam FLEN = (Q_SUPPORTED ? Q_LEN : D_SUPPORTED ? D_LEN : F_SUPPORTED ? S_LEN : H_LEN);
|
||||
localparam NE = (Q_SUPPORTED ? Q_NE : D_SUPPORTED ? D_NE : F_SUPPORTED ? S_NE : H_NE);
|
||||
localparam NF = (Q_SUPPORTED ? Q_NF : D_SUPPORTED ? D_NF : F_SUPPORTED ? S_NF : H_NF);
|
||||
localparam FMT = (Q_SUPPORTED ? 2'd3 : D_SUPPORTED ? 2'd1 : F_SUPPORTED ? 2'd0 : 2'd2);
|
||||
localparam BIAS = (Q_SUPPORTED ? Q_BIAS : D_SUPPORTED ? D_BIAS : F_SUPPORTED ? S_BIAS : H_BIAS);*/
|
||||
// Floating point length FLEN and number of exponent (NE) and fraction (NF) bits (for longest format supported)
|
||||
localparam FLEN = Q_SUPPORTED ? Q_LEN : D_SUPPORTED ? D_LEN : S_LEN;
|
||||
localparam NE = Q_SUPPORTED ? Q_NE : D_SUPPORTED ? D_NE : S_NE;
|
||||
localparam NF = Q_SUPPORTED ? Q_NF : D_SUPPORTED ? D_NF : S_NF;
|
||||
localparam FMT = Q_SUPPORTED ? 2'd3 : D_SUPPORTED ? 2'd1 : 2'd0;
|
||||
localparam BIAS = Q_SUPPORTED ? Q_BIAS : D_SUPPORTED ? D_BIAS : S_BIAS;
|
||||
|
||||
// Floating point constants needed for FPU paramerterization
|
||||
localparam FPSIZES = ((32)'(Q_SUPPORTED)+(32)'(D_SUPPORTED)+(32)'(F_SUPPORTED)+(32)'(ZFH_SUPPORTED));
|
||||
localparam FMTBITS = ((32)'(FPSIZES>=3)+1);
|
||||
localparam LEN1 = ((D_SUPPORTED & (FLEN != D_LEN)) ? D_LEN : (F_SUPPORTED & (FLEN != S_LEN)) ? S_LEN : H_LEN);
|
||||
localparam NE1 = ((D_SUPPORTED & (FLEN != D_LEN)) ? D_NE : (F_SUPPORTED & (FLEN != S_LEN)) ? S_NE : H_NE);
|
||||
localparam NF1 = ((D_SUPPORTED & (FLEN != D_LEN)) ? D_NF : (F_SUPPORTED & (FLEN != S_LEN)) ? S_NF : H_NF);
|
||||
localparam FMT1 = ((D_SUPPORTED & (FLEN != D_LEN)) ? 2'd1 : (F_SUPPORTED & (FLEN != S_LEN)) ? 2'd0 : 2'd2);
|
||||
localparam BIAS1 = ((D_SUPPORTED & (FLEN != D_LEN)) ? D_BIAS : (F_SUPPORTED & (FLEN != S_LEN)) ? S_BIAS : H_BIAS);
|
||||
localparam LEN2 = ((F_SUPPORTED & (LEN1 != S_LEN)) ? S_LEN : H_LEN);
|
||||
localparam NE2 = ((F_SUPPORTED & (LEN1 != S_LEN)) ? S_NE : H_NE);
|
||||
localparam NF2 = ((F_SUPPORTED & (LEN1 != S_LEN)) ? S_NF : H_NF);
|
||||
localparam FMT2 = ((F_SUPPORTED & (LEN1 != S_LEN)) ? 2'd0 : 2'd2);
|
||||
localparam BIAS2 = ((F_SUPPORTED & (LEN1 != S_LEN)) ? S_BIAS : H_BIAS);
|
||||
// LEN1/NE1/NF1/FNT1 is the size of the second longest supported format
|
||||
localparam FPSIZES = (32)'(Q_SUPPORTED)+(32)'(D_SUPPORTED)+(32)'(F_SUPPORTED)+(32)'(ZFH_SUPPORTED);
|
||||
localparam FMTBITS = (32)'(FPSIZES>=3)+1;
|
||||
localparam LEN1 = (FLEN > D_LEN) ? D_LEN : (FLEN > S_LEN) ? S_LEN : H_LEN;
|
||||
localparam NE1 = (FLEN > D_LEN) ? D_NE : (FLEN > S_LEN) ? S_NE : H_NE;
|
||||
localparam NF1 = (FLEN > D_LEN) ? D_NF : (FLEN > S_LEN) ? S_NF : H_NF;
|
||||
localparam FMT1 = (FLEN > D_LEN) ? 2'd1 : (FLEN > S_LEN) ? 2'd0 : 2'd2;
|
||||
localparam BIAS1 = (FLEN > D_LEN) ? D_BIAS : (FLEN > S_LEN) ? S_BIAS : H_BIAS;
|
||||
|
||||
// LEN2 etc is the size of the third longest supported format
|
||||
localparam LEN2 = (LEN1 > S_LEN) ? S_LEN : H_LEN;
|
||||
localparam NE2 = (LEN1 > S_LEN) ? S_NE : H_NE;
|
||||
localparam NF2 = (LEN1 > S_LEN) ? S_NF : H_NF;
|
||||
localparam FMT2 = (LEN1 > S_LEN) ? 2'd0 : 2'd2;
|
||||
localparam BIAS2 = (LEN1 > S_LEN) ? S_BIAS : H_BIAS;
|
||||
|
||||
// divider r and rk (bits per digit, bits per cycle)
|
||||
localparam LOGR = $clog2(RADIX); // r = log(R) bits per digit
|
||||
@ -115,7 +111,7 @@ localparam LLEN = (($unsigned(FLEN)<$unsigned(XLEN)) ? ($unsigned(XLEN)) : ($uns
|
||||
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 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
|
||||
|
@ -14,6 +14,7 @@ localparam cvw_t P = '{
|
||||
ZICNTR_SUPPORTED : ZICNTR_SUPPORTED,
|
||||
ZIHPM_SUPPORTED : ZIHPM_SUPPORTED,
|
||||
ZFH_SUPPORTED : ZFH_SUPPORTED,
|
||||
ZFA_SUPPORTED : ZFA_SUPPORTED,
|
||||
SSTC_SUPPORTED : SSTC_SUPPORTED,
|
||||
VIRTMEM_SUPPORTED : VIRTMEM_SUPPORTED,
|
||||
VECTORED_INTERRUPTS_SUPPORTED : VECTORED_INTERRUPTS_SUPPORTED,
|
||||
|
3
setup.sh
3
setup.sh
@ -16,8 +16,7 @@ echo \$WALLY set to ${WALLY}
|
||||
# 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 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-2022.4_3/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 SNPS_HOME=/cad/synopsys/SYN # Change this for your path to Design Compiler, excluding bin
|
||||
|
||||
# Path to RISC-V Tools
|
||||
|
@ -253,3 +253,10 @@ coverage exclude -srcfile priorityonehot.sv
|
||||
# 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/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
|
||||
|
@ -20,6 +20,7 @@
|
||||
# More extensions
|
||||
--override cpu/Zcb=T
|
||||
--override cpu/Zicond=T
|
||||
--override cpu/Zfh=T
|
||||
|
||||
# Cache block operations
|
||||
--override cpu/Zicbom=T
|
||||
@ -36,6 +37,8 @@
|
||||
# SV39 and SV48 supported
|
||||
--override cpu/Sv_modes=768
|
||||
|
||||
--override cpu/Svinval=T
|
||||
|
||||
|
||||
# clarify
|
||||
#--override refRoot/cpu/mtvec_sext=F
|
||||
|
5
src/cache/cacheway.sv
vendored
5
src/cache/cacheway.sv
vendored
@ -77,6 +77,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
logic ClearDirtyWay;
|
||||
logic SelNonHit;
|
||||
logic SelData;
|
||||
logic InvalidateCacheDelay;
|
||||
|
||||
if (!READ_ONLY_CACHE) begin:flushlogic
|
||||
logic FlushWayEn;
|
||||
@ -121,7 +122,9 @@ module cacheway import cvw::*; #(parameter cvw_t P,
|
||||
assign TagWay = SelData ? ReadTag : '0; // AND part of AOMux
|
||||
assign HitDirtyWay = Dirty & ValidWay;
|
||||
assign DirtyWay = SelDirty & HitDirtyWay;
|
||||
assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]);
|
||||
assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]) & ~InvalidateCacheDelay;
|
||||
|
||||
flop #(1) InvalidateCacheReg(clk, InvalidateCache, InvalidateCacheDelay);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Data Array
|
||||
|
@ -49,6 +49,7 @@ typedef struct packed {
|
||||
logic ZICNTR_SUPPORTED;
|
||||
logic ZIHPM_SUPPORTED;
|
||||
logic ZFH_SUPPORTED;
|
||||
logic ZFA_SUPPORTED;
|
||||
logic SSTC_SUPPORTED;
|
||||
logic VIRTMEM_SUPPORTED;
|
||||
logic VECTORED_INTERRUPTS_SUPPORTED;
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
module ahbinterface #(
|
||||
parameter XLEN,
|
||||
parameter LSU = 0 // 1: LSU bus width is `XLEN, 0: IFU bus width is 32 bits
|
||||
parameter logic LSU = 1'b0 // 1: LSU bus width is `XLEN, 0: IFU bus width is 32 bits
|
||||
)(
|
||||
input logic HCLK, HRESETn,
|
||||
// bus interface
|
||||
@ -44,6 +44,7 @@ module ahbinterface #(
|
||||
input logic Stall, // Core pipeline is stalled
|
||||
input logic Flush, // Pipeline stage flush. Prevents bus transaction from starting
|
||||
input logic [1:0] BusRW, // Memory operation read/write control: 10: read, 01: write
|
||||
input logic BusAtomic, // Uncache atomic memory operation
|
||||
input logic [XLEN/8-1:0] ByteMask, // Bytes enables within a word
|
||||
input logic [XLEN-1:0] WriteData, // IEU write data for a store
|
||||
output logic BusStall, // Bus is busy with an in flight memory operation
|
||||
@ -64,7 +65,7 @@ module ahbinterface #(
|
||||
assign HWSTRB = '0;
|
||||
end
|
||||
|
||||
busfsm busfsm(.HCLK, .HRESETn, .Flush, .BusRW,
|
||||
busfsm #(~LSU) busfsm(.HCLK, .HRESETn, .Flush, .BusRW, .BusAtomic,
|
||||
.BusCommitted, .Stall, .BusStall, .CaptureEn, .HREADY,
|
||||
.HTRANS, .HWRITE);
|
||||
|
||||
|
@ -66,7 +66,7 @@ module buscachefsm #(
|
||||
output logic [2:0] HBURST // AHB burst length
|
||||
);
|
||||
|
||||
typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, ATOMIC_PHASE, MEM3, CACHE_FETCH, CACHE_WRITEBACK} busstatetype;
|
||||
typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, ATOMIC_READ_DATA_PHASE, ATOMIC_PHASE, MEM3, CACHE_FETCH, CACHE_WRITEBACK} busstatetype;
|
||||
typedef enum logic [1:0] {AHB_IDLE = 2'b00, AHB_BUSY = 2'b01, AHB_NONSEQ = 2'b10, AHB_SEQ = 2'b11} ahbtranstype;
|
||||
|
||||
busstatetype CurrState, NextState;
|
||||
@ -87,13 +87,15 @@ module buscachefsm #(
|
||||
|
||||
always_comb begin
|
||||
case(CurrState)
|
||||
ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE;
|
||||
else if (HREADY & BusWrite) NextState = CACHE_WRITEBACK;
|
||||
else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH;
|
||||
else NextState = ADR_PHASE;
|
||||
DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_PHASE;
|
||||
else if(HREADY & ~BusAtomic) NextState = MEM3;
|
||||
ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE;
|
||||
else if (HREADY & BusWrite) NextState = CACHE_WRITEBACK;
|
||||
else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH;
|
||||
else NextState = ADR_PHASE;
|
||||
DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_READ_DATA_PHASE;
|
||||
else if(HREADY & ~BusAtomic) NextState = MEM3;
|
||||
else NextState = DATA_PHASE;
|
||||
ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE;
|
||||
else NextState = ATOMIC_READ_DATA_PHASE;
|
||||
ATOMIC_PHASE: if(HREADY) NextState = MEM3;
|
||||
else NextState = ATOMIC_PHASE;
|
||||
MEM3: if(Stall) NextState = MEM3;
|
||||
@ -107,7 +109,7 @@ module buscachefsm #(
|
||||
else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3;
|
||||
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
|
||||
else NextState = CACHE_WRITEBACK;
|
||||
default: NextState = ADR_PHASE;
|
||||
default: NextState = ADR_PHASE;
|
||||
endcase
|
||||
end
|
||||
|
||||
@ -129,6 +131,7 @@ module buscachefsm #(
|
||||
//(CurrState == DATA_PHASE & ~BusRW[0]) | // *** replace the next line with this. Fails uart test but i think it's a test problem not a hardware problem.
|
||||
(CurrState == DATA_PHASE) |
|
||||
(CurrState == ATOMIC_PHASE) |
|
||||
(CurrState == ATOMIC_READ_DATA_PHASE) |
|
||||
(CurrState == CACHE_FETCH & ~FinalBeatCount) |
|
||||
(CurrState == CACHE_WRITEBACK & ~FinalBeatCount);
|
||||
|
||||
@ -136,11 +139,11 @@ module buscachefsm #(
|
||||
|
||||
// AHB bus interface
|
||||
assign HTRANS = (CurrState == ADR_PHASE & HREADY & ((|BusRW) | (|CacheBusRW) | BusCMOZero) & ~Flush) |
|
||||
(CurrState == DATA_PHASE & BusAtomic) |
|
||||
(CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) |
|
||||
(CacheAccess & FinalBeatCount & |CacheBusRW & HREADY & ~Flush) ? AHB_NONSEQ : // if we have a pipelined request
|
||||
(CacheAccess & |BeatCount) ? (`BURST_EN ? AHB_SEQ : AHB_NONSEQ) : AHB_IDLE;
|
||||
|
||||
assign HWRITE = ((BusRW[0] & ~BusAtomic) | BusWrite & ~Flush) | (CurrState == DATA_PHASE & BusAtomic) |
|
||||
assign HWRITE = ((BusRW[0] & ~BusAtomic) | BusWrite & ~Flush) | (CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) |
|
||||
(CurrState == CACHE_WRITEBACK & |BeatCount);
|
||||
assign HBURST = `BURST_EN & ((|CacheBusRW & ~Flush) | (CacheAccess & |BeatCount)) ? LocalBurstType : 3'b0;
|
||||
|
||||
@ -159,6 +162,7 @@ module buscachefsm #(
|
||||
assign SelBusBeat = (CurrState == ADR_PHASE & (BusRW[0] | BusWrite)) |
|
||||
(CurrState == DATA_PHASE & BusRW[0]) |
|
||||
(CurrState == ATOMIC_PHASE & BusRW[0]) |
|
||||
(CurrState == ATOMIC_READ_DATA_PHASE & BusRW[0]) |
|
||||
(CurrState == CACHE_WRITEBACK) |
|
||||
(CurrState == CACHE_FETCH);
|
||||
|
||||
|
@ -28,7 +28,9 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// HCLK and clk must be the same clock!
|
||||
module busfsm (
|
||||
module busfsm #(
|
||||
parameter logic READ_ONLY
|
||||
)(
|
||||
input logic HCLK,
|
||||
input logic HRESETn,
|
||||
|
||||
@ -36,6 +38,7 @@ module busfsm (
|
||||
input logic Stall, // Core pipeline is stalled
|
||||
input logic Flush, // Pipeline stage flush. Prevents bus transaction from starting
|
||||
input logic [1:0] BusRW, // Memory operation read/write control: 10: read, 01: write
|
||||
input logic BusAtomic, // Uncache atomic memory operation
|
||||
output logic CaptureEn, // Enable updating the Fetch buffer with valid data from HRDATA
|
||||
output logic BusStall, // Bus is busy with an in flight memory operation
|
||||
output logic BusCommitted, // Bus is busy with an in flight memory operation and it is not safe to take an interrupt
|
||||
@ -45,7 +48,7 @@ module busfsm (
|
||||
output logic HWRITE // AHB 0: Read operation 1: Write operation
|
||||
);
|
||||
|
||||
typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, MEM3} busstatetype;
|
||||
typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, MEM3, ATOMIC_READ_DATA_PHASE, ATOMIC_PHASE} busstatetype;
|
||||
typedef enum logic [1:0] {AHB_IDLE = 2'b00, AHB_BUSY = 2'b01, AHB_NONSEQ = 2'b10, AHB_SEQ = 2'b11} ahbtranstype;
|
||||
|
||||
busstatetype CurrState, NextState;
|
||||
@ -56,24 +59,33 @@ module busfsm (
|
||||
|
||||
always_comb begin
|
||||
case(CurrState)
|
||||
ADR_PHASE: if(HREADY & |BusRW) NextState = DATA_PHASE;
|
||||
else NextState = ADR_PHASE;
|
||||
DATA_PHASE: if(HREADY) NextState = MEM3;
|
||||
else NextState = DATA_PHASE;
|
||||
MEM3: if(Stall) NextState = MEM3;
|
||||
else NextState = ADR_PHASE;
|
||||
default: NextState = ADR_PHASE;
|
||||
ADR_PHASE: if(HREADY & |BusRW) NextState = DATA_PHASE;
|
||||
else NextState = ADR_PHASE;
|
||||
DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_READ_DATA_PHASE;
|
||||
else if(HREADY & ~BusAtomic) NextState = MEM3;
|
||||
else NextState = DATA_PHASE;
|
||||
ATOMIC_READ_DATA_PHASE: if(HREADY) NextState = ATOMIC_PHASE;
|
||||
else NextState = ATOMIC_READ_DATA_PHASE;
|
||||
ATOMIC_PHASE: if(HREADY) NextState = MEM3;
|
||||
else NextState = ATOMIC_PHASE;
|
||||
MEM3: if(Stall) NextState = MEM3;
|
||||
else NextState = ADR_PHASE;
|
||||
default: NextState = ADR_PHASE;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign BusStall = (CurrState == ADR_PHASE & |BusRW) |
|
||||
// (CurrState == DATA_PHASE & ~BusRW[0]); // possible optimization here. fails uart test, but i'm not sure the failure is valid.
|
||||
(CurrState == ATOMIC_PHASE) |
|
||||
(CurrState == ATOMIC_READ_DATA_PHASE) |
|
||||
(CurrState == DATA_PHASE);
|
||||
|
||||
assign BusCommitted = CurrState != ADR_PHASE;
|
||||
assign BusCommitted = (CurrState != ADR_PHASE) & ~(READ_ONLY & CurrState == MEM3);
|
||||
|
||||
assign HTRANS = (CurrState == ADR_PHASE & HREADY & |BusRW & ~Flush) |
|
||||
(CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic) ? AHB_NONSEQ : AHB_IDLE;
|
||||
assign HWRITE = (BusRW[0] & ~BusAtomic) | (CurrState == ATOMIC_READ_DATA_PHASE & BusAtomic);
|
||||
|
||||
assign HTRANS = (CurrState == ADR_PHASE & HREADY & |BusRW & ~Flush) ? AHB_NONSEQ : AHB_IDLE;
|
||||
assign HWRITE = BusRW[0];
|
||||
assign CaptureEn = CurrState == DATA_PHASE;
|
||||
|
||||
endmodule
|
||||
|
@ -36,6 +36,7 @@
|
||||
module fcmp import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.FMTBITS-1:0] Fmt, // format of fp number
|
||||
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 [P.NE-1:0] Xe, Ye, // input exponents
|
||||
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'b101: CmpNV = EitherSNaN; //max
|
||||
3'b010: CmpNV = EitherSNaN; //equal
|
||||
3'b001: CmpNV = EitherNaN; //less than
|
||||
3'b011: CmpNV = EitherNaN; //less than or equal
|
||||
3'b001: CmpNV = Zfa ? EitherSNaN : EitherNaN; // fltq / flt perform CompareQuietLess / CompareSignalingLess differing on when to set invalid
|
||||
3'b011: CmpNV = Zfa ? EitherSNaN : EitherNaN; // fleq / fle differ on when to set invalid
|
||||
default: CmpNV = 1'bx;
|
||||
endcase
|
||||
end
|
||||
@ -128,23 +129,35 @@ module fcmp import cvw::*; #(parameter cvw_t P) (
|
||||
// - if one is a NaN output the non-NaN
|
||||
always_comb
|
||||
if(OpCtrl[0]) // MAX
|
||||
if(XNaN)
|
||||
if(YNaN) CmpFpRes = NaNRes; // X = NaN Y = NaN
|
||||
else CmpFpRes = Y; // X = NaN Y != NaN
|
||||
else
|
||||
if(YNaN) CmpFpRes = X; // X != NaN Y = NaN
|
||||
else // X,Y != NaN
|
||||
if(LT) CmpFpRes = Y; // X < Y
|
||||
else CmpFpRes = X; // X > Y
|
||||
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(YNaN) CmpFpRes = NaNRes; // X = NaN Y = NaN
|
||||
else CmpFpRes = Y; // X = NaN Y != NaN
|
||||
else
|
||||
if(YNaN) CmpFpRes = X; // X != NaN Y = NaN
|
||||
else // X,Y != NaN
|
||||
if(LT) CmpFpRes = Y; // X < Y
|
||||
else CmpFpRes = X; // X > Y
|
||||
else // MIN
|
||||
if(XNaN)
|
||||
if(YNaN) CmpFpRes = NaNRes; // X = NaN Y = NaN
|
||||
else CmpFpRes = Y; // X = NaN Y != NaN
|
||||
else
|
||||
if(YNaN) CmpFpRes = X; // X != NaN Y = NaN
|
||||
else // X,Y != NaN
|
||||
if(LT) CmpFpRes = X; // X < Y
|
||||
else CmpFpRes = Y; // X > Y
|
||||
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(YNaN) CmpFpRes = NaNRes; // X = NaN Y = NaN
|
||||
else CmpFpRes = Y; // X = NaN Y != NaN
|
||||
else
|
||||
if(YNaN) CmpFpRes = X; // X != NaN Y = NaN
|
||||
else // X,Y != NaN
|
||||
if(LT) CmpFpRes = X; // X < Y
|
||||
else CmpFpRes = Y; // X > Y
|
||||
|
||||
// LT/LE/EQ
|
||||
// - -0 = 0
|
||||
|
210
src/fpu/fctrl.sv
210
src/fpu/fctrl.sv
@ -38,7 +38,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||
input logic FDivBusyE, // is the divider busy
|
||||
// instruction
|
||||
input logic [31:0] InstrD, // the full instruction
|
||||
input logic [6:0] Funct7D, // bits 31:25 of instruction - may contain percision
|
||||
input logic [6:0] Funct7D, // bits 31:25 of instruction - may contain precision
|
||||
input logic [6:0] OpD, // bits 6:0 of instruction
|
||||
input logic [4:0] Rs2D, // bits 24:20 of instruction
|
||||
input logic [2:0] Funct3D, // bits 14:12 of instruction - may contain rounding mode
|
||||
@ -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] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage
|
||||
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
|
||||
output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable
|
||||
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
|
||||
);
|
||||
|
||||
`define FCTRLW 12
|
||||
`define FCTRLW 13
|
||||
|
||||
logic [`FCTRLW-1:0] ControlsD; // control signals
|
||||
logic FRegWriteD; // FP register write enable
|
||||
@ -79,138 +80,178 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||
logic SupportedFmt; // is the format supported
|
||||
logic SupportedFmt2; // is the source format supported for fp -> fp
|
||||
logic FCvtIntD, FCvtIntM; // convert to integer opperation
|
||||
logic ZfaD; // Zfa variants of instructions
|
||||
|
||||
// FPU Instruction Decoder
|
||||
assign Fmt = Funct7D[1:0];
|
||||
assign Fmt2 = Rs2D[1:0]; // source format for fcvt fp->fp
|
||||
|
||||
assign SupportedFmt = (Fmt == 2'b00 | (Fmt == 2'b01 & P.D_SUPPORTED) |
|
||||
(Fmt == 2'b10 & P.ZFH_SUPPORTED) | (Fmt == 2'b11 & P.Q_SUPPORTED));
|
||||
assign SupportedFmt = (Fmt == 2'b00 | (Fmt == 2'b01 & P.D_SUPPORTED) |
|
||||
(Fmt == 2'b10 & P.ZFH_SUPPORTED & {OpD[6:4], OpD[1:0]} != 5'b10011) | // fma not supported for Zfh
|
||||
(Fmt == 2'b11 & P.Q_SUPPORTED));
|
||||
assign SupportedFmt2 = (Fmt2 == 2'b00 | (Fmt2 == 2'b01 & P.D_SUPPORTED) |
|
||||
(Fmt2 == 2'b10 & P.ZFH_SUPPORTED) | (Fmt2 == 2'b11 & P.Q_SUPPORTED));
|
||||
|
||||
// decode the instruction
|
||||
// FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt
|
||||
// FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt_Zfa
|
||||
always_comb
|
||||
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)
|
||||
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
|
||||
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
|
||||
case(OpD)
|
||||
7'b0000111: case(Funct3D)
|
||||
3'b010: ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0; // flw
|
||||
3'b011: if (P.D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0; // fld
|
||||
3'b100: if (P.Q_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0; // flq
|
||||
3'b001: if (P.ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0; // flh
|
||||
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_0; // fld
|
||||
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_0; // flh
|
||||
endcase
|
||||
7'b0100111: case(Funct3D)
|
||||
3'b010: ControlsD = `FCTRLW'b0_0_10_00_0xx_0_0_0; // fsw
|
||||
3'b011: if (P.D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_00_0xx_0_0_0; // fsd
|
||||
3'b100: if (P.Q_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_00_0xx_0_0_0; // fsq
|
||||
3'b001: if (P.ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_00_0xx_0_0_0; // fsh
|
||||
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_0; // fsd
|
||||
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_0; // fsh
|
||||
endcase
|
||||
7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0_0; // fmadd
|
||||
7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0_0; // fmsub
|
||||
7'b1001011: ControlsD = `FCTRLW'b1_0_01_10_010_0_0_0; // fnmsub
|
||||
7'b1001111: ControlsD = `FCTRLW'b1_0_01_10_011_0_0_0; // fnmadd
|
||||
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_0; // fmsub
|
||||
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_0; // fnmadd
|
||||
7'b1010011: casez(Funct7D)
|
||||
7'b00000??: ControlsD = `FCTRLW'b1_0_01_10_110_0_0_0; // fadd
|
||||
7'b00001??: ControlsD = `FCTRLW'b1_0_01_10_111_0_0_0; // fsub
|
||||
7'b00010??: ControlsD = `FCTRLW'b1_0_01_10_100_0_0_0; // fmul
|
||||
7'b00011??: ControlsD = `FCTRLW'b1_0_01_01_xx0_1_0_0; // fdiv
|
||||
7'b01011??: if (Rs2D == 5'b0000) ControlsD = `FCTRLW'b1_0_01_01_xx1_1_0_0; // fsqrt
|
||||
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_0; // fsub
|
||||
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_0; // fdiv
|
||||
7'b01011??: if (Rs2D == 5'b0000) ControlsD = `FCTRLW'b1_0_01_01_xx1_1_0_0_0; // fsqrt
|
||||
7'b00100??: case(Funct3D)
|
||||
3'b000: ControlsD = `FCTRLW'b1_0_00_00_000_0_0_0; // fsgnj
|
||||
3'b001: ControlsD = `FCTRLW'b1_0_00_00_001_0_0_0; // fsgnjn
|
||||
3'b010: ControlsD = `FCTRLW'b1_0_00_00_010_0_0_0; // fsgnjx
|
||||
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_0; // fsgnjn
|
||||
3'b010: ControlsD = `FCTRLW'b1_0_00_00_010_0_0_0_0; // fsgnjx
|
||||
endcase
|
||||
7'b00101??: case(Funct3D)
|
||||
3'b000: ControlsD = `FCTRLW'b1_0_00_00_110_0_0_0; // fmin
|
||||
3'b001: ControlsD = `FCTRLW'b1_0_00_00_101_0_0_0; // fmax
|
||||
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_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
|
||||
7'b10100??: case(Funct3D)
|
||||
3'b010: ControlsD = `FCTRLW'b0_1_00_00_010_0_0_0; // feq
|
||||
3'b001: ControlsD = `FCTRLW'b0_1_00_00_001_0_0_0; // flt
|
||||
3'b000: ControlsD = `FCTRLW'b0_1_00_00_011_0_0_0; // fle
|
||||
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_0; // flt
|
||||
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
|
||||
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)
|
||||
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
|
||||
else if (P.ZFA_SUPPORTED & P.XLEN == 32 & P.D_SUPPORTED & Funct7D[1:0] == 2'b01 & Funct3D == 3'b000 & Rs2D == 5'b00001)
|
||||
ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0_1; // fmvh.x.d (Zfa)
|
||||
// Q not supported in RV64GC
|
||||
// coverage off
|
||||
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; // fmv.w/d/h/q.x int to fp reg
|
||||
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; // fcvt.s.(d/q/h)
|
||||
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; // fcvt.d.(s/h/q)
|
||||
// coverage off
|
||||
// Not covered in testing because rv64gc does not support half or quad precision
|
||||
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)
|
||||
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)
|
||||
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
|
||||
7'b1101000: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_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'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_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'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_0; // fcvt.s.wu wu->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_0; // fcvt.s.lu lu->s
|
||||
endcase
|
||||
7'b1100000: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w
|
||||
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu
|
||||
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l
|
||||
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu
|
||||
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_0; // fcvt.wu.s s->wu
|
||||
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_0; // fcvt.lu.s s->lu
|
||||
endcase
|
||||
7'b1101001: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_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'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_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'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_0; // fcvt.d.wu wu->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_0; // fcvt.d.lu lu->d
|
||||
endcase
|
||||
7'b1100001: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w
|
||||
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu
|
||||
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l
|
||||
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu
|
||||
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_0; // fcvt.wu.d d->wu
|
||||
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_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
|
||||
// coverage off
|
||||
// Not covered in testing because rv64gc does not support half or quad precision
|
||||
7'b1101010: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_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'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_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'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_0; // fcvt.h.wu wu->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_0; // fcvt.h.lu lu->h
|
||||
endcase
|
||||
7'b1100010: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.h h->w
|
||||
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.h h->wu
|
||||
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.h h->l
|
||||
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.h h->lu
|
||||
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_0; // fcvt.wu.h h->wu
|
||||
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_0; // fcvt.lu.h h->lu
|
||||
endcase
|
||||
// Not covered in testing because rv64gc does not support quad precision
|
||||
// coverage off
|
||||
7'b1101011: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_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'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_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'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_0; // fcvt.q.wu wu->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_0; // fcvt.q.lu lu->q
|
||||
endcase
|
||||
7'b1100011: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.q q->w
|
||||
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu
|
||||
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l
|
||||
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu
|
||||
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_0; // fcvt.wu.q q->wu
|
||||
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_0; // fcvt.lu.q q->lu
|
||||
endcase
|
||||
// coverage on
|
||||
endcase
|
||||
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
|
||||
end
|
||||
/* verilator lint_on CASEINCOMPLETE */
|
||||
|
||||
// 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:
|
||||
// 000 - round to nearest, ties to even
|
||||
@ -273,6 +314,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||
// 011 - mv to fp 01
|
||||
// 110 - min 10
|
||||
// 101 - max 10
|
||||
// 111 - fli 11
|
||||
|
||||
// OpCtrl:
|
||||
// Fma: {not multiply-add?, negate prod?, negate Z?}
|
||||
@ -309,9 +351,9 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||
assign Adr3D = InstrD[31:27];
|
||||
|
||||
// D/E pipleine register
|
||||
flopenrc #(14+P.FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE,
|
||||
{FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, FCvtIntD, ~IllegalFPUInstrD},
|
||||
{FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, FPUActiveE});
|
||||
flopenrc #(15+P.FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE,
|
||||
{FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, FCvtIntD, ZfaD, ~IllegalFPUInstrD},
|
||||
{FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, ZfaE, FPUActiveE});
|
||||
flopenrc #(15) DEAdrReg(clk, reset, FlushE, ~StallE, {Adr1D, Adr2D, Adr3D}, {Adr1E, Adr2E, Adr3E});
|
||||
flopenrc #(1) DEFDivStartReg(clk, reset, FlushE, ~StallE|FDivBusyE, FDivStartD, FDivStartE);
|
||||
flopenrc #(3) DEEnReg(clk, reset, FlushE, ~StallE, {XEnD, YEnD, ZEnD}, {XEnE, YEnE, ZEnE});
|
||||
@ -321,9 +363,9 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||
else assign IDivStartE = 0;
|
||||
|
||||
// E/M pipleine register
|
||||
flopenrc #(13+int'(P.FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM,
|
||||
{FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE},
|
||||
{FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM, FCvtIntM});
|
||||
flopenrc #(14+int'(P.FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM,
|
||||
{FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, FCvtIntE, ZfaE},
|
||||
{FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM, FCvtIntM, ZfaM});
|
||||
|
||||
// renameing for readability
|
||||
assign FpLoadStoreM = FResSelM[1];
|
||||
|
@ -69,9 +69,9 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
|
||||
assign Int64 = OpCtrl[1];
|
||||
assign IntToFp = OpCtrl[2];
|
||||
|
||||
// choose the ouptut format depending on the opperation
|
||||
// - fp -> fp: OpCtrl contains the percision of the output
|
||||
// - int -> fp: Fmt contains the percision of the output
|
||||
// choose the output format depending on the opperation
|
||||
// - fp -> fp: OpCtrl contains the precision of the output
|
||||
// - int -> fp: Fmt contains the precision of the output
|
||||
if (P.FPSIZES == 2)
|
||||
assign OutFmt = IntToFp ? Fmt : (OpCtrl[1:0] == P.FMT);
|
||||
else if (P.FPSIZES == 3 | P.FPSIZES == 4)
|
||||
|
219
src/fpu/fli.sv
Normal file
219
src/fpu/fli.sv
Normal 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
|
@ -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 FRegWriteE; // Write floating-point register
|
||||
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
|
||||
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
|
||||
|
||||
// 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] BoxedOneE; // One value for Z for multiplication, with NaN boxing if needed
|
||||
logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt
|
||||
logic [P.FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer
|
||||
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
|
||||
@ -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]),
|
||||
.IntDivE, .InstrD,
|
||||
.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,
|
||||
.IllegalFPUInstrD, .XEnD, .YEnD, .ZEnD, .XEnE, .YEnE, .ZEnE,
|
||||
.FResSelE, .FResSelM, .FResSelW, .FPUActiveE, .PostProcSelE, .PostProcSelM, .FCvtIntW,
|
||||
@ -246,7 +248,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
|
||||
.UmM, .FIntDivResultM);
|
||||
|
||||
// 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),
|
||||
.XSNaN(XSNaNE), .YSNaN(YSNaNE), .X(XE), .Y(YE), .CmpNV(CmpNVE),
|
||||
.CmpFpRes(CmpFpResE), .CmpIntRes(CmpIntResE));
|
||||
@ -263,37 +265,53 @@ module fpu import cvw::*; #(parameter cvw_t P) (
|
||||
.ToInt(FWriteIntE), .XZero(XZeroE), .Fmt(FmtE), .Ce(CeE), .ShiftAmt(CvtShiftAmtE),
|
||||
.ResSubnormUf(CvtResSubnormUfE), .Cs(CsE), .IntZero(IntZeroE), .LzcIn(CvtLzcInE));
|
||||
|
||||
// NaN Box SrcA to convert integer to requested FP size
|
||||
if(P.FPSIZES == 1) assign AlignedSrcAE = {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE};
|
||||
// floating-point load immediate: fli
|
||||
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)
|
||||
mux2 #(P.FLEN) SrcAMux ({{P.FLEN-P.LEN1{1'b1}}, ForwardedSrcAE[P.LEN1-1:0]}, {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE}, FmtE, AlignedSrcAE);
|
||||
else if(P.FPSIZES == 3 | P.FPSIZES == 4)
|
||||
mux4 #(P.FLEN) SrcAMux ({{P.FLEN-P.S_LEN{1'b1}}, ForwardedSrcAE[P.S_LEN-1:0]},
|
||||
{{P.FLEN-P.D_LEN{1'b1}}, ForwardedSrcAE[P.D_LEN-1:0]},
|
||||
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
|
||||
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]},
|
||||
{{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.XLEN{1'b1}}, ForwardedSrcAE}, FmtE, AlignedSrcAE); // NaN boxing zeroes
|
||||
FmtE, PreIntSrcE); // NaN boxing zeroes
|
||||
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
|
||||
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);
|
||||
|
||||
// select the result that may be written to the integer register with fmv - to IEU
|
||||
// fmv.x.*: select the result that may be written to the integer register
|
||||
if(P.FPSIZES == 1) begin
|
||||
assign mvsgn = XE[P.FLEN-1];
|
||||
assign SgnExtXE = XE;
|
||||
end else if(P.FPSIZES == 2) begin
|
||||
mux2 #(1) sgnmux (XE[P.LEN1-1], XE[P.FLEN-1],FmtE, mvsgn);
|
||||
mux2 #(1) sgnmux (XE[P.LEN1-1], XE[P.FLEN-1],FmtE, mvsgn);
|
||||
mux2 #(P.FLEN) sgnextmux ({{P.FLEN-P.LEN1{mvsgn}}, XE[P.LEN1-1:0]}, XE, FmtE, SgnExtXE);
|
||||
end else if(P.FPSIZES == 3 | P.FPSIZES == 4) begin
|
||||
mux4 #(1) sgnmux (XE[P.H_LEN-1], XE[P.S_LEN-1], XE[P.D_LEN-1], XE[P.LLEN-1], FmtE, mvsgn);
|
||||
mux4 #(P.FLEN) fmulzeromux ({{P.FLEN-P.H_LEN{mvsgn}}, XE[P.H_LEN-1:0]},
|
||||
{{P.FLEN-P.S_LEN{mvsgn}}, XE[P.S_LEN-1:0]},
|
||||
{{P.FLEN-P.D_LEN{mvsgn}}, XE[P.D_LEN-1:0]},
|
||||
XE, FmtE, SgnExtXE);
|
||||
mux4 #(1) sgnmux (XE[P.S_LEN-1], XE[P.D_LEN-1], XE[P.H_LEN-1], XE[P.LLEN-1], FmtE, mvsgn);
|
||||
mux3 #(P.FLEN) sgnextmux ({{P.FLEN-P.S_LEN{mvsgn}}, XE[P.S_LEN-1:0]},
|
||||
{{P.FLEN-P.D_LEN{mvsgn}}, XE[P.D_LEN-1:0]},
|
||||
{{P.FLEN-P.H_LEN{mvsgn}}, XE[P.H_LEN-1:0]},
|
||||
FmtE, SgnExtXE); // Q not needed because there is no fmv.x.q
|
||||
end
|
||||
|
||||
// sign extend to XLEN if necessary
|
||||
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
|
||||
assign IntSrcXE = {{P.XLEN-P.FLEN{mvsgn}}, SgnExtXE};
|
||||
mux3 #(P.XLEN) IntResMux (ClassResE, IntSrcXE, CmpIntResE, {~FResSelE[1], FResSelE[0]}, FIntResE);
|
||||
@ -330,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),
|
||||
.FmaSm(SmM), .DivUe(UeM), .FmaAs(AsM), .FmaPs(PsM), .OpCtrl(OpCtrlM), .FmaSCnt(SCntM), .FmaSe(SeM),
|
||||
.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));
|
||||
|
||||
// FPU flag selection - to privileged
|
||||
|
@ -82,7 +82,7 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||
P.FMT: ResNegNF = -($clog2(P.NF)+1)'(P.NF);
|
||||
P.FMT1: ResNegNF = -($clog2(P.NF)+1)'(P.NF1);
|
||||
P.FMT2: ResNegNF = -($clog2(P.NF)+1)'(P.NF2);
|
||||
default: ResNegNF = 'x;
|
||||
default: ResNegNF = 0; // Not used for floating-point so don't care, but convert to unsigned long has OutFmt = 11.
|
||||
endcase
|
||||
|
||||
end else if (P.FPSIZES == 4) begin
|
||||
|
@ -70,7 +70,7 @@ module flags import cvw::*; #(parameter cvw_t P) (
|
||||
logic DivInvalid; // integer invalid flag
|
||||
logic Underflow; // Underflow flag
|
||||
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
|
||||
|
@ -50,7 +50,7 @@ module fmashiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||
// calculate the sum's exponent
|
||||
assign PreNormSumExp = FmaSe + {{P.NE+2-$unsigned($clog2(3*P.NF+5)){1'b1}}, ~FmaSCnt} + (P.NE+2)'(P.NF+3);
|
||||
|
||||
//convert the sum's exponent into the proper percision
|
||||
//convert the sum's exponent into the proper precision
|
||||
if (P.FPSIZES == 1) begin
|
||||
assign NormSumExp = PreNormSumExp;
|
||||
end else if (P.FPSIZES == 2) begin
|
||||
|
@ -56,6 +56,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
||||
input logic CvtResSubnormUf, // the convert result is subnormal or underflows
|
||||
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 Zfa, // Zfa operation (fcvtmod.w.d)
|
||||
input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
|
||||
input logic IntZero, // is the integer input zero
|
||||
// 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 FmaPreResultSubnorm; // is the result subnormal - calculated before LZA corection
|
||||
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.NORMSHIFTSZ-1:0] DivShiftIn; // divsqrt shift input
|
||||
logic [P.NE+1:0] Ue; // divsqrt corrected exponent after corretion shift
|
||||
@ -127,9 +128,9 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
||||
assign InfIn = XInf|YInf|ZInf;
|
||||
assign NaNIn = XNaN|YNaN|ZNaN;
|
||||
|
||||
// choose the ouptut format depending on the opperation
|
||||
// - fp -> fp: OpCtrl contains the percision of the output
|
||||
// - otherwise: Fmt contains the percision of the output
|
||||
// choose the output format depending on the opperation
|
||||
// - fp -> fp: OpCtrl contains the precision of the output
|
||||
// - otherwise: Fmt contains the precision of the output
|
||||
if (P.FPSIZES == 2)
|
||||
assign OutFmt = IntToFp|~CvtOp ? Fmt : (OpCtrl[1:0] == P.FMT);
|
||||
else if (P.FPSIZES == 3 | P.FPSIZES == 4)
|
||||
@ -216,9 +217,9 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
negateintres #(P) negateintres(.Xs, .Shifted, .Signed, .Int64, .Plus1, .CvtNegResMsbs, .CvtNegRes);
|
||||
|
||||
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,
|
||||
.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);
|
||||
|
||||
endmodule
|
||||
|
@ -145,18 +145,18 @@ module round import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
end else if (P.FPSIZES == 3) begin
|
||||
// 1: XLEN > NF > NF1
|
||||
if (XLENPOS == 1) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF2-2:P.CORRSHIFTSZ-P.NF1-1]&FpRes&(OutFmt==P.FMT1)) |
|
||||
if (XLENPOS == 1) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF2-2:P.CORRSHIFTSZ-P.NF1-1]&FpRes&(OutFmt==P.FMT2)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.NF-1]&FpRes&~(OutFmt==P.FMT)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.XLEN-2:0]);
|
||||
// 2: NF > XLEN > NF1
|
||||
if (XLENPOS == 2) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF2-2:P.CORRSHIFTSZ-P.NF1-1]&FpRes&(OutFmt==P.FMT1)) |
|
||||
if (XLENPOS == 2) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF2-2:P.CORRSHIFTSZ-P.NF1-1]&FpRes&(OutFmt==P.FMT2)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes&~(OutFmt==P.FMT)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF-1]&(IntRes|~(OutFmt==P.FMT))) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF-2:0]);
|
||||
// 3: NF > NF1 > XLEN
|
||||
if (XLENPOS == 3) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF2-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes&(OutFmt==P.FMT1)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF1-1]&((OutFmt==P.FMT1)|IntRes)) |
|
||||
if (XLENPOS == 3) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF2-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes&(OutFmt==P.FMT2)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF1-1]&((OutFmt==P.FMT2)|IntRes)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.NF-1]&(~(OutFmt==P.FMT)|IntRes)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF-2:0]);
|
||||
|
||||
|
@ -44,7 +44,7 @@ module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
||||
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] CorrQmShifted; // the shifted divsqrt result after one bit shift
|
||||
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
|
||||
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 Mf = Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.CORRSHIFTSZ];
|
||||
|
||||
|
@ -53,6 +53,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
|
||||
input logic IntToFp, // is cvt int -> fp opperation
|
||||
input logic Int64, // is the integer 64 bits
|
||||
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 IntInvalid, // integer invalid flag to choose the result
|
||||
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] NormRes; // normal result
|
||||
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 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
|
||||
// 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
|
||||
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
|
||||
// - 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 the normal res (trmined and sign extended if nessisary)
|
||||
always_comb
|
||||
if(IntInvalid) FCvtIntRes = OfIntRes;
|
||||
if(SelCvtOfRes) FCvtIntRes = OfIntRes2;
|
||||
else if(CvtCe[P.NE])
|
||||
if(Xs&Signed&Plus1) FCvtIntRes = {{P.XLEN{1'b1}}};
|
||||
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]};
|
||||
endmodule
|
||||
|
@ -370,7 +370,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
|
||||
// Fences
|
||||
// Ordinary fence is presently a nop
|
||||
// fence.i flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented
|
||||
if (P.ZIFENCEI_SUPPORTED & P.ICACHE_SUPPORTED) begin:fencei
|
||||
if (P.ZIFENCEI_SUPPORTED & (P.ICACHE_SUPPORTED | P.DCACHE_SUPPORTED)) begin:fencei
|
||||
logic FenceID;
|
||||
assign FenceID = FenceXD & (Funct3D == 3'b001); // is it a FENCE.I instruction?
|
||||
assign InvalidateICacheD = FenceID;
|
||||
|
@ -273,9 +273,9 @@ module ifu import cvw::*; #(parameter cvw_t P) (
|
||||
assign BusRW = ~ITLBMissF & ~SelIROM ? IFURWF : '0;
|
||||
assign IFUHSIZE = 3'b010;
|
||||
|
||||
ahbinterface #(P.XLEN, 0) ahbinterface(.HCLK(clk), .Flush(FlushD), .HRESETn(~reset), .HREADY(IFUHREADY),
|
||||
ahbinterface #(P.XLEN, 1'b0) ahbinterface(.HCLK(clk), .Flush(FlushD), .HRESETn(~reset), .HREADY(IFUHREADY),
|
||||
.HRDATA(HRDATA), .HTRANS(IFUHTRANS), .HWRITE(IFUHWRITE), .HWDATA(),
|
||||
.HWSTRB(), .BusRW, .ByteMask(), .WriteData('0),
|
||||
.HWSTRB(), .BusRW, .BusAtomic('0), .ByteMask(), .WriteData('0),
|
||||
.Stall(GatedStallD), .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(FetchBuffer));
|
||||
|
||||
assign CacheCommittedF = '0;
|
||||
|
@ -111,7 +111,9 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
logic GatedStallW; // Hazard unit StallW gated when SelHPTW = 1
|
||||
|
||||
logic BusStall; // Bus interface busy with multicycle operation
|
||||
logic LSUBusStallM; // Bus interface busy with multicycle operation masked by IgnoreRequestTLB
|
||||
logic HPTWStall; // HPTW busy with multicycle operation
|
||||
logic DCacheBusStallM; // Cache or bus stall
|
||||
logic CacheBusHPWTStall; // Cache, bus, or hptw is requesting a stall
|
||||
logic SelSpillE; // Align logic detected a spill and needs to stall
|
||||
|
||||
@ -194,7 +196,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
if(P.VIRTMEM_SUPPORTED) begin : hptw
|
||||
hptw #(P) hptw(.clk, .reset, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF,
|
||||
.DTLBMissM, .DTLBWriteM, .InstrUpdateDAF, .DataUpdateDAM,
|
||||
.FlushW, .DCacheStallM, .SATP_REGW, .PCSpillF,
|
||||
.FlushW, .DCacheBusStallM, .SATP_REGW, .PCSpillF,
|
||||
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_ADUE, .PrivilegeModeW,
|
||||
.ReadDataM(ReadDataM[P.XLEN-1:0]), // ReadDataM is LLEN, but HPTW only needs XLEN
|
||||
.WriteDataM(WriteDataZM), .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M,
|
||||
@ -225,7 +227,8 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
// the trap module.
|
||||
assign CommittedM = SelHPTW | DCacheCommittedM | BusCommittedM;
|
||||
assign GatedStallW = StallW & ~SelHPTW;
|
||||
assign CacheBusHPWTStall = DCacheStallM | HPTWStall | BusStall;
|
||||
assign DCacheBusStallM = DCacheStallM | LSUBusStallM;
|
||||
assign CacheBusHPWTStall = DCacheBusStallM | HPTWStall;
|
||||
assign LSUStallM = CacheBusHPWTStall | SpillStallM;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -342,7 +345,6 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
assign DCacheStallM = CacheStall & ~IgnoreRequestTLB;
|
||||
assign CacheBusRW = CacheBusRWTemp;
|
||||
|
||||
// *** add support for cboz
|
||||
ahbcacheinterface #(.AHBW(P.AHBW), .LLEN(P.LLEN), .PA_BITS(P.PA_BITS), .BEATSPERLINE(BEATSPERLINE), .AHBWLOGBWPL(AHBWLOGBWPL), .LINELEN(LINELEN), .LLENPOVERAHBW(LLENPOVERAHBW), .READ_ONLY_CACHE(0)) ahbcacheinterface(
|
||||
.HCLK(clk), .HRESETn(~reset), .Flush(FlushW | IgnoreRequestTLB),
|
||||
.HRDATA, .HWDATA(LSUHWDATA), .HWSTRB(LSUHWSTRB),
|
||||
@ -353,6 +355,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
.Cacheable(CacheableOrFlushCacheM), .BusRW, .Stall(GatedStallW),
|
||||
.BusStall, .BusCommitted(BusCommittedM));
|
||||
|
||||
|
||||
// Mux between the 3 sources of read data, 0: cache, 1: Bus, 2: DTIM
|
||||
// Uncache bus access may be smaller width than LLEN. Duplicate LLENPOVERAHBW times.
|
||||
// *** DTIMReadDataWordM should be increased to LLEN.
|
||||
@ -368,9 +371,9 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
assign LSUHADDR = PAdrM;
|
||||
assign LSUHSIZE = LSUFunct3M;
|
||||
|
||||
ahbinterface #(P.XLEN, 1) ahbinterface(.HCLK(clk), .HRESETn(~reset), .Flush(FlushW), .HREADY(LSUHREADY),
|
||||
ahbinterface #(P.XLEN, 1'b1) ahbinterface(.HCLK(clk), .HRESETn(~reset), .Flush(FlushW), .HREADY(LSUHREADY),
|
||||
.HRDATA(HRDATA), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HWDATA(LSUHWDATA),
|
||||
.HWSTRB(LSUHWSTRB), .BusRW, .ByteMask(ByteMaskM), .WriteData(LSUWriteDataM[P.XLEN-1:0]),
|
||||
.HWSTRB(LSUHWSTRB), .BusRW, .BusAtomic(AtomicM[1]), .ByteMask(ByteMaskM), .WriteData(LSUWriteDataM[P.XLEN-1:0]),
|
||||
.Stall(GatedStallW), .BusStall, .BusCommitted(BusCommittedM), .FetchBuffer(FetchBuffer));
|
||||
|
||||
// Mux between the 2 sources of read data, 0: Bus, 1: DTIM
|
||||
@ -387,6 +390,8 @@ module lsu import cvw::*; #(parameter cvw_t P) (
|
||||
assign {DCacheStallM, DCacheCommittedM} = '0;
|
||||
end
|
||||
|
||||
assign LSUBusStallM = BusStall & ~IgnoreRequestTLB;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Atomic operations
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -42,7 +42,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic [P.XLEN-1:0] ReadDataM, // page table entry from LSU
|
||||
input logic [P.XLEN-1:0] WriteDataM,
|
||||
input logic DCacheStallM, // stall from LSU
|
||||
input logic DCacheBusStallM, // stall from LSU
|
||||
input logic [2:0] Funct3M,
|
||||
input logic [6:0] Funct7M,
|
||||
input logic ITLBMissF,
|
||||
@ -145,7 +145,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// State flops
|
||||
flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrUpdateDAM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB)
|
||||
assign PRegEn = HPTWRW[1] & ~DCacheStallM | UpdatePTE;
|
||||
assign PRegEn = HPTWRW[1] & ~DCacheBusStallM | UpdatePTE;
|
||||
flopenr #(P.XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache
|
||||
|
||||
// Assign PTE descriptors common across all XLEN values
|
||||
@ -283,30 +283,30 @@ module hptw import cvw::*; #(parameter cvw_t P) (
|
||||
flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState);
|
||||
always_comb
|
||||
case (WalkerState)
|
||||
IDLE: if (TLBMiss & ~DCacheStallM) NextWalkerState = InitialWalkerState;
|
||||
IDLE: if (TLBMiss & ~DCacheBusStallM) NextWalkerState = InitialWalkerState;
|
||||
else NextWalkerState = IDLE;
|
||||
L3_ADR: NextWalkerState = L3_RD; // first access in SV48
|
||||
L3_RD: if (DCacheStallM) NextWalkerState = L3_RD;
|
||||
L3_RD: if (DCacheBusStallM) NextWalkerState = L3_RD;
|
||||
else if(HPTWFaultM) NextWalkerState = FAULT;
|
||||
else NextWalkerState = L2_ADR;
|
||||
L2_ADR: if (InitialWalkerState == L2_ADR | ValidNonLeafPTE) NextWalkerState = L2_RD; // first access in SV39
|
||||
else NextWalkerState = LEAF;
|
||||
L2_RD: if (DCacheStallM) NextWalkerState = L2_RD;
|
||||
L2_RD: if (DCacheBusStallM) NextWalkerState = L2_RD;
|
||||
else if(HPTWFaultM) NextWalkerState = FAULT;
|
||||
else NextWalkerState = L1_ADR;
|
||||
L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32
|
||||
else NextWalkerState = LEAF;
|
||||
L1_RD: if (DCacheStallM) NextWalkerState = L1_RD;
|
||||
L1_RD: if (DCacheBusStallM) NextWalkerState = L1_RD;
|
||||
else if(HPTWFaultM) NextWalkerState = FAULT;
|
||||
else NextWalkerState = L0_ADR;
|
||||
L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD;
|
||||
else NextWalkerState = LEAF;
|
||||
L0_RD: if (DCacheStallM) NextWalkerState = L0_RD;
|
||||
L0_RD: if (DCacheBusStallM) NextWalkerState = L0_RD;
|
||||
else if(HPTWFaultM) NextWalkerState = FAULT;
|
||||
else NextWalkerState = LEAF;
|
||||
LEAF: if (P.SVADU_SUPPORTED & HPTWUpdateDA) NextWalkerState = UPDATE_PTE;
|
||||
else NextWalkerState = IDLE;
|
||||
UPDATE_PTE: if(DCacheStallM) NextWalkerState = UPDATE_PTE;
|
||||
UPDATE_PTE: if(DCacheBusStallM) NextWalkerState = UPDATE_PTE;
|
||||
else NextWalkerState = LEAF;
|
||||
FAULT: NextWalkerState = IDLE;
|
||||
default: NextWalkerState = IDLE; // should never be reached
|
||||
|
@ -140,7 +140,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
|
||||
2'b11: DataMisalignedM = |VAdr[2:0]; // ld, sd, fld, fsd
|
||||
endcase
|
||||
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
|
||||
assign InstrPageFaultF = TLBPageFault & ExecuteAccessF;
|
||||
|
@ -232,95 +232,7 @@ module instrNameDecTB(
|
||||
10'b1000111_???: name = "FMSUB";
|
||||
10'b1001011_???: name = "FNMSUB";
|
||||
10'b1001111_???: name = "FNMADD";
|
||||
10'b1010011_000: if (funct7[6:2] == 5'b00000) name = "FADD";
|
||||
else if (funct7[6:2] == 5'b00001) name = "FSUB";
|
||||
else if (funct7[6:2] == 5'b00010) name = "FMUL";
|
||||
else if (funct7[6:2] == 5'b00011) name = "FDIV";
|
||||
else if (funct7[6:2] == 5'b01011) name = "FSQRT";
|
||||
else if (funct7 == 7'b1100000 & rs2 == 5'b00000) name = "FCVT.W.S";
|
||||
else if (funct7 == 7'b1100000 & rs2 == 5'b00001) name = "FCVT.WU.S";
|
||||
else if (funct7 == 7'b1100000 & rs2 == 5'b00010) name = "FCVT.L.S";
|
||||
else if (funct7 == 7'b1100000 & rs2 == 5'b00011) name = "FCVT.LU.S";
|
||||
else if (funct7 == 7'b1101000 & rs2 == 5'b00000) name = "FCVT.S.W";
|
||||
else if (funct7 == 7'b1101000 & rs2 == 5'b00001) name = "FCVT.S.WU";
|
||||
else if (funct7 == 7'b1101000 & rs2 == 5'b00010) name = "FCVT.S.L";
|
||||
else if (funct7 == 7'b1101000 & rs2 == 5'b00011) name = "FCVT.S.LU";
|
||||
else if (funct7 == 7'b1100001 & rs2 == 5'b00000) name = "FCVT.W.D";
|
||||
else if (funct7 == 7'b1100001 & rs2 == 5'b00001) name = "FCVT.WU.D";
|
||||
else if (funct7 == 7'b1100001 & rs2 == 5'b00010) name = "FCVT.L.D";
|
||||
else if (funct7 == 7'b1100001 & rs2 == 5'b00011) name = "FCVT.LU.D";
|
||||
else if (funct7 == 7'b1101001 & rs2 == 5'b00000) name = "FCVT.D.W";
|
||||
else if (funct7 == 7'b1101001 & rs2 == 5'b00001) name = "FCVT.D.WU";
|
||||
else if (funct7 == 7'b1101001 & rs2 == 5'b00010) name = "FCVT.D.L";
|
||||
else if (funct7 == 7'b1101001 & rs2 == 5'b00011) name = "FCVT.D.LU";
|
||||
else if (funct7 == 7'b0100000 & rs2 == 5'b00001) name = "FCVT.S.D";
|
||||
else if (funct7 == 7'b0100001 & rs2 == 5'b00000) name = "FCVT.D.S";
|
||||
else if (funct7 == 7'b1110000 & rs2 == 5'b00000) name = "FMV.X.W";
|
||||
else if (funct7 == 7'b1111000 & rs2 == 5'b00000) name = "FMV.W.X";
|
||||
else if (funct7 == 7'b1110001 & rs2 == 5'b00000) name = "FMV.X.D"; // DOUBLE
|
||||
else if (funct7 == 7'b1111001 & rs2 == 5'b00000) name = "FMV.D.X"; // DOUBLE
|
||||
else if (funct7[6:2] == 5'b00100) name = "FSGNJ";
|
||||
else if (funct7[6:2] == 5'b00101) name = "FMIN";
|
||||
else if (funct7[6:2] == 5'b10100) name = "FLE";
|
||||
else name = "ILLEGAL";
|
||||
10'b1010011_001: if (funct7[6:2] == 5'b00000) name = "FADD";
|
||||
else if (funct7[6:2] == 5'b00001) name = "FSUB";
|
||||
else if (funct7[6:2] == 5'b00010) name = "FMUL";
|
||||
else if (funct7[6:2] == 5'b00011) name = "FDIV";
|
||||
else if (funct7[6:2] == 5'b01011) name = "FSQRT";
|
||||
else if (funct7 == 7'b1100000 & rs2 == 5'b00000) name = "FCVT.W.S";
|
||||
else if (funct7 == 7'b1100000 & rs2 == 5'b00001) name = "FCVT.WU.S";
|
||||
else if (funct7 == 7'b1100000 & rs2 == 5'b00010) name = "FCVT.L.S";
|
||||
else if (funct7 == 7'b1100000 & rs2 == 5'b00011) name = "FCVT.LU.S";
|
||||
else if (funct7 == 7'b1101000 & rs2 == 5'b00000) name = "FCVT.S.W";
|
||||
else if (funct7 == 7'b1101000 & rs2 == 5'b00001) name = "FCVT.S.WU";
|
||||
else if (funct7 == 7'b1101000 & rs2 == 5'b00010) name = "FCVT.S.L";
|
||||
else if (funct7 == 7'b1101000 & rs2 == 5'b00011) name = "FCVT.S.LU";
|
||||
else if (funct7 == 7'b1100001 & rs2 == 5'b00000) name = "FCVT.W.D";
|
||||
else if (funct7 == 7'b1100001 & rs2 == 5'b00001) name = "FCVT.WU.D";
|
||||
else if (funct7 == 7'b1100001 & rs2 == 5'b00010) name = "FCVT.L.D";
|
||||
else if (funct7 == 7'b1100001 & rs2 == 5'b00011) name = "FCVT.LU.D";
|
||||
else if (funct7 == 7'b1101001 & rs2 == 5'b00000) name = "FCVT.D.W";
|
||||
else if (funct7 == 7'b1101001 & rs2 == 5'b00001) name = "FCVT.D.WU";
|
||||
else if (funct7 == 7'b1101001 & rs2 == 5'b00010) name = "FCVT.D.L";
|
||||
else if (funct7 == 7'b1101001 & rs2 == 5'b00011) name = "FCVT.D.LU";
|
||||
else if (funct7 == 7'b0100000 & rs2 == 5'b00001) name = "FCVT.S.D";
|
||||
else if (funct7 == 7'b0100001 & rs2 == 5'b00000) name = "FCVT.D.S";
|
||||
else if (funct7[6:2] == 5'b00100) name = "FSGNJN";
|
||||
else if (funct7[6:2] == 5'b00101) name = "FMAX";
|
||||
else if (funct7[6:2] == 5'b10100) name = "FLT";
|
||||
else if (funct7[6:2] == 5'b11100) name = "FCLASS";
|
||||
else name = "ILLEGAL";
|
||||
10'b1010011_010: if (funct7[6:2] == 5'b00000) name = "FADD";
|
||||
else if (funct7[6:2] == 5'b00001) name = "FSUB";
|
||||
else if (funct7[6:2] == 5'b00010) name = "FMUL";
|
||||
else if (funct7[6:2] == 5'b00011) name = "FDIV";
|
||||
else if (funct7[6:2] == 5'b01011) name = "FSQRT";
|
||||
else if (funct7 == 7'b1100000 & rs2 == 5'b00000) name = "FCVT.W.S";
|
||||
else if (funct7 == 7'b1100000 & rs2 == 5'b00001) name = "FCVT.WU.S";
|
||||
else if (funct7 == 7'b1100000 & rs2 == 5'b00010) name = "FCVT.L.S";
|
||||
else if (funct7 == 7'b1100000 & rs2 == 5'b00011) name = "FCVT.LU.S";
|
||||
else if (funct7 == 7'b1101000 & rs2 == 5'b00000) name = "FCVT.S.W";
|
||||
else if (funct7 == 7'b1101000 & rs2 == 5'b00001) name = "FCVT.S.WU";
|
||||
else if (funct7 == 7'b1101000 & rs2 == 5'b00010) name = "FCVT.S.L";
|
||||
else if (funct7 == 7'b1101000 & rs2 == 5'b00011) name = "FCVT.S.LU";
|
||||
else if (funct7 == 7'b1100001 & rs2 == 5'b00000) name = "FCVT.W.D";
|
||||
else if (funct7 == 7'b1100001 & rs2 == 5'b00001) name = "FCVT.WU.D";
|
||||
else if (funct7 == 7'b1100001 & rs2 == 5'b00010) name = "FCVT.L.D";
|
||||
else if (funct7 == 7'b1100001 & rs2 == 5'b00011) name = "FCVT.LU.D";
|
||||
else if (funct7 == 7'b1101001 & rs2 == 5'b00000) name = "FCVT.D.W";
|
||||
else if (funct7 == 7'b1101001 & rs2 == 5'b00001) name = "FCVT.D.WU";
|
||||
else if (funct7 == 7'b1101001 & rs2 == 5'b00010) name = "FCVT.D.L";
|
||||
else if (funct7 == 7'b1101001 & rs2 == 5'b00011) name = "FCVT.D.LU";
|
||||
else if (funct7 == 7'b0100000 & rs2 == 5'b00001) name = "FCVT.S.D";
|
||||
else if (funct7 == 7'b0100001 & rs2 == 5'b00000) name = "FCVT.D.S";
|
||||
else if (funct7[6:2] == 5'b00100) name = "FSGNJX";
|
||||
else if (funct7[6:2] == 5'b10100) name = "FEQ";
|
||||
else name = "ILLEGAL";
|
||||
/* verilator lint_off CASEOVERLAP */
|
||||
// *** RT: definitely take a look at this. This overlaps with 10'b1010011_000
|
||||
10'b1010011_???: if (funct7[6:2] == 5'b00000) name = "FADD";
|
||||
/* verilator lint_on CASEOVERLAP */
|
||||
else if (funct7[6:2] == 5'b00001) name = "FSUB";
|
||||
else if (funct7[6:2] == 5'b00010) name = "FMUL";
|
||||
else if (funct7[6:2] == 5'b00011) name = "FDIV";
|
||||
@ -343,6 +255,61 @@ module instrNameDecTB(
|
||||
else if (funct7 == 7'b1101001 & rs2 == 5'b00011) name = "FCVT.D.LU";
|
||||
else if (funct7 == 7'b0100000 & rs2 == 5'b00001) name = "FCVT.S.D";
|
||||
else if (funct7 == 7'b0100001 & rs2 == 5'b00000) name = "FCVT.D.S";
|
||||
else if (funct7 == 7'b1100010 & rs2 == 5'b00000) name = "FCVT.W.H";
|
||||
else if (funct7 == 7'b1100010 & rs2 == 5'b00001) name = "FCVT.WU.H";
|
||||
else if (funct7 == 7'b1100010 & rs2 == 5'b00010) name = "FCVT.L.H";
|
||||
else if (funct7 == 7'b1100010 & rs2 == 5'b00011) name = "FCVT.LU.H";
|
||||
else if (funct7 == 7'b1101010 & rs2 == 5'b00000) name = "FCVT.H.W";
|
||||
else if (funct7 == 7'b1101010 & rs2 == 5'b00001) name = "FCVT.H.WU";
|
||||
else if (funct7 == 7'b1101010 & rs2 == 5'b00010) name = "FCVT.H.L";
|
||||
else if (funct7 == 7'b1101010 & rs2 == 5'b00011) name = "FCVT.H.LU";
|
||||
else if (funct7 == 7'b1100011 & rs2 == 5'b00000) name = "FCVT.W.Q";
|
||||
else if (funct7 == 7'b1100011 & rs2 == 5'b00001) name = "FCVT.WU.Q";
|
||||
else if (funct7 == 7'b1100011 & rs2 == 5'b00010) name = "FCVT.L.Q";
|
||||
else if (funct7 == 7'b1100011 & rs2 == 5'b00011) name = "FCVT.LU.Q";
|
||||
else if (funct7 == 7'b1101011 & rs2 == 5'b00000) name = "FCVT.Q.W";
|
||||
else if (funct7 == 7'b1101011 & rs2 == 5'b00001) name = "FCVT.Q.WU";
|
||||
else if (funct7 == 7'b1101011 & rs2 == 5'b00010) name = "FCVT.Q.L";
|
||||
else if (funct7 == 7'b1101011 & rs2 == 5'b00011) name = "FCVT.Q.LU";
|
||||
else if (funct7 == 7'b0100000 & rs2 == 5'b00001) name = "FCVT.S.D";
|
||||
else if (funct7 == 7'b0100000 & rs2 == 5'b00010) name = "FCVT.S.H";
|
||||
else if (funct7 == 7'b0100000 & rs2 == 5'b00011) name = "FCVT.S.Q";
|
||||
else if (funct7 == 7'b0100001 & rs2 == 5'b00000) name = "FCVT.D.S";
|
||||
else if (funct7 == 7'b0100001 & rs2 == 5'b00010) name = "FCVT.D.H";
|
||||
else if (funct7 == 7'b0100001 & rs2 == 5'b00011) name = "FCVT.D.Q";
|
||||
else if (funct7 == 7'b0100010 & rs2 == 5'b00000) name = "FCVT.H.S";
|
||||
else if (funct7 == 7'b0100010 & rs2 == 5'b00001) name = "FCVT.H.D";
|
||||
else if (funct7 == 7'b0100010 & rs2 == 5'b00011) name = "FCVT.H.Q";
|
||||
else if (funct7 == 7'b0100011 & rs2 == 5'b00000) name = "FCVT.Q.S";
|
||||
else if (funct7 == 7'b0100011 & rs2 == 5'b00001) name = "FCVT.Q.D";
|
||||
else if (funct7 == 7'b0100011 & rs2 == 5'b00010) name = "FCVT.Q.H";
|
||||
else if (funct7 == 7'b1110000 & rs2 == 5'b00000 & funct3 == 3'b000) name = "FMV.X.W";
|
||||
else if (funct7 == 7'b1111000 & rs2 == 5'b00000 & funct3 == 3'b000) name = "FMV.W.X";
|
||||
else if (funct7 == 7'b1110001 & rs2 == 5'b00000 & funct3 == 3'b000) name = "FMV.X.D";
|
||||
else if (funct7 == 7'b1111001 & rs2 == 5'b00000 & funct3 == 3'b000) name = "FMV.D.X";
|
||||
else if (funct7 == 7'b1110010 & rs2 == 5'b00000 & funct3 == 3'b000) name = "FMV.X.H";
|
||||
else if (funct7 == 7'b1111010 & rs2 == 5'b00000 & funct3 == 3'b000) name = "FMV.H.X";
|
||||
else if (funct7[6:2] == 5'b00100 & funct3 == 3'b000) name = "FSGNJ";
|
||||
else if (funct7[6:2] == 5'b00101 & funct3 == 3'b000) name = "FMIN";
|
||||
else if (funct7[6:2] == 5'b10100 & funct3 == 3'b000) name = "FLE";
|
||||
else if (funct7[6:2] == 5'b00100 & funct3 == 3'b001) name = "FSGNJN";
|
||||
else if (funct7[6:2] == 5'b00101 & funct3 == 3'b001) name = "FMAX";
|
||||
else if (funct7[6:2] == 5'b10100 & funct3 == 3'b001) name = "FLT";
|
||||
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'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";
|
||||
10'b0000111_010: name = "FLW";
|
||||
10'b0100111_010: name = "FSW";
|
||||
|
@ -882,7 +882,7 @@ module testbenchfp;
|
||||
// - the sign of the NaN does not matter for the opperations being tested
|
||||
// - when 2 or more NaNs are inputed the NaN that is propigated doesn't matter
|
||||
if (UnitVal !== `CVTFPUNIT & UnitVal !== `CVTINTUNIT)
|
||||
case (FmtVal)
|
||||
case (FmtVal)
|
||||
2'b11: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res === {1'b0, {P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) |
|
||||
(AnsFlg[4]&(Res[P.Q_LEN-2:0] === {{P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) |
|
||||
(XNaN&(Res[P.Q_LEN-2:0] === {X[P.Q_LEN-2:P.Q_NF],1'b1,X[P.Q_NF-2:0]})) |
|
||||
@ -903,9 +903,9 @@ module testbenchfp;
|
||||
(XNaN&(Res[P.H_LEN-2:0] === {X[P.H_LEN-2:P.H_NF],1'b1,X[P.H_NF-2:0]})) |
|
||||
(YNaN&(Res[P.H_LEN-2:0] === {Y[P.H_LEN-2:P.H_NF],1'b1,Y[P.H_NF-2:0]})) |
|
||||
(ZNaN&(Res[P.H_LEN-2:0] === {Z[P.H_LEN-2:P.H_NF],1'b1,Z[P.H_NF-2:0]})));
|
||||
endcase
|
||||
else if (UnitVal === `CVTFPUNIT) // if converting from floating point to floating point OpCtrl contains the final FP format
|
||||
case (OpCtrlVal[1:0])
|
||||
endcase
|
||||
else if (UnitVal === `CVTFPUNIT) // if converting from floating point to floating point OpCtrl contains the final FP format
|
||||
case (OpCtrlVal[1:0])
|
||||
2'b11: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res === {1'b0, {P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) |
|
||||
(AnsFlg[4]&(Res[P.Q_LEN-2:0] === {{P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) |
|
||||
(AnsNaN&(Res[P.Q_LEN-2:0] === Ans[P.Q_LEN-2:0])) |
|
||||
@ -926,72 +926,70 @@ module testbenchfp;
|
||||
(AnsNaN&(Res[P.H_LEN-2:0] === Ans[P.H_LEN-2:0])) |
|
||||
(XNaN&(Res[P.H_LEN-2:0] === {X[P.H_LEN-2:P.H_NF],1'b1,X[P.H_NF-2:0]})) |
|
||||
(YNaN&(Res[P.H_LEN-2:0] === {Y[P.H_LEN-2:P.H_NF],1'b1,Y[P.H_NF-2:0]})));
|
||||
endcase
|
||||
else NaNGood = 1'b0; // integers can't be NaNs
|
||||
endcase
|
||||
else NaNGood = 1'b0; // integers can't be NaNs
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ||||||| ||| ||| ||||||| ||||||| ||| |||
|
||||
// ||| ||| ||| ||| ||| ||| |||
|
||||
// ||| |||||||||| ||||||| ||| ||||||
|
||||
// ||| ||| ||| ||| ||| ||| |||
|
||||
// ||||||| ||| ||| ||||||| ||||||| ||| |||
|
||||
// ||||||| ||| ||| ||||||| ||||||| ||| |||
|
||||
// ||| ||| ||| ||| ||| ||| |||
|
||||
// ||| |||||||||| ||||||| ||| ||||||
|
||||
// ||| ||| ||| ||| ||| ||| |||
|
||||
// ||||||| ||| ||| ||||||| ||||||| ||| |||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// check if result is correct
|
||||
// wait till the division result is done or one extra cylcle for early termination (to simulate the EM pipline stage)
|
||||
assign ResMatch = ((Res === Ans) | NaNGood | (NaNGood === 1'bx));
|
||||
assign FlagMatch = ((ResFlg === AnsFlg) | (AnsFlg === 5'bx));
|
||||
assign divsqrtop = (OpCtrlVal == `SQRT_OPCTRL) | (OpCtrlVal == `DIV_OPCTRL);
|
||||
assign FMAop = (OpCtrlVal == `FMAUNIT);
|
||||
assign DivDone = OldFDivBusyE & ~FDivBusyE;
|
||||
// check if result is correct
|
||||
// wait till the division result is done or one extra cylcle for early termination (to simulate the EM pipline stage)
|
||||
assign ResMatch = ((Res === Ans) | NaNGood | (NaNGood === 1'bx));
|
||||
assign FlagMatch = ((ResFlg === AnsFlg) | (AnsFlg === 5'bx));
|
||||
assign divsqrtop = (OpCtrlVal == `SQRT_OPCTRL) | (OpCtrlVal == `DIV_OPCTRL);
|
||||
assign FMAop = (OpCtrlVal == `FMAUNIT);
|
||||
assign DivDone = OldFDivBusyE & ~FDivBusyE;
|
||||
|
||||
// Maybe change OpCtrl but for now just look at TEST for fma test
|
||||
assign CheckNow = ((DivDone | ~divsqrtop) | (TEST == "add" | TEST == "fma" | TEST == "sub")) & (UnitVal !== `CVTINTUNIT) & (UnitVal !== `CMPUNIT);
|
||||
if (~(ResMatch & FlagMatch) & CheckNow) begin
|
||||
// Maybe change OpCtrl but for now just look at TEST for fma test
|
||||
assign CheckNow = ((DivDone | ~divsqrtop) | (TEST == "add" | TEST == "fma" | TEST == "sub")) & (UnitVal !== `CVTINTUNIT) & (UnitVal !== `CMPUNIT);
|
||||
if (~(ResMatch & FlagMatch) & CheckNow) begin
|
||||
errors += 1;
|
||||
$display("\nError in %s", Tests[TestNum]);
|
||||
$display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]);
|
||||
$display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Expected: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg);
|
||||
$stop;
|
||||
end else if (((UnitVal === `CVTINTUNIT) | (UnitVal === `CMPUNIT)) &
|
||||
~(ResMatch & FlagMatch) & (Ans[0] !== 1'bx)) begin // Check for conversion and comparisons
|
||||
errors += 1;
|
||||
$display("\nError in %s", Tests[TestNum]);
|
||||
$display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]);
|
||||
$display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Expected: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg);
|
||||
$display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]);
|
||||
$display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Ans: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg);
|
||||
$stop;
|
||||
end else if (((UnitVal === `CVTINTUNIT) | (UnitVal === `CMPUNIT)) &
|
||||
~(ResMatch & FlagMatch) & (Ans[0] !== 1'bx)) begin // Check for conversion and comparisons
|
||||
errors += 1;
|
||||
$display("\nError in %s", Tests[TestNum]);
|
||||
$display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]);
|
||||
$display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Ans: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
|
||||
if (TestVectors[VectorNum][0] === 1'bx & Tests[TestNum] !== "") begin // if reached the eof
|
||||
// increment the test
|
||||
TestNum += 1;
|
||||
// clear the vectors
|
||||
for(int i=0; i<6133248; i++) TestVectors[i] = {P.FLEN*4+8{1'bx}};
|
||||
// read next files
|
||||
$readmemh({`PATH, Tests[TestNum]}, TestVectors);
|
||||
// set the vector index back to 0
|
||||
VectorNum = 0;
|
||||
// incemet the operation if all the rounding modes have been tested
|
||||
if (FrmNum === 4) OpCtrlNum += 1;
|
||||
// increment the rounding mode or loop back to rne
|
||||
if (FrmNum < 4)
|
||||
FrmNum += 1;
|
||||
else begin
|
||||
FrmNum = 0;
|
||||
// Add some time as a buffer between tests at the end of each test
|
||||
repeat (10)
|
||||
@(posedge clk);
|
||||
end
|
||||
// if no more Tests - finish
|
||||
if (Tests[TestNum] === "") begin
|
||||
$display("\nAll Tests completed with %d errors\n", errors);
|
||||
$stop;
|
||||
end
|
||||
$display("Running %s vectors", Tests[TestNum]);
|
||||
// increment the test
|
||||
TestNum += 1;
|
||||
// clear the vectors
|
||||
for(int i=0; i<6133248; i++) TestVectors[i] = {P.FLEN*4+8{1'bx}};
|
||||
// read next files
|
||||
$readmemh({`PATH, Tests[TestNum]}, TestVectors);
|
||||
// set the vector index back to 0
|
||||
VectorNum = 0;
|
||||
// incemet the operation if all the rounding modes have been tested
|
||||
if (FrmNum === 4) OpCtrlNum += 1;
|
||||
// increment the rounding mode or loop back to rne
|
||||
if (FrmNum < 4) FrmNum += 1;
|
||||
else begin
|
||||
FrmNum = 0;
|
||||
// Add some time as a buffer between tests at the end of each test
|
||||
repeat (10)
|
||||
@(posedge clk);
|
||||
end
|
||||
// if no more Tests - finish
|
||||
if (Tests[TestNum] === "") begin
|
||||
$display("\nAll Tests completed with %d errors\n", errors);
|
||||
$stop;
|
||||
end
|
||||
$display("Running %s vectors", Tests[TestNum]);
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
@ -127,6 +127,9 @@ module testbench;
|
||||
"arch64zbs": if (P.ZBS_SUPPORTED) tests = arch64zbs;
|
||||
"arch64zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch64zicboz;
|
||||
"arch64zcb": if (P.ZCB_SUPPORTED) tests = arch64zcb;
|
||||
"arch64zfh": if (P.ZFH_SUPPORTED) tests = arch64zfh;
|
||||
"arch64zfaf": if (P.ZFA_SUPPORTED) tests = arch64zfaf;
|
||||
"arch64zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch64zfad;
|
||||
endcase
|
||||
end else begin // RV32
|
||||
case (TEST)
|
||||
@ -161,6 +164,9 @@ module testbench;
|
||||
"arch32zbs": if (P.ZBS_SUPPORTED) tests = arch32zbs;
|
||||
"arch32zicboz": if (P.ZICBOZ_SUPPORTED) tests = arch32zicboz;
|
||||
"arch32zcb": if (P.ZCB_SUPPORTED) tests = arch32zcb;
|
||||
"arch32zfh": if (P.ZFH_SUPPORTED) tests = arch32zfh;
|
||||
"arch32zfaf": if (P.ZFA_SUPPORTED) tests = arch32zfaf;
|
||||
"arch32zfad": if (P.ZFA_SUPPORTED & P.D_SUPPORTED) tests = arch32zfad;
|
||||
endcase
|
||||
end
|
||||
if (tests.size() == 0) begin
|
||||
@ -626,8 +632,8 @@ task automatic updateProgramAddrLabelArray;
|
||||
end
|
||||
end
|
||||
|
||||
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["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);
|
||||
|
||||
$fclose(ProgramLabelMapFP);
|
||||
$fclose(ProgramAddrMapFP);
|
||||
|
@ -1291,6 +1291,123 @@ string imperas32f[] = '{
|
||||
"rv64i_m/F/src/fsw-align-01.S"
|
||||
};
|
||||
|
||||
string arch64zfh[] = '{
|
||||
`RISCVARCHTEST,
|
||||
"rv64i_m/Zfh/src/fadd_b10-01.S",
|
||||
"rv64i_m/Zfh/src/fadd_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fadd_b11-01.S",
|
||||
"rv64i_m/Zfh/src/fadd_b12-01.S",
|
||||
"rv64i_m/Zfh/src/fadd_b13-01.S",
|
||||
"rv64i_m/Zfh/src/fadd_b2-01.S",
|
||||
"rv64i_m/Zfh/src/fadd_b3-01.S",
|
||||
"rv64i_m/Zfh/src/fadd_b4-01.S",
|
||||
"rv64i_m/Zfh/src/fadd_b5-01.S",
|
||||
"rv64i_m/Zfh/src/fadd_b7-01.S",
|
||||
"rv64i_m/Zfh/src/fadd_b8-01.S",
|
||||
"rv64i_m/Zfh/src/fclass_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.h.w_b25-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.h.w_b26-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.h.wu_b25-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.h.wu_b26-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.w.h_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.w.h_b22-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.w.h_b23-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.w.h_b24-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.w.h_b27-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.w.h_b28-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.w.h_b29-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.wu.h_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.wu.h_b22-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.wu.h_b23-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.wu.h_b24-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.wu.h_b27-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.wu.h_b28-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.wu.h_b29-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.h.l_b25-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.h.l_b26-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.h.lu_b25-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.h.lu_b26-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.l.h_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.l.h_b22-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.l.h_b23-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.l.h_b24-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.l.h_b27-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.l.h_b28-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.l.h_b29-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.lu.h_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.lu.h_b22-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.lu.h_b23-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.lu.h_b24-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.lu.h_b27-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.lu.h_b28-01.S",
|
||||
"rv64i_m/Zfh/src/fcvt.lu.h_b29-01.S",
|
||||
"rv64i_m/Zfh/src/fdiv_b20-01.S",
|
||||
"rv64i_m/Zfh/src/fdiv_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fdiv_b2-01.S",
|
||||
"rv64i_m/Zfh/src/fdiv_b21-01.S",
|
||||
"rv64i_m/Zfh/src/fdiv_b3-01.S",
|
||||
"rv64i_m/Zfh/src/fdiv_b4-01.S",
|
||||
"rv64i_m/Zfh/src/fdiv_b5-01.S",
|
||||
"rv64i_m/Zfh/src/fdiv_b6-01.S",
|
||||
"rv64i_m/Zfh/src/fdiv_b7-01.S",
|
||||
"rv64i_m/Zfh/src/fdiv_b8-01.S",
|
||||
"rv64i_m/Zfh/src/fdiv_b9-01.S",
|
||||
"rv64i_m/Zfh/src/feq_b1-01.S",
|
||||
"rv64i_m/Zfh/src/feq_b19-01.S",
|
||||
"rv64i_m/Zfh/src/fle_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fle_b19-01.S",
|
||||
"rv64i_m/Zfh/src/flt_b1-01.S",
|
||||
"rv64i_m/Zfh/src/flt_b19-01.S",
|
||||
"rv64i_m/Zfh/src/flh-align-01.S",
|
||||
"rv64i_m/Zfh/src/fmax_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fmax_b19-01.S",
|
||||
"rv64i_m/Zfh/src/fmin_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fmin_b19-01.S",
|
||||
"rv64i_m/Zfh/src/fmul_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fmul_b2-01.S",
|
||||
"rv64i_m/Zfh/src/fmul_b3-01.S",
|
||||
"rv64i_m/Zfh/src/fmul_b4-01.S",
|
||||
"rv64i_m/Zfh/src/fmul_b5-01.S",
|
||||
"rv64i_m/Zfh/src/fmul_b6-01.S",
|
||||
"rv64i_m/Zfh/src/fmul_b7-01.S",
|
||||
"rv64i_m/Zfh/src/fmul_b8-01.S",
|
||||
"rv64i_m/Zfh/src/fmul_b9-01.S",
|
||||
"rv64i_m/Zfh/src/fmv.h.x_b25-01.S",
|
||||
"rv64i_m/Zfh/src/fmv.h.x_b26-01.S",
|
||||
"rv64i_m/Zfh/src/fmv.x.h_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fmv.x.h_b22-01.S",
|
||||
"rv64i_m/Zfh/src/fmv.x.h_b23-01.S",
|
||||
"rv64i_m/Zfh/src/fmv.x.h_b24-01.S",
|
||||
"rv64i_m/Zfh/src/fmv.x.h_b27-01.S",
|
||||
"rv64i_m/Zfh/src/fmv.x.h_b28-01.S",
|
||||
"rv64i_m/Zfh/src/fmv.x.h_b29-01.S",
|
||||
"rv64i_m/Zfh/src/fsgnj_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fsgnjn_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fsgnjx_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fsqrt_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fsqrt_b20-01.S",
|
||||
"rv64i_m/Zfh/src/fsqrt_b2-01.S",
|
||||
"rv64i_m/Zfh/src/fsqrt_b3-01.S",
|
||||
"rv64i_m/Zfh/src/fsqrt_b4-01.S",
|
||||
"rv64i_m/Zfh/src/fsqrt_b5-01.S",
|
||||
"rv64i_m/Zfh/src/fsqrt_b7-01.S",
|
||||
"rv64i_m/Zfh/src/fsqrt_b8-01.S",
|
||||
"rv64i_m/Zfh/src/fsqrt_b9-01.S",
|
||||
"rv64i_m/Zfh/src/fsub_b10-01.S",
|
||||
"rv64i_m/Zfh/src/fsub_b1-01.S",
|
||||
"rv64i_m/Zfh/src/fsub_b11-01.S",
|
||||
"rv64i_m/Zfh/src/fsub_b12-01.S",
|
||||
"rv64i_m/Zfh/src/fsub_b13-01.S",
|
||||
"rv64i_m/Zfh/src/fsub_b2-01.S",
|
||||
"rv64i_m/Zfh/src/fsub_b3-01.S",
|
||||
"rv64i_m/Zfh/src/fsub_b4-01.S",
|
||||
"rv64i_m/Zfh/src/fsub_b5-01.S",
|
||||
"rv64i_m/Zfh/src/fsub_b7-01.S",
|
||||
"rv64i_m/Zfh/src/fsub_b8-01.S",
|
||||
"rv64i_m/Zfh/src/fsh-align-01.S"
|
||||
};
|
||||
|
||||
|
||||
string arch64d_fma[] = '{
|
||||
`RISCVARCHTEST,
|
||||
//"rv64i_m/D/src/fmadd.d_b15-01.S",
|
||||
@ -1638,7 +1755,6 @@ string arch64zbs[] = '{
|
||||
|
||||
string arch32f[] = '{
|
||||
`RISCVARCHTEST,
|
||||
"rv32i_m/F/src/fdiv_b20-01.S",
|
||||
"rv32i_m/F/src/fadd_b10-01.S",
|
||||
"rv32i_m/F/src/fadd_b1-01.S",
|
||||
"rv32i_m/F/src/fadd_b11-01.S",
|
||||
@ -1783,6 +1899,184 @@ string arch64zbs[] = '{
|
||||
"rv32i_m/F/src/fsw-align-01.S"
|
||||
};
|
||||
|
||||
string arch32zfh[] = '{
|
||||
`RISCVARCHTEST,
|
||||
"rv32i_m/Zfh/src/fadd_b10-01.S",
|
||||
"rv32i_m/Zfh/src/fadd_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fadd_b11-01.S",
|
||||
"rv32i_m/Zfh/src/fadd_b12-01.S",
|
||||
"rv32i_m/Zfh/src/fadd_b13-01.S",
|
||||
"rv32i_m/Zfh/src/fadd_b2-01.S",
|
||||
"rv32i_m/Zfh/src/fadd_b3-01.S",
|
||||
"rv32i_m/Zfh/src/fadd_b4-01.S",
|
||||
"rv32i_m/Zfh/src/fadd_b5-01.S",
|
||||
"rv32i_m/Zfh/src/fadd_b7-01.S",
|
||||
"rv32i_m/Zfh/src/fadd_b8-01.S",
|
||||
"rv32i_m/Zfh/src/fclass_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.h.w_b25-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.h.w_b26-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.h.wu_b25-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.h.wu_b26-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.w.h_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.w.h_b22-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.w.h_b23-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.w.h_b24-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.w.h_b27-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.w.h_b28-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.w.h_b29-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.wu.h_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.wu.h_b22-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.wu.h_b23-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.wu.h_b24-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.wu.h_b27-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.wu.h_b28-01.S",
|
||||
"rv32i_m/Zfh/src/fcvt.wu.h_b29-01.S",
|
||||
"rv32i_m/Zfh/src/fdiv_b20-01.S",
|
||||
"rv32i_m/Zfh/src/fdiv_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fdiv_b2-01.S",
|
||||
"rv32i_m/Zfh/src/fdiv_b21-01.S",
|
||||
"rv32i_m/Zfh/src/fdiv_b3-01.S",
|
||||
"rv32i_m/Zfh/src/fdiv_b4-01.S",
|
||||
"rv32i_m/Zfh/src/fdiv_b5-01.S",
|
||||
"rv32i_m/Zfh/src/fdiv_b6-01.S",
|
||||
"rv32i_m/Zfh/src/fdiv_b7-01.S",
|
||||
"rv32i_m/Zfh/src/fdiv_b8-01.S",
|
||||
"rv32i_m/Zfh/src/fdiv_b9-01.S",
|
||||
"rv32i_m/Zfh/src/feq_b1-01.S",
|
||||
"rv32i_m/Zfh/src/feq_b19-01.S",
|
||||
"rv32i_m/Zfh/src/fle_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fle_b19-01.S",
|
||||
"rv32i_m/Zfh/src/flt_b1-01.S",
|
||||
"rv32i_m/Zfh/src/flt_b19-01.S",
|
||||
"rv32i_m/Zfh/src/flh-align-01.S",
|
||||
"rv32i_m/Zfh/src/fmax_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fmax_b19-01.S",
|
||||
"rv32i_m/Zfh/src/fmin_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fmin_b19-01.S",
|
||||
"rv32i_m/Zfh/src/fmul_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fmul_b2-01.S",
|
||||
"rv32i_m/Zfh/src/fmul_b3-01.S",
|
||||
"rv32i_m/Zfh/src/fmul_b4-01.S",
|
||||
"rv32i_m/Zfh/src/fmul_b5-01.S",
|
||||
"rv32i_m/Zfh/src/fmul_b6-01.S",
|
||||
"rv32i_m/Zfh/src/fmul_b7-01.S",
|
||||
"rv32i_m/Zfh/src/fmul_b8-01.S",
|
||||
"rv32i_m/Zfh/src/fmul_b9-01.S",
|
||||
"rv32i_m/Zfh/src/fmv.h.x_b25-01.S",
|
||||
"rv32i_m/Zfh/src/fmv.h.x_b26-01.S",
|
||||
"rv32i_m/Zfh/src/fmv.x.h_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fmv.x.h_b22-01.S",
|
||||
"rv32i_m/Zfh/src/fmv.x.h_b23-01.S",
|
||||
"rv32i_m/Zfh/src/fmv.x.h_b24-01.S",
|
||||
"rv32i_m/Zfh/src/fmv.x.h_b27-01.S",
|
||||
"rv32i_m/Zfh/src/fmv.x.h_b28-01.S",
|
||||
"rv32i_m/Zfh/src/fmv.x.h_b29-01.S",
|
||||
"rv32i_m/Zfh/src/fsgnj_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fsgnjn_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fsgnjx_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fsqrt_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fsqrt_b20-01.S",
|
||||
"rv32i_m/Zfh/src/fsqrt_b2-01.S",
|
||||
"rv32i_m/Zfh/src/fsqrt_b3-01.S",
|
||||
"rv32i_m/Zfh/src/fsqrt_b4-01.S",
|
||||
"rv32i_m/Zfh/src/fsqrt_b5-01.S",
|
||||
"rv32i_m/Zfh/src/fsqrt_b7-01.S",
|
||||
"rv32i_m/Zfh/src/fsqrt_b8-01.S",
|
||||
"rv32i_m/Zfh/src/fsqrt_b9-01.S",
|
||||
"rv32i_m/Zfh/src/fsub_b10-01.S",
|
||||
"rv32i_m/Zfh/src/fsub_b1-01.S",
|
||||
"rv32i_m/Zfh/src/fsub_b11-01.S",
|
||||
"rv32i_m/Zfh/src/fsub_b12-01.S",
|
||||
"rv32i_m/Zfh/src/fsub_b13-01.S",
|
||||
"rv32i_m/Zfh/src/fsub_b2-01.S",
|
||||
"rv32i_m/Zfh/src/fsub_b3-01.S",
|
||||
"rv32i_m/Zfh/src/fsub_b4-01.S",
|
||||
"rv32i_m/Zfh/src/fsub_b5-01.S",
|
||||
"rv32i_m/Zfh/src/fsub_b7-01.S",
|
||||
"rv32i_m/Zfh/src/fsub_b8-01.S",
|
||||
"rv32i_m/Zfh/src/fsh-align-01.S"
|
||||
};
|
||||
|
||||
string arch32zfaf[] = '{
|
||||
`RISCVARCHTEST,
|
||||
"rv32i_m/F_Zfa/src/fleq_b1-01.S",
|
||||
"rv32i_m/F_Zfa/src/fleq_b19-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_b19-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/D_Zfa/src/fltq_b19-01.S",
|
||||
"rv32i_m/F_Zfa/src/fminm_b1-01.S",
|
||||
"rv32i_m/F_Zfa/src/fminm_b19-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[] = '{
|
||||
`RISCVARCHTEST,
|
||||
//"rv32i_m/D/src/fmadd.d_b15-01.S",
|
||||
|
@ -37,4 +37,31 @@ main:
|
||||
csrrw t1, menvcfg, 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
|
||||
|
@ -297,7 +297,32 @@ sretdone:
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
@ -115,6 +115,10 @@ class spike(pluginTemplate):
|
||||
self.isa += '_Zicond'
|
||||
if "Zicboz" in ispec["ISA"]:
|
||||
self.isa += '_Zicboz'
|
||||
if "Zfa" in ispec["ISA"]:
|
||||
self.isa += '_Zfa'
|
||||
if "Zfh" in ispec["ISA"]:
|
||||
self.isa += '_Zfh'
|
||||
if "Zca" in ispec["ISA"]:
|
||||
self.isa += '_Zca'
|
||||
if "Zcb" in ispec["ISA"]:
|
||||
|
@ -1,6 +1,6 @@
|
||||
hart_ids: [0]
|
||||
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
|
||||
physical_addr_sz: 32
|
||||
User_Spec_Version: '2.3'
|
||||
|
@ -2,7 +2,7 @@ hart_ids: [0]
|
||||
hart0:
|
||||
# ISA: RV64IMAFDCSUZicsr_Zicboz_Zifencei_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
|
||||
User_Spec_Version: '2.3'
|
||||
supported_xlen: [64]
|
||||
|
@ -607,6 +607,7 @@ SETUP_PLIC
|
||||
.4byte delay1, 0x0000001, write32_test # reset delay1 register
|
||||
.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 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 ip, 0x00000001, read32_test # tx watermark interupt should be pending
|
||||
.4byte 0x0, 0x00000000, readmip_test
|
||||
|
@ -608,6 +608,7 @@ SETUP_PLIC
|
||||
|
||||
.8byte delay1, 0x0000001, write32_test # reset delay1 register
|
||||
.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 ie, 0x00000000, write32_test # enable transmit interrupt
|
||||
.8byte ip, 0x00000001, read32_test # tx watermark interupt should be pending
|
||||
|
Loading…
Reference in New Issue
Block a user