diff --git a/setup.sh b/setup.sh index af4bac3b..f6cbac6b 100755 --- a/setup.sh +++ b/setup.sh @@ -16,15 +16,15 @@ 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 QUESTAPATH=/cad/mentor/questa_sim-2022.4_2/questasim/bin # Change this for your path to Questa -export SNPSPATH=/cad/synopsys/SYN/bin # Change this for your path to Design Compiler +export QUESTA_HOME=/cad/mentor/questa_sim-2022.4_2/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 export RISCV=/opt/riscv # change this if you installed the tools in a different location # Tools # Questa and Synopsys -export PATH=$QUESTAPATH:$SNPSPATH:$PATH +export PATH=$QUESTA_HOME/bin:$SNPS_HOME/bin:$PATH # GCC export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RISCV/riscv-gnu-toolchain/lib:$RISCV/riscv-gnu-toolchain/riscv64-unknown-elf/lib export PATH=$PATH:$RISCV/riscv-gnu-toolchain/bin:$RISCV/riscv-gnu-toolchain/riscv64-unknown-elf/bin # GCC tools @@ -42,4 +42,15 @@ export PATH=/usr/local/bin/verilator:$PATH # Change this for your path to Verila #export PATH=$RISCV/imperas-riscv-tests/riscv-ovpsim-plus/bin/Linux64:$PATH #export LD_LIBRARY_PATH=$RISCV/imperas_riscv_tests/riscv-ovpsim-plus/bin/Linux64:$LD_LIBRARY_PATH # remove if no imperas +export IDV=$RISCV/ImperasDV-OpenHW +if [ -e "$IDV" ]; then +# echo "Imperas exists" + export IMPERAS_HOME=$IDV/Imperas + export IMPERAS_PERSONALITY=CPUMAN_DV_ASYNC + export ROOTDIR=~/ + source ${IDV}/Imperas/bin/setup.sh + setupImperas ${IDV}/Imperas +fi + + echo "setup done" \ No newline at end of file diff --git a/src/fpu/fdivsqrt/fdivsqrtfsm.sv b/src/fpu/fdivsqrt/fdivsqrtfsm.sv index 81f6a5ee..da13813f 100644 --- a/src/fpu/fdivsqrt/fdivsqrtfsm.sv +++ b/src/fpu/fdivsqrt/fdivsqrtfsm.sv @@ -60,9 +60,9 @@ module fdivsqrtfsm( assign IFDivStartE = (FDivStartE | (IDivStartE & `IDIV_ON_FPU)) & (state == IDLE) & ~StallM; assign FDivDoneE = (state == DONE); assign FDivBusyE = (state == BUSY) | IFDivStartE; - + // terminate immediately on special cases - assign FSpecialCaseE = XZeroE | (YZeroE&~SqrtE) | XInfE | YInfE | XNaNE | YNaNE | (XsE&SqrtE); + assign FSpecialCaseE = XZeroE | | XInfE | XNaNE | (XsE&SqrtE) | (YZeroE | YInfE | YNaNE)&~SqrtE; if (`IDIV_ON_FPU) assign SpecialCaseE = IntDivE ? ISpecialCaseE : FSpecialCaseE; else assign SpecialCaseE = FSpecialCaseE; flopenr #(1) SpecialCaseReg(clk, reset, IFDivStartE, SpecialCaseE, SpecialCaseM); // save SpecialCase for checking in fdivsqrtpostproc diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 8e89656a..52b7f640 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -113,7 +113,7 @@ module controller( logic FenceD, FenceE; // Fence instruction logic SFenceVmaD; // sfence.vma instruction logic IntDivM; // Integer divide instruction - + logic IFunctD, RFunctD, MFunctD; // Detect I, R, and M-type RV32IM/Rv64IM instructions // Extract fields assign OpD = InstrD[6:0]; @@ -121,6 +121,26 @@ module controller( assign Funct7D = InstrD[31:25]; assign Rs1D = InstrD[19:15]; + // Funct 7 checking + // Be rigorous about detecting illegal instructions if CSRs or bit manipulation is supported + // otherwise be cheap + + if (`ZICSR_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED | `ZBC_SUPPORTED | `ZBS_SUPPORTED) begin // Exact integer decoding + logic Funct7ZeroD, Funct7b5D, IShiftD, INoShiftD; + + assign Funct7ZeroD = (Funct7D == 7'b0000000); // most R-type instructions + assign Funct7b5D = (Funct7D == 7'b0100000); // srai, sub + assign IShiftD = (Funct3D == 3'b001 & Funct7ZeroD) | (Funct3D == 3'b101 & (Funct7ZeroD | Funct7b5D)); // slli, srli, srai, or w forms + assign INoShiftD = (Funct3D != 3'b001 & Funct3D != 3'b101); + assign IFunctD = IShiftD | INoShiftD; + assign RFunctD = ((Funct3D == 3'b000 | Funct3D == 3'b101) & Funct7b5D) | Funct7ZeroD; + assign MFunctD = (Funct7D == 7'b0000001) & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv + end else begin + assign IFunctD = 1; // Don't bother to separate out shift decoding + assign RFunctD = ~Funct7D[0]; // Not a multiply + assign MFunctD = Funct7D[0] & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv + end + // Main Instruction Decoder always_comb case(OpD) @@ -132,9 +152,12 @@ module controller( ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0; // fence else ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_0; // fence treated as nop - 7'b0010011: ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU + 7'b0010011: if (IFunctD) + ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU + else + ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction 7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_0_0_0_0_0_0_0_0_00_0; // auipc - 7'b0011011: if (`XLEN == 64) + 7'b0011011: if (IFunctD & `XLEN == 64) ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_1_0_0_0_0_00_0; // IW-type ALU for RV64i else ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction @@ -149,16 +172,16 @@ module controller( ControlsD = `CTRLW'b1_101_01_11_001_0_0_0_0_0_0_0_0_0_10_0; // amo end else ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction - 7'b0110011: if (Funct7D == 7'b0000000 | Funct7D == 7'b0100000) + 7'b0110011: if (RFunctD) ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_0_0_0_0_0_00_0; // R-type - else if (Funct7D == 7'b0000001 & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2]))) + else if (MFunctD) ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_0_0_0_0_1_00_0; // Multiply/divide else ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction 7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_0_0_1_0_0_0_0_0_00_0; // lui - 7'b0111011: if ((Funct7D == 7'b0000000 | Funct7D == 7'b0100000) & `XLEN == 64) + 7'b0111011: if (RFunctD & (`XLEN == 64)) ControlsD = `CTRLW'b1_000_00_00_000_0_1_0_0_1_0_0_0_0_00_0; // R-type W instructions for RV64i - else if (Funct7D == 7'b0000001 & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])) & `XLEN == 64) + else if (MFunctD & (`XLEN == 64)) ControlsD = `CTRLW'b1_000_00_00_011_0_0_0_0_1_0_0_0_1_00_0; // W-type Multiply/Divide else ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // Non-implemented instruction diff --git a/src/mmu/hptw.sv b/src/mmu/hptw.sv index aac0a606..e7d1a9df 100644 --- a/src/mmu/hptw.sv +++ b/src/mmu/hptw.sv @@ -91,8 +91,8 @@ module hptw ( logic [`PA_BITS-1:0] HPTWReadAdr; logic SelHPTWAdr; logic [`XLEN+1:0] HPTWAdrExt; - logic ITLBMissOrDAFaultF; - logic DTLBMissOrDAFaultM; + logic ITLBMissOrUpdateDAF; + logic DTLBMissOrUpdateDAM; logic LSUAccessFaultM; logic [`PA_BITS-1:0] HPTWAdr; logic [1:0] HPTWRW; @@ -108,14 +108,14 @@ module hptw ( // Extract bits from CSRs and inputs assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0]; - assign TLBMiss = (DTLBMissOrDAFaultM | ITLBMissOrDAFaultF); + assign TLBMiss = (DTLBMissOrUpdateDAM | ITLBMissOrUpdateDAF); // Determine which address to translate mux2 #(`XLEN) vadrmux(PCSpillF, IEUAdrExtM[`XLEN-1:0], DTLBWalk, TranslationVAdr); assign CurrentPPN = PTE[`PPN_BITS+9:10]; // State flops - flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrDAFaultM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB) + 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; flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache @@ -275,8 +275,8 @@ module hptw ( assign SelHPTW = WalkerState != IDLE; assign HPTWStall = (WalkerState != IDLE) | (WalkerState == IDLE & TLBMiss); - assign ITLBMissOrDAFaultF = ITLBMissF | (`SVADU_SUPPORTED & InstrUpdateDAF); - assign DTLBMissOrDAFaultM = DTLBMissM | (`SVADU_SUPPORTED & DataUpdateDAM); + assign ITLBMissOrUpdateDAF = ITLBMissF | (`SVADU_SUPPORTED & InstrUpdateDAF); + assign DTLBMissOrUpdateDAM = DTLBMissM | (`SVADU_SUPPORTED & DataUpdateDAM); // HTPW address/data/control muxing diff --git a/testbench/common/riscvassertions.sv b/testbench/common/riscvassertions.sv index f733aac5..b3bc8f96 100644 --- a/testbench/common/riscvassertions.sv +++ b/testbench/common/riscvassertions.sv @@ -23,7 +23,6 @@ module riscvassertions; initial begin - $display("IDIV_ON_FPU = %b M_SUPPORTED %b comb %b\n", `IDIV_ON_FPU, `M_SUPPORTED, ((`IDIV_ON_FPU) || (!`M_SUPPORTED))); assert (`PMP_ENTRIES == 0 || `PMP_ENTRIES==16 || `PMP_ENTRIES==64) else $error("Illegal number of PMP entries: PMP_ENTRIES must be 0, 16, or 64"); assert (`S_SUPPORTED || `VIRTMEM_SUPPORTED == 0) else $error("Virtual memory requires S mode support"); assert (`IDIV_BITSPERCYCLE == 1 || `IDIV_BITSPERCYCLE==2 || `IDIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: IDIV_BITSPERCYCLE must be 1, 2, or 4");