diff --git a/wally-pipelined/config/buildroot/wally-config.vh b/wally-pipelined/config/buildroot/wally-config.vh index 8e8ec1ca9..826f560f6 100644 --- a/wally-pipelined/config/buildroot/wally-config.vh +++ b/wally-pipelined/config/buildroot/wally-config.vh @@ -37,7 +37,7 @@ `define MISA (32'h0014112D) `define ZCSR_SUPPORTED 1 `define ZCOUNTERS_SUPPORTED 1 -`define COUNTERS 31 +`define COUNTERS 32 // Microarchitectural Features `define UARCH_PIPELINED 1 diff --git a/wally-pipelined/config/busybear/wally-config.vh b/wally-pipelined/config/busybear/wally-config.vh index aa122e7ea..ce189ff1a 100644 --- a/wally-pipelined/config/busybear/wally-config.vh +++ b/wally-pipelined/config/busybear/wally-config.vh @@ -37,7 +37,7 @@ `define MISA (32'h0014112D) `define ZCSR_SUPPORTED 1 `define ZCOUNTERS_SUPPORTED 1 -`define COUNTERS 31 +`define COUNTERS 32 // Microarchitectural Features `define UARCH_PIPELINED 1 diff --git a/wally-pipelined/config/coremark/wally-config.vh b/wally-pipelined/config/coremark/wally-config.vh index 54a09e124..d5935665e 100644 --- a/wally-pipelined/config/coremark/wally-config.vh +++ b/wally-pipelined/config/coremark/wally-config.vh @@ -36,7 +36,7 @@ //`define MISA (32'h00000104) `define MISA (32'h00000104 | 1<<5 | 1<<18 | 1 << 20 | 1 << 12) `define ZCSR_SUPPORTED 1 -`define COUNTERS 31 +`define COUNTERS 32 `define ZCOUNTERS_SUPPORTED 1 // Microarchitectural Features diff --git a/wally-pipelined/config/coremark_bare/wally-config.vh b/wally-pipelined/config/coremark_bare/wally-config.vh index c1d182e15..2a9a6c4cb 100644 --- a/wally-pipelined/config/coremark_bare/wally-config.vh +++ b/wally-pipelined/config/coremark_bare/wally-config.vh @@ -36,7 +36,7 @@ //`define MISA (32'h00000104) `define MISA (32'h00001104 | 1<<5 | 1<<18 | 1 << 20 | 1 << 12 | 1 << 0) `define ZCSR_SUPPORTED 1 -`define COUNTERS 31 +`define COUNTERS 32 `define ZCOUNTERS_SUPPORTED 1 // Microarchitectural Features diff --git a/wally-pipelined/config/rv32ic/wally-config.vh b/wally-pipelined/config/rv32ic/wally-config.vh index 32fdf1967..7bbe713a6 100644 --- a/wally-pipelined/config/rv32ic/wally-config.vh +++ b/wally-pipelined/config/rv32ic/wally-config.vh @@ -35,7 +35,7 @@ `define MISA (32'h00000104 | 1 << 20 | 1 << 18 | 1 << 12) `define ZCSR_SUPPORTED 1 -`define COUNTERS 31 +`define COUNTERS 32 `define ZCOUNTERS_SUPPORTED 1 // Microarchitectural Features diff --git a/wally-pipelined/config/rv64BP/wally-config.vh b/wally-pipelined/config/rv64BP/wally-config.vh index 50a62e4b2..6cc8ce732 100644 --- a/wally-pipelined/config/rv64BP/wally-config.vh +++ b/wally-pipelined/config/rv64BP/wally-config.vh @@ -37,7 +37,7 @@ //`define MISA (32'h00000105) `define MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) `define ZCSR_SUPPORTED 1 -`define COUNTERS 31 +`define COUNTERS 32 `define ZCOUNTERS_SUPPORTED 1 // Microarchitectural Features diff --git a/wally-pipelined/config/rv64ic/wally-config.vh b/wally-pipelined/config/rv64ic/wally-config.vh index bfdf3c131..1c94adf02 100644 --- a/wally-pipelined/config/rv64ic/wally-config.vh +++ b/wally-pipelined/config/rv64ic/wally-config.vh @@ -36,7 +36,7 @@ // MISA RISC-V configuration per specification `define MISA (32'h00000104 | 0 << 5 | 0 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) `define ZCSR_SUPPORTED 1 -`define COUNTERS 31 +`define COUNTERS 32 `define ZCOUNTERS_SUPPORTED 1 // Microarchitectural Features @@ -67,6 +67,8 @@ `define BOOTTIMBASE 32'h00000000 // spec had been 0x1000 to 0x2FFF, but dh truncated to 0x1000 to 0x1FFF because upper half seems to be all zeros and this is easier for decoder `define BOOTTIMRANGE 32'h00003FFF +//`define BOOTTIMBASE 32'h00001000 // spec had been 0x1000 to 0x2FFF, but dh truncated to 0x1000 to 0x1FFF because upper half seems to be all zeros and this is easier for decoder +//`define BOOTTIMRANGE 32'h00000FFF `define TIMBASE 32'h80000000 `define TIMRANGE 32'h07FFFFFF `define CLINTBASE 32'h02000000 diff --git a/wally-pipelined/config/rv64icfd/wally-config.vh b/wally-pipelined/config/rv64icfd/wally-config.vh index 87e8683d4..f003148eb 100644 --- a/wally-pipelined/config/rv64icfd/wally-config.vh +++ b/wally-pipelined/config/rv64icfd/wally-config.vh @@ -36,7 +36,7 @@ // MISA RISC-V configuration per specification `define MISA (32'h00000104 | 0 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) `define ZCSR_SUPPORTED 1 -`define COUNTERS 31 +`define COUNTERS 32 `define ZCOUNTERS_SUPPORTED 1 // Microarchitectural Features @@ -62,7 +62,7 @@ // Peripheral memory space extends from BASE to BASE+RANGE // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits -`define BOOTTIMBASE 32'h00000000 // spec had been 0x1000 to 0x2FFF, but dh truncated to 0x1000 to 0x1FFF because upper half seems to be all zeros and this is easier for decoder +`define BOOTTIMBASE 32'h00000000 `define BOOTTIMRANGE 32'h00003FFF `define TIMBASE 32'h80000000 // `define TIMRANGE 32'h0007FFFF diff --git a/wally-pipelined/config/rv64imc/wally-config.vh b/wally-pipelined/config/rv64imc/wally-config.vh index 1c27ed627..be0970dee 100644 --- a/wally-pipelined/config/rv64imc/wally-config.vh +++ b/wally-pipelined/config/rv64imc/wally-config.vh @@ -35,7 +35,7 @@ // MISA RISC-V configuration per specification `define MISA (32'h00000104 | 0 << 5 | 0 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) `define ZCSR_SUPPORTED 1 -`define COUNTERS 31 +`define COUNTERS 32 `define ZCOUNTERS_SUPPORTED 1 // Microarchitectural Features diff --git a/wally-pipelined/config/shared/wally-shared.vh b/wally-pipelined/config/shared/wally-shared.vh index b6fd7faf1..2db0476d7 100644 --- a/wally-pipelined/config/shared/wally-shared.vh +++ b/wally-pipelined/config/shared/wally-shared.vh @@ -39,9 +39,16 @@ //`define N_SUPPORTED ((MISA >> 13) % 2 == 1) `define N_SUPPORTED 0 + +// logarithm of XLEN, used for number of index bits to select +//`define LOG_XLEN (`XLEN == 32 ? 5 : 6) + +// Number of 64 bit PMP Configuration Register entries (or pairs of 32 bit entries) +`define PMPCFG_ENTRIES (`PMP_ENTRIES\8) + + // Disable spurious Verilator warnings /* verilator lint_off STMTDLY */ -/* verilator lint_off WIDTH */ /* verilator lint_off ASSIGNDLY */ /* verilator lint_off PINCONNECTEMPTY */ diff --git a/wally-pipelined/src/cache/ICacheCntrl.sv b/wally-pipelined/src/cache/ICacheCntrl.sv index 0df6c73c2..7d18bcf24 100644 --- a/wally-pipelined/src/cache/ICacheCntrl.sv +++ b/wally-pipelined/src/cache/ICacheCntrl.sv @@ -156,7 +156,7 @@ module ICacheCntrl #(parameter BLOCKLEN = 256) ( // on spill we want to get the first 2 bytes of the next cache block. // the spill only occurs if the PCPF mod BlockByteLength == -2. Therefore we can // simply add 2 to land on the next cache block. - assign PCSpillF = PCPF + 2'b10; + assign PCSpillF = PCPF + `XLEN'b10; // now we have to select between these three PCs assign PCPreFinalF = PCMux[0] | StallF ? PCPF : PCNextF; // *** don't like the stallf, but it is necessary @@ -188,7 +188,7 @@ module ICacheCntrl #(parameter BLOCKLEN = 256) ( assign spill = PCPF[4:1] == 4'b1111 ? 1'b1 : 1'b0; assign hit = ICacheMemReadValid; // note ICacheMemReadValid is hit. - assign FetchCountFlag = FetchCount == FetchCountThreshold; + assign FetchCountFlag = (FetchCount == FetchCountThreshold); // Next state logic always_comb begin diff --git a/wally-pipelined/src/ebu/amoalu.sv b/wally-pipelined/src/ebu/amoalu.sv index 8acba98cc..45f419665 100644 --- a/wally-pipelined/src/ebu/amoalu.sv +++ b/wally-pipelined/src/ebu/amoalu.sv @@ -50,7 +50,7 @@ module amoalu ( 5'b10100: y = ($signed(a) >= $signed(b)) ? a : b; // amomax 5'b11000: y = ($unsigned(a) < $unsigned(b)) ? a : b; // amominu 5'b11100: y = ($unsigned(a) >= $unsigned(b)) ? a : b; // amomaxu - default: y = 'bx; // undefined; *** could change to b for efficiency + default: y = `XLEN'bx; // undefined; *** could change to b for efficiency endcase // sign extend if necessary diff --git a/wally-pipelined/src/ieu/controller.sv b/wally-pipelined/src/ieu/controller.sv index 9a877f4be..b27541d42 100644 --- a/wally-pipelined/src/ieu/controller.sv +++ b/wally-pipelined/src/ieu/controller.sv @@ -156,7 +156,7 @@ module controller( assign IllegalBaseInstrFaultD = ControlsD[0]; assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD, ResultSrcD, BranchD, ALUOpD, JumpD, TargetSrcD, W64D, CSRReadD, - PrivilegedD, MulDivD, AtomicD, unused} = ControlsD & ~IllegalIEUInstrFaultD; + PrivilegedD, MulDivD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD; // *** move Privileged, CSRwrite?? Or move controller out of IEU into datapath and handle all instructions assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source? diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 4ec40a63b..29d77f091 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -88,11 +88,12 @@ module ifu ( ); - logic [`XLEN-1:0] UnalignedPCNextF, PCNextF; + logic [`XLEN-1:0] PCCorrectE, UnalignedPCNextF, PCNextF; logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM; logic PrivilegedChangePCM; logic IllegalCompInstrD; - logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCW, PCLinkD, PCLinkM, PCNextPF, PCPF; + logic [`XLEN-1:0] PCPlus2or4F, PCW, PCLinkD, PCLinkM, PCNextPF, PCPF; + logic [`XLEN-3:0] PCPlusUpperF; logic CompressedF; logic [31:0] InstrRawD; localparam [31:0] nop = 32'h00000013; // instruction for NOP @@ -117,7 +118,7 @@ module ifu ( // branch predictor signals logic SelBPPredF; - logic [`XLEN-1:0] BPPredPCF, PCCorrectE, PCNext0F, PCNext1F, PCNext2F, PCNext3F; + logic [`XLEN-1:0] BPPredPCF, PCNext0F, PCNext1F, PCNext2F, PCNext3F; logic [4:0] InstrClassD, InstrClassE; diff --git a/wally-pipelined/src/mmu/pagetablewalker.sv b/wally-pipelined/src/mmu/pagetablewalker.sv index 725a319d4..fef3a6ef2 100644 --- a/wally-pipelined/src/mmu/pagetablewalker.sv +++ b/wally-pipelined/src/mmu/pagetablewalker.sv @@ -353,7 +353,7 @@ module pagetablewalker ( // Assign outputs to ahblite // *** Currently truncate address to 32 bits. This must be changed if // we support larger physical address spaces - assign MMUPAdr = TranslationPAdr[31:0]; + assign MMUPAdr = {{(`XLEN-32){1'b0}}, TranslationPAdr[31:0]}; end endgenerate diff --git a/wally-pipelined/src/mmu/physicalpagemask.sv b/wally-pipelined/src/mmu/physicalpagemask.sv index 8adaf4364..472d1c035 100644 --- a/wally-pipelined/src/mmu/physicalpagemask.sv +++ b/wally-pipelined/src/mmu/physicalpagemask.sv @@ -36,7 +36,7 @@ module physicalpagemask ( ); localparam EXTRA_BITS = `PPN_BITS - `VPN_BITS; - logic ZeroExtendedVPN = {{EXTRA_BITS{1'b0}}, VPN}; // forces the VPN to be the same width as PPN. + logic [`PPN_BITS-1:0] ZeroExtendedVPN = {{EXTRA_BITS{1'b0}}, VPN}; // forces the VPN to be the same width as PPN. logic [`PPN_BITS-1:0] OffsetMask; diff --git a/wally-pipelined/src/mmu/priorityencoder.sv b/wally-pipelined/src/mmu/priorityencoder.sv index 9baaee2e4..d56da3d65 100644 --- a/wally-pipelined/src/mmu/priorityencoder.sv +++ b/wally-pipelined/src/mmu/priorityencoder.sv @@ -40,7 +40,9 @@ module priorityencoder #(parameter BINARY_BITS = 3) ( always_comb begin binary = 0; for (i = 0; i < 2**BINARY_BITS; i++) begin + // verilator lint_off WIDTH if (onehot[i]) binary = i; // prioritizes the most significant bit + // verilator lint_on WIDTH end end // *** triple check synthesizability here diff --git a/wally-pipelined/src/muldiv/mul.sv b/wally-pipelined/src/muldiv/mul.sv index 6ed5490d2..3b29ee3fe 100644 --- a/wally-pipelined/src/muldiv/mul.sv +++ b/wally-pipelined/src/muldiv/mul.sv @@ -59,8 +59,8 @@ module mul ( assign PP = SrcAE[`XLEN-1] & SrcBE[`XLEN-1]; // flavor of multiplication - assign MULH = (Funct3E == 2'b01); - assign MULHSU = (Funct3E == 2'b10); + assign MULH = (Funct3E == 3'b001); + assign MULHSU = (Funct3E == 3'b010); // assign MULHU = (Funct3E == 2'b11); // signal unused // Handle signs diff --git a/wally-pipelined/src/privileged/csr.sv b/wally-pipelined/src/privileged/csr.sv index f1576128f..460886593 100644 --- a/wally-pipelined/src/privileged/csr.sv +++ b/wally-pipelined/src/privileged/csr.sv @@ -53,7 +53,7 @@ module csr #(parameter output logic [1:0] STATUS_MPP, output logic STATUS_SPP, STATUS_TSR, output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW, - output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW, + output logic [11:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW, output logic [`XLEN-1:0] SATP_REGW, output logic [11:0] MIP_REGW, MIE_REGW, output logic STATUS_MIE, STATUS_SIE, diff --git a/wally-pipelined/src/privileged/csrc.sv b/wally-pipelined/src/privileged/csrc.sv index fa5eea1a4..73d1fadab 100644 --- a/wally-pipelined/src/privileged/csrc.sv +++ b/wally-pipelined/src/privileged/csrc.sv @@ -1,3 +1,285 @@ + + +/////////////////////////////////////////// +// csrc.sv +// +// Written: David_Harris@hmc.edu 9 January 2021 +// Modified: +// +// Purpose: Counter CSRs +// See RISC-V Privileged Mode Specification 20190608 3.1.10-11 +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module csrc #(parameter + MCYCLE = 12'hB00, +// MTIME = 12'hB01, // address not specified in privileged spec. Consider moving to CLINT to match SiFive + // MTIMECMP = 12'hB21, // not specified in privileged spec. Move to CLINT + MINSTRET = 12'hB02, + MHPMCOUNTERBASE = 12'hB00, + //MHPMCOUNTER3 = 12'hB03, + //MHPMCOUNTER4 = 12'hB04, + // ... more counters + //MHPMCOUNTER31 = 12'hB1F, + MCYCLEH = 12'hB80, +// MTIMEH = 12'hB81, // address not specified in privileged spec. Consider moving to CLINT to match SiFive +// MTIMECMPH = 12'hBA1, // not specified in privileged spec. Move to CLINT + MINSTRETH = 12'hB82, + MHPMCOUNTERHBASE = 12'hB80, + //MHPMCOUNTER3H = 12'hB83, + //MHPMCOUNTER4H = 12'hB84, + // ... more counters + //MHPMCOUNTER31H = 12'hB9F, + MCOUNTERINHIBIT = 12'h320, + MHPMEVENTBASE = 12'h320, + //MHPMEVENT3 = 12'h323, + //MHPMEVENT4 = 12'h324, + // ... more counters + //MHPMEVENT31 = 12'h33F, + CYCLE = 12'hC00, +// TIME = 12'hC01, // not specified + INSTRET = 12'hC02, + HPMCOUNTERBASE = 12'hC00, + //HPMCOUNTER3 = 12'hC03, + //HPMCOUNTER4 = 12'hC04, + // ...more counters + //HPMCOUNTER31 = 12'hC1F, + CYCLEH = 12'hC80, +// TIMEH = 12'hC81, // not specified + INSTRETH = 12'hC82, + HPMCOUNTERHBASE = 12'hC80 + //HPMCOUNTER3H = 12'hC83, + //HPMCOUNTER4H = 12'hC84, + // ... more counters + //HPMCOUNTER31H = 12'hC9F +) ( + input logic clk, reset, + input logic InstrValidW, LoadStallD, CSRMWriteM, + input logic [11:0] CSRAdrM, + input logic [1:0] PrivilegeModeW, + input logic [`XLEN-1:0] CSRWriteValM, + input logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW, + output logic [`XLEN-1:0] CSRCReadValM, + output logic IllegalCSRCAccessM + ); + + generate + if (`ZCOUNTERS_SUPPORTED) begin + // logic [63:0] TIME_REGW, TIMECMP_REGW; + logic [63:0] CYCLE_REGW, INSTRET_REGW; + logic [63:0] HPMCOUNTER3_REGW, HPMCOUNTER4_REGW; // add more performance counters here if desired + logic [63:0] CYCLEPlusM, INSTRETPlusM; + logic [63:0] HPMCOUNTER3PlusM, HPMCOUNTER4PlusM; + // logic [`XLEN-1:0] NextTIMEM; + logic [`XLEN-1:0] NextCYCLEM, NextINSTRETM; + logic [`XLEN-1:0] NextHPMCOUNTER3M, NextHPMCOUNTER4M; + logic WriteCYCLEM, WriteINSTRETM; + logic WriteHPMCOUNTER3M, WriteHPMCOUNTER4M; + logic [4:0] CounterNumM; + logic [`COUNTERS-1:3][`XLEN-1:0] HPMCOUNTER_REGW, HPMCOUNTERH_REGW; + //logic [`COUNTERS-1:3][`XLEN-1:0] HPMCOUNTERH_REGW; + + // Write enables + // assign WriteTIMEM = CSRMWriteM && (CSRAdrM == MTIME); + // assign WriteTIMECMPM = CSRMWriteM && (CSRAdrM == MTIMECMP); + assign WriteCYCLEM = CSRMWriteM && (CSRAdrM == MCYCLE); + assign WriteINSTRETM = CSRMWriteM && (CSRAdrM == MINSTRET); + //assign WriteHPMCOUNTER3M = CSRMWriteM && (CSRAdrM == MHPMCOUNTER3); + //assign WriteHPMCOUNTER4M = CSRMWriteM && (CSRAdrM == MHPMCOUNTER4); + + // Counter adders with inhibits for power savings + assign CYCLEPlusM = CYCLE_REGW + {63'b0, ~MCOUNTINHIBIT_REGW[0]}; + // assign TIMEPlusM = TIME_REGW + 1; // can't be inhibited + assign INSTRETPlusM = INSTRET_REGW + {63'b0, InstrValidW & ~MCOUNTINHIBIT_REGW[2]}; + //assign HPMCOUNTER3PlusM = HPMCOUNTER3_REGW + {63'b0, LoadStallD & ~MCOUNTINHIBIT_REGW[3]}; // count load stalls + ///assign HPMCOUNTER4PlusM = HPMCOUNTER4_REGW + {63'b0, 1'b0 & ~MCOUNTINHIBIT_REGW[4]}; // change to count signals + assign NextCYCLEM = WriteCYCLEM ? CSRWriteValM : CYCLEPlusM[`XLEN-1:0]; + // assign NextTIMEM = WriteTIMEM ? CSRWriteValM : TIMEPlusM[`XLEN-1:0]; + assign NextINSTRETM = WriteINSTRETM ? CSRWriteValM : INSTRETPlusM[`XLEN-1:0]; + //assign NextHPMCOUNTER3M = WriteHPMCOUNTER3M ? CSRWriteValM : HPMCOUNTER3PlusM[`XLEN-1:0]; + //assign NextHPMCOUNTER4M = WriteHPMCOUNTER4M ? CSRWriteValM : HPMCOUNTER4PlusM[`XLEN-1:0]; + + // parameterized number of additional counters + if (`COUNTERS > 3) begin + logic [`COUNTERS-1:3] WriteHPMCOUNTERM, CounterEvent; + logic [63:0] /*HPMCOUNTER_REGW[`COUNTERS-1:3], */ HPMCOUNTERPlusM[`COUNTERS-1:3]; + logic [`XLEN-1:0] NextHPMCOUNTERM[`COUNTERS-1:3]; + + genvar i; + assign CounterEvent[3] = LoadStallD; + assign CounterEvent[`COUNTERS-1:4] = 0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions + + for (i = 3; i < `COUNTERS; i = i+1) begin + assign WriteHPMCOUNTERM[i] = CSRMWriteM && (CSRAdrM == MHPMCOUNTERBASE + i); + assign NextHPMCOUNTERM[i][`XLEN-1:0] = WriteHPMCOUNTERM[i] ? CSRWriteValM : HPMCOUNTERPlusM[i][`XLEN-1:0]; + always @(posedge clk, posedge reset) // ModelSim doesn't like syntax of passing array element to flop + if (reset) HPMCOUNTER_REGW[i][`XLEN-1:0] <= #1 0; + else HPMCOUNTER_REGW[i][`XLEN-1:0] <= #1 NextHPMCOUNTERM[i]; + //flopr #(`XLEN) HPMCOUNTERreg[i](clk, reset, NextHPMCOUNTERM[i], HPMCOUNTER_REGW[i]); + + if (`XLEN==32) begin + logic [`COUNTERS-1:3] WriteHPMCOUNTERHM; + logic [`XLEN-1:0] NextHPMCOUNTERHM[`COUNTERS-1:3]; + assign HPMCOUNTERPlusM[i] = {HPMCOUNTERH_REGW[i], HPMCOUNTER_REGW[i]} + {63'b0, CounterEvent[i] & ~MCOUNTINHIBIT_REGW[i]}; + assign WriteHPMCOUNTERHM[i] = CSRMWriteM && (CSRAdrM == MHPMCOUNTERHBASE + i); + assign NextHPMCOUNTERHM[i] = WriteHPMCOUNTERHM[i] ? CSRWriteValM : HPMCOUNTERPlusM[i][63:32]; + always @(posedge clk, posedge reset) // ModelSim doesn't like syntax of passing array element to flop + if (reset) HPMCOUNTERH_REGW[i][`XLEN-1:0] <= #1 0; + else HPMCOUNTERH_REGW[i][`XLEN-1:0] <= #1 NextHPMCOUNTERHM[i]; + //flopr #(`XLEN) HPMCOUNTERHreg[i](clk, reset, NextHPMCOUNTERHM[i], HPMCOUNTER_REGW[i][63:32]); + end else begin + assign HPMCOUNTERPlusM[i] = HPMCOUNTER_REGW[i] + {63'b0, CounterEvent[i] & ~MCOUNTINHIBIT_REGW[i]}; + end + end + end + + // Write / update counters + // Only the Machine mode versions of the counter CSRs are writable + if (`XLEN==64) begin// 64-bit counters + // flopr #(64) TIMEreg(clk, reset, WriteTIMEM ? CSRWriteValM : TIME_REGW + 1, TIME_REGW); // may count off a different clock*** + // flopenr #(64) TIMECMPreg(clk, reset, WriteTIMECMPM, CSRWriteValM, TIMECMP_REGW); + flopr #(64) CYCLEreg(clk, reset, NextCYCLEM, CYCLE_REGW); + flopr #(64) INSTRETreg(clk, reset, NextINSTRETM, INSTRET_REGW); + //flopr #(64) HPMCOUNTER3reg(clk, reset, NextHPMCOUNTER3M, HPMCOUNTER3_REGW); + //flopr #(64) HPMCOUNTER4reg(clk, reset, NextHPMCOUNTER4M, HPMCOUNTER4_REGW); + end else begin // 32-bit low and high counters + logic WriteTIMEHM, WriteTIMECMPHM, WriteCYCLEHM, WriteINSTRETHM; + //logic WriteHPMCOUNTER3HM, WriteHPMCOUNTER4HM; + logic [`XLEN-1:0] NextCYCLEHM, NextTIMEHM, NextINSTRETHM; + //logic [`XLEN-1:0] NextHPMCOUNTER3HM, NextHPMCOUNTER4HM; + + // Write Enables + // assign WriteTIMEHM = CSRMWriteM && (CSRAdrM == MTIMEH); + // assign WriteTIMECMPHM = CSRMWriteM && (CSRAdrM == MTIMECMPH); + assign WriteCYCLEHM = CSRMWriteM && (CSRAdrM == MCYCLEH); + assign WriteINSTRETHM = CSRMWriteM && (CSRAdrM == MINSTRETH); + //assign WriteHPMCOUNTER3HM = CSRMWriteM && (CSRAdrM == MHPMCOUNTER3H); + //assign WriteHPMCOUNTER4HM = CSRMWriteM && (CSRAdrM == MHPMCOUNTER4H); + assign NextCYCLEHM = WriteCYCLEM ? CSRWriteValM : CYCLEPlusM[63:32]; + // assign NextTIMEHM = WriteTIMEHM ? CSRWriteValM : TIMEPlusM[63:32]; + assign NextINSTRETHM = WriteINSTRETHM ? CSRWriteValM : INSTRETPlusM[63:32]; + //assign NextHPMCOUNTER3HM = WriteHPMCOUNTER3HM ? CSRWriteValM : HPMCOUNTER3PlusM[63:32]; + //assign NextHPMCOUNTER4HM = WriteHPMCOUNTER4HM ? CSRWriteValM : HPMCOUNTER4PlusM[63:32]; + + // Counter CSRs + // flopr #(32) TIMEreg(clk, reset, NextTIMEM, TIME_REGW); // may count off a different clock*** + // flopenr #(32) TIMECMPreg(clk, reset, WriteTIMECMPM, CSRWriteValM, TIMECMP_REGW[31:0]); + flopr #(32) CYCLEreg(clk, reset, NextCYCLEM, CYCLE_REGW[31:0]); + flopr #(32) INSTRETreg(clk, reset, NextINSTRETM, INSTRET_REGW[31:0]); + //flopr #(32) HPMCOUNTER3reg(clk, reset, NextHPMCOUNTER3M, HPMCOUNTER3_REGW[31:0]); + //flopr #(32) HPMCOUNTER4reg(clk, reset, NextHPMCOUNTER4M, HPMCOUNTER4_REGW[31:0]); + // flopr #(32) TIMEHreg(clk, reset, NextTIMEHM, TIME_REGW); // may count off a different clock*** + // flopenr #(32) TIMECMPHreg(clk, reset, WriteTIMECMPHM, CSRWriteValM, TIMECMP_REGW[63:32]); + flopr #(32) CYCLEHreg(clk, reset, NextCYCLEHM, CYCLE_REGW[63:32]); + flopr #(32) INSTRETHreg(clk, reset, NextINSTRETHM, INSTRET_REGW[63:32]); + //flopr #(32) HPMCOUNTER3Hreg(clk, reset, NextHPMCOUNTER3HM, HPMCOUNTER3_REGW[63:32]); + //flopr #(32) HPMCOUNTER4Hreg(clk, reset, NextHPMCOUNTER4HM, HPMCOUNTER4_REGW[63:32]); + end + + // eventually move TIME and TIMECMP to the CLINT + // run TIME off asynchronous reference clock + // synchronize write enable to TIME + // four phase handshake to synchronize reads from TIME + + // interrupt on timer compare + // ability to disable optional CSRs + + // Read Counters, or cause excepiton if insufficient privilege in light of COUNTEREN flags + assign CounterNumM = CSRAdrM[4:0]; // which counter to read? + if (`XLEN==64) // 64-bit counter reads + always_comb + if (PrivilegeModeW == `M_MODE || + MCOUNTEREN_REGW[CounterNumM] && (PrivilegeModeW == `S_MODE || SCOUNTEREN_REGW[CounterNumM])) begin + IllegalCSRCAccessM = 0; + if (CSRAdrM >= MHPMCOUNTERBASE+3 && CSRAdrM < MHPMCOUNTERBASE+`COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CSRAdrM-MHPMCOUNTERBASE]; + else if (CSRAdrM >= HPMCOUNTERBASE+3 && CSRAdrM < HPMCOUNTERBASE+`COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CSRAdrM-HPMCOUNTERBASE]; + else case (CSRAdrM) + // MTIME: CSRCReadValM = TIME_REGW; + // MTIMECMP: CSRCReadValM = TIMECMP_REGW; + MCYCLE: CSRCReadValM = CYCLE_REGW; + MINSTRET: CSRCReadValM = INSTRET_REGW; + //MHPMCOUNTER3: CSRCReadValM = HPMCOUNTER3_REGW; + //MHPMCOUNTER4: CSRCReadValM = HPMCOUNTER4_REGW; + // TIME: CSRCReadValM = TIME_REGW; + CYCLE: CSRCReadValM = CYCLE_REGW; + INSTRET: CSRCReadValM = INSTRET_REGW; + //HPMCOUNTER3: CSRCReadValM = HPMCOUNTER3_REGW; + //HPMCOUNTER4: CSRCReadValM = HPMCOUNTER4_REGW; + default: begin + CSRCReadValM = 0; + IllegalCSRCAccessM = 1; + end + endcase + end else begin + IllegalCSRCAccessM = 1; // no privileges for this csr + CSRCReadValM = 0; + end + else // 32-bit counter reads + always_comb + if (PrivilegeModeW == `M_MODE || MCOUNTEREN_REGW[CounterNumM] && (PrivilegeModeW == `S_MODE || SCOUNTEREN_REGW[CounterNumM])) begin + IllegalCSRCAccessM = 0; + if (CSRAdrM >= MHPMCOUNTERBASE+3 && CSRAdrM < MHPMCOUNTERBASE+`COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CSRAdrM-MHPMCOUNTERBASE]; + else if (CSRAdrM >= HPMCOUNTERBASE+3 && CSRAdrM < HPMCOUNTERBASE+`COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CSRAdrM-HPMCOUNTERBASE]; + else if (CSRAdrM >= MHPMCOUNTERHBASE+3 && CSRAdrM < MHPMCOUNTERHBASE+`COUNTERS) CSRCReadValM = HPMCOUNTERH_REGW[CSRAdrM-MHPMCOUNTERHBASE]; + else if (CSRAdrM >= HPMCOUNTERHBASE+3 && CSRAdrM < HPMCOUNTERHBASE+`COUNTERS) CSRCReadValM = HPMCOUNTERH_REGW[CSRAdrM-HPMCOUNTERHBASE]; + else case (CSRAdrM) + // MTIME: CSRCReadValM = TIME_REGW[31:0]; + // MTIMECMP: CSRCReadValM = TIMECMP_REGW[31:0]; + MCYCLE: CSRCReadValM = CYCLE_REGW[31:0]; + MINSTRET: CSRCReadValM = INSTRET_REGW[31:0]; + //MHPMCOUNTER3: CSRCReadValM = HPMCOUNTER3_REGW[31:0]; + //MHPMCOUNTER4: CSRCReadValM = HPMCOUNTER4_REGW[31:0]; + // TIME: CSRCReadValM = TIME_REGW[31:0]; + CYCLE: CSRCReadValM = CYCLE_REGW[31:0]; + INSTRET: CSRCReadValM = INSTRET_REGW[31:0]; + //HPMCOUNTER3: CSRCReadValM = HPMCOUNTER3_REGW[31:0]; + //HPMCOUNTER4: CSRCReadValM = HPMCOUNTER4_REGW[31:0]; + // MTIMEH: CSRCReadValM = TIME_REGW[63:32]; + // MTIMECMPH: CSRCReadValM = TIMECMP_REGW[63:32]; + MCYCLEH: CSRCReadValM = CYCLE_REGW[63:32]; + MINSTRETH: CSRCReadValM = INSTRET_REGW[63:32]; + //MHPMCOUNTER3H: CSRCReadValM = HPMCOUNTER3_REGW[63:32]; + //MHPMCOUNTER4H: CSRCReadValM = HPMCOUNTER4_REGW[63:32]; + // TIMEH: CSRCReadValM = TIME_REGW[63:32]; + CYCLEH: CSRCReadValM = CYCLE_REGW[63:32]; + INSTRETH: CSRCReadValM = INSTRET_REGW[63:32]; + //HPMCOUNTER3H: CSRCReadValM = HPMCOUNTER3_REGW[63:32]; + //HPMCOUNTER4H: CSRCReadValM = HPMCOUNTER4_REGW[63:32]; + default: begin + CSRCReadValM = 0; + IllegalCSRCAccessM = 1; + end + endcase + end else begin + IllegalCSRCAccessM = 1; // no privileges for this csr + CSRCReadValM = 0; + end + end else begin + assign CSRCReadValM = 0; + assign IllegalCSRCAccessM = 1; + end + endgenerate +endmodule + +/* Bad code from class + /////////////////////////////////////////// // csrc.sv // @@ -29,8 +311,14 @@ `include "wally-config.vh" -module csrc ( - input logic clk, reset, +module csrc #(parameter + // counters + MHPMCOUNTERBASE = 12'hB00, + MHPMCOUNTERHBASE = 12'hB80, + MPHMEVENTBASE = 12'h320, + HPMCOUNTERBASE = 12'hC00, + HPMCOUNTERHBASE = 12'hC80, + )(input logic clk, reset, input logic StallD, StallE, StallM, StallW, input logic InstrValidW, LoadStallD, CSRMWriteM, input logic BPPredDirWrongM, @@ -45,6 +333,9 @@ module csrc ( output logic [`XLEN-1:0] CSRCReadValM, output logic IllegalCSRCAccessM); + // counters + + // create Counter arrays to store address of each counter integer MHPMCOUNTER [`COUNTERS:0]; integer MHPMCOUNTERH [`COUNTERS:0]; @@ -53,6 +344,7 @@ module csrc ( integer MHPEVENT [`COUNTERS:0]; genvar i; + // *** this is totally incorrect. Fix parameterized counters dh 6/9/21 generate for (i = 0; i <= `COUNTERS; i = i + 1) begin if (i != 1) begin @@ -198,4 +490,4 @@ module csrc ( end // end for else endgenerate endmodule - +*/ \ No newline at end of file diff --git a/wally-pipelined/src/privileged/csri.sv b/wally-pipelined/src/privileged/csri.sv index 1b34aaf51..f534ff8f3 100644 --- a/wally-pipelined/src/privileged/csri.sv +++ b/wally-pipelined/src/privileged/csri.sv @@ -37,7 +37,7 @@ module csri #(parameter input logic CSRMWriteM, CSRSWriteM, input logic [11:0] CSRAdrM, input logic ExtIntM, TimerIntM, SwIntM, - input logic [`XLEN-1:0] MIDELEG_REGW, + input logic [11:0] MIDELEG_REGW, output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, input logic [`XLEN-1:0] CSRWriteValM ); @@ -87,8 +87,8 @@ module csri #(parameter end always @(posedge clk, posedge reset) begin if (reset) IE_REGW <= 12'b0; - else if (WriteMIEM) IE_REGW <= (CSRWriteValM & 12'hAAA); // MIE controls M and S fields - else if (WriteSIEM) IE_REGW <= (CSRWriteValM & 12'h222) | (IE_REGW & 12'h888); // only S fields + else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields + else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields // else if (WriteUIEM) IE_REGW = (CSRWriteValM & 12'h111) | (IE_REGW & 12'hAAA); // only U field end endgenerate diff --git a/wally-pipelined/src/privileged/csrm.sv b/wally-pipelined/src/privileged/csrm.sv index 89947847f..6dda40e02 100644 --- a/wally-pipelined/src/privileged/csrm.sv +++ b/wally-pipelined/src/privileged/csrm.sv @@ -74,14 +74,8 @@ module csrm #(parameter DCSR = 12'h7B0, DPC = 12'h7B1, DSCRATCH0 = 12'h7B2, - DSCRATCH1 = 12'h7B3, - - // Constants - ZERO = {(`XLEN){1'b0}}, - ALL_ONES = 32'hfffffff, - MEDELEG_MASK = ~(ZERO | 1'b1 << 11), - MIDELEG_MASK = {{(`XLEN-12){1'b0}}, 12'h222} - ) ( + DSCRATCH1 = 12'h7B3 +) ( input logic clk, reset, input logic StallW, input logic CSRMWriteM, MTrapM, @@ -90,7 +84,7 @@ module csrm #(parameter input logic [`XLEN-1:0] CSRWriteValM, output logic [`XLEN-1:0] CSRMReadValM, MEPC_REGW, MTVEC_REGW, output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW, - output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, + output logic [11:0] MEDELEG_REGW, MIDELEG_REGW, // 64-bit registers in RV64, or two 32-bit registers in RV32 output logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [0:`PMP_ENTRIES-1], @@ -149,8 +143,8 @@ module csrm #(parameter flopenl #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, `XLEN'b0, MTVEC_REGW); //busybear: changed reset value to 0 generate if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin // DELEG registers should exist - flopenl #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK, ZERO, MEDELEG_REGW); - flopenl #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK, ZERO, MIDELEG_REGW); + flopenl #(12) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM[11:0] & 12'h7FF, 12'b0, MEDELEG_REGW); + flopenl #(12) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & 12'h222, 12'b0, MIDELEG_REGW); end else begin assign MEDELEG_REGW = 0; assign MIDELEG_REGW = 0; @@ -167,9 +161,9 @@ module csrm #(parameter if (`OVPSIM_CSR_CONFIG) flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, MCOUNTEREN_REGW); else - flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], ALL_ONES, MCOUNTEREN_REGW); + flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], 32'hFFFFFFFF, MCOUNTEREN_REGW); endgenerate - flopenl #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], ALL_ONES, MCOUNTINHIBIT_REGW); + flopenl #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], 32'hFFFFFFFF, MCOUNTINHIBIT_REGW); // There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop generate @@ -202,13 +196,13 @@ module csrm #(parameter MISA_ADR: CSRMReadValM = MISA_REGW; MVENDORID: CSRMReadValM = 0; MARCHID: CSRMReadValM = 0; - MIMPID: CSRMReadValM = 'h100; // pipelined implementation + MIMPID: CSRMReadValM = `XLEN'h100; // pipelined implementation MHARTID: CSRMReadValM = 0; MSTATUS: CSRMReadValM = MSTATUS_REGW; MSTATUSH: CSRMReadValM = 0; // flush this out later if MBE and SBE fields are supported MTVEC: CSRMReadValM = MTVEC_REGW; - MEDELEG: CSRMReadValM = MEDELEG_REGW; - MIDELEG: CSRMReadValM = MIDELEG_REGW; + MEDELEG: CSRMReadValM = {{(`XLEN-12){1'b0}}, MEDELEG_REGW}; + MIDELEG: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIDELEG_REGW}; MIP: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW}; MIE: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW}; MSCRATCH: CSRMReadValM = MSCRATCH_REGW; @@ -218,9 +212,9 @@ module csrm #(parameter MCOUNTEREN:CSRMReadValM = {{(`XLEN-32){1'b0}}, MCOUNTEREN_REGW}; MCOUNTINHIBIT:CSRMReadValM = {{(`XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW}; PMPCFG0: CSRMReadValM = PMPCFG01_REGW[`XLEN-1:0]; - PMPCFG1: CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG01_REGW[63:31]}; + PMPCFG1: CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG01_REGW[63:32]}; PMPCFG2: CSRMReadValM = PMPCFG23_REGW[`XLEN-1:0]; - PMPCFG3: CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG23_REGW[63:31]}; + PMPCFG3: CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG23_REGW[63:32]}; PMPADDR0: CSRMReadValM = PMPADDR_ARRAY_REGW[0]; // *** make configurable PMPADDR1: CSRMReadValM = PMPADDR_ARRAY_REGW[1]; PMPADDR2: CSRMReadValM = PMPADDR_ARRAY_REGW[2]; diff --git a/wally-pipelined/src/privileged/csrs.sv b/wally-pipelined/src/privileged/csrs.sv index 7fff94dbd..c9e5e9943 100644 --- a/wally-pipelined/src/privileged/csrs.sv +++ b/wally-pipelined/src/privileged/csrs.sv @@ -40,12 +40,7 @@ module csrs #(parameter SCAUSE = 12'h142, STVAL = 12'h143, SIP= 12'h144, - SATP = 12'h180, - - // Constants - ZERO = {(`XLEN){1'b0}}, - ALL_ONES = 32'hfffffff, - SEDELEG_MASK = ~(ZERO | 3'b111 << 9) + SATP = 12'h180 ) ( input logic clk, reset, input logic StallW, @@ -55,7 +50,7 @@ module csrs #(parameter input logic [`XLEN-1:0] CSRWriteValM, output logic [`XLEN-1:0] CSRSReadValM, SEPC_REGW, STVEC_REGW, output logic [31:0] SCOUNTEREN_REGW, - output logic [`XLEN-1:0] SEDELEG_REGW, SIDELEG_REGW, + output logic [11:0] SEDELEG_REGW, SIDELEG_REGW, output logic [`XLEN-1:0] SATP_REGW, input logic [11:0] SIP_REGW, SIE_REGW, output logic WriteSSTATUSM, @@ -84,22 +79,22 @@ module csrs #(parameter assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN) && ~StallW; // CSRs - flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, ZERO, STVEC_REGW); //busybear: change reset to 0 + flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, `XLEN'b0, STVEC_REGW); //busybear: change reset to 0 flopenr #(`XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW); flopenr #(`XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW); - flopenl #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, ZERO, SCAUSE_REGW); + flopenl #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, `XLEN'b0, SCAUSE_REGW); flopenr #(`XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW); flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW); if (`OVPSIM_CSR_CONFIG) flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, SCOUNTEREN_REGW); else - flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], ALL_ONES, SCOUNTEREN_REGW); + flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], 32'hFFFFFFFF, SCOUNTEREN_REGW); if (`N_SUPPORTED) begin logic WriteSEDELEGM, WriteSIDELEGM; assign WriteSEDELEGM = CSRSWriteM && (CSRAdrM == SEDELEG); assign WriteSIDELEGM = CSRSWriteM && (CSRAdrM == SIDELEG); - flopenl #(`XLEN) SEDELEGreg(clk, reset, WriteSEDELEGM, CSRWriteValM & SEDELEG_MASK, ZERO, SEDELEG_REGW); - flopenl #(`XLEN) SIDELEGreg(clk, reset, WriteSIDELEGM, CSRWriteValM, ZERO, SIDELEG_REGW); + flopenl #(12) SEDELEGreg(clk, reset, WriteSEDELEGM, CSRWriteValM[11:0] & 12'h1FF, 12'b0, SEDELEG_REGW); + flopenl #(12) SIDELEGreg(clk, reset, WriteSIDELEGM, CSRWriteValM[11:0], 12'b0, SIDELEG_REGW); end else begin assign SEDELEG_REGW = 0; assign SIDELEG_REGW = 0; @@ -111,8 +106,8 @@ module csrs #(parameter case (CSRAdrM) SSTATUS: CSRSReadValM = SSTATUS_REGW; STVEC: CSRSReadValM = STVEC_REGW; - SEDELEG: CSRSReadValM = SEDELEG_REGW; - SIDELEG: CSRSReadValM = SIDELEG_REGW; + SEDELEG: CSRSReadValM = {{(`XLEN-12){1'b0}}, SEDELEG_REGW}; + SIDELEG: CSRSReadValM = {{(`XLEN-12){1'b0}}, SIDELEG_REGW}; SIP: CSRSReadValM = {{(`XLEN-12){1'b0}}, SIP_REGW}; SIE: CSRSReadValM = {{(`XLEN-12){1'b0}}, SIE_REGW}; SSCRATCH: CSRSReadValM = SSCRATCH_REGW; diff --git a/wally-pipelined/src/privileged/privileged.sv b/wally-pipelined/src/privileged/privileged.sv index 503582def..6476c7533 100644 --- a/wally-pipelined/src/privileged/privileged.sv +++ b/wally-pipelined/src/privileged/privileged.sv @@ -76,8 +76,7 @@ module privileged ( logic [`XLEN-1:0] CauseM, NextFaultMtvalM; logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW; - logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW; -// logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW; + logic [11:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW; logic uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM; logic IllegalCSRAccessM; @@ -105,8 +104,8 @@ module privileged ( /////////////////////////////////////////// // get bits of DELEG registers based on CAUSE - assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[4:0]] : MEDELEG_REGW[CauseM[4:0]]; - assign sd = CauseM[`XLEN-1] ? SIDELEG_REGW[CauseM[4:0]] : SEDELEG_REGW[CauseM[4:0]]; // depricated + assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[3:0]]; + assign sd = CauseM[`XLEN-1] ? SIDELEG_REGW[CauseM[3:0]] : SEDELEG_REGW[CauseM[3:0]]; // depricated // PrivilegeMode FSM always_comb diff --git a/wally-pipelined/src/privileged/trap.sv b/wally-pipelined/src/privileged/trap.sv index 7e5218dec..93475b9d3 100644 --- a/wally-pipelined/src/privileged/trap.sv +++ b/wally-pipelined/src/privileged/trap.sv @@ -49,15 +49,16 @@ module trap ( // input logic WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM ); - logic [11:0] MIntGlobalEnM, SIntGlobalEnM, PendingIntsM; + logic MIntGlobalEnM, SIntGlobalEnM; + logic [11:0] PendingIntsM; //logic InterruptM; logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector; logic BusTrapM; // Determine pending enabled interrupts - assign MIntGlobalEnM = {12{(PrivilegeModeW != `M_MODE) || STATUS_MIE}}; // if M ints enabled or lower priv 3.1.9 + assign MIntGlobalEnM = (PrivilegeModeW != `M_MODE) || STATUS_MIE; // if M ints enabled or lower priv 3.1.9 assign SIntGlobalEnM = (PrivilegeModeW == `U_MODE) || STATUS_SIE; // if S ints enabled or lower priv 3.1.9 - assign PendingIntsM = (MIP_REGW & MIE_REGW) & ((MIntGlobalEnM & 12'h888) | (SIntGlobalEnM & 12'h222)); + assign PendingIntsM = (MIP_REGW & MIE_REGW) & ({12{MIntGlobalEnM}} & 12'h888) | ({12{SIntGlobalEnM}} & 12'h222); assign InterruptM = (|PendingIntsM) & InstrValidM & ~CommittedM; // interrupt if any sources are pending // & with a M stage valid bit to avoid interrupts from interrupt a nonexistent flushed instruction (in the M stage) diff --git a/wally-pipelined/src/uncore/dtim.sv b/wally-pipelined/src/uncore/dtim.sv index 778c509f5..bcb1eb9db 100644 --- a/wally-pipelined/src/uncore/dtim.sv +++ b/wally-pipelined/src/uncore/dtim.sv @@ -96,6 +96,7 @@ module dtim #(parameter BASE=0, RANGE = 65535) ( end -----/\----- EXCLUDED -----/\----- */ + /* verilator lint_off WIDTH */ generate if (`XLEN == 64) begin always_ff @(posedge HCLK) begin @@ -111,7 +112,8 @@ module dtim #(parameter BASE=0, RANGE = 65535) ( end end endgenerate + /* verilator lint_on WIDTH */ - assign HREADTim = HREADYTim ? HREADTim0 : 'bz; + assign HREADTim = HREADYTim ? HREADTim0 : `XLEN'bz; endmodule diff --git a/wally-pipelined/src/uncore/uartPC16550D.sv b/wally-pipelined/src/uncore/uartPC16550D.sv index 9261848c6..057c92ba5 100644 --- a/wally-pipelined/src/uncore/uartPC16550D.sv +++ b/wally-pipelined/src/uncore/uartPC16550D.sv @@ -70,7 +70,7 @@ module uartPC16550D( // Baud and rx/tx timing logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period - logic [23:0] baudcount; + logic [16+`UART_PRESCALE-1:0] baudcount; logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16 logic [3:0] rxbitsreceived, txbitssent; statetype rxstate, txstate; @@ -97,7 +97,8 @@ module uartPC16550D( logic [15:0] RXerrbit, rxfullbit; // transmit data - logic [11:0] TXHR, txdata, nexttxdata, txsr; + logic [7:0] TXHR, nexttxdata; + logic [11:0] txdata, txsr; logic txnextbit, txhrfull, txsrfull; logic txparity; logic txfifoempty, txfifofull, txfifodmaready; @@ -169,7 +170,7 @@ module uartPC16550D( always_comb if (~MEMRb) case (A) - 3'b000: if (DLAB) Dout = DLL; else Dout = RBR; + 3'b000: if (DLAB) Dout = DLL; else Dout = RBR[7:0]; 3'b001: if (DLAB) Dout = DLM; else Dout = {4'b0, IER[3:0]}; 3'b010: Dout = {{2{fifoenabled}}, 2'b00, intrID[2:0], ~intrpending}; // Read only Interupt Ident Register 3'b011: Dout = LCR; @@ -228,13 +229,13 @@ module uartPC16550D( end assign rxcentered = rxbaudpulse && (rxoversampledcnt == 4'b1000); // implies rxstate = UART_ACTIVE - assign rxbitsexpected = 1 + (5 + LCR[1:0]) + LCR[3] + 1; // start bit + data bits + (parity bit) + stop bit + assign rxbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1; // start bit + data bits + (parity bit) + stop bit /////////////////////////////////////////// // receive shift register, buffer register, FIFO /////////////////////////////////////////// always_ff @(posedge HCLK, negedge HRESETn) - if (~HRESETn) rxshiftreg <= #1 9'b000000001; // initialize so that there is a valid stop bit + if (~HRESETn) rxshiftreg <= #1 10'b0000000001; // initialize so that there is a valid stop bit else if (rxcentered) rxshiftreg <= #1 {rxshiftreg[8:0], SINsync}; // capture bit assign rxparitybit = rxshiftreg[1]; // parity, if it exists, in bit 1 when all done assign rxstopbit = rxshiftreg[0]; @@ -278,8 +279,10 @@ module uartPC16550D( end assign rxfifoempty = (rxfifohead == rxfifotail); + // verilator lint_off WIDTH assign rxfifoentries = (rxfifohead >= rxfifotail) ? (rxfifohead-rxfifotail) : (rxfifohead + 16 - rxfifotail); + // verilator lint_on WIDTH assign rxfifotriggered = rxfifoentries >= rxfifotriggerlevel; //assign rxfifotimeout = rxtimeoutcnt[6]; // time out after 4 character periods; *** probably not right yet assign rxfifotimeout = 0; // disabled pending fix @@ -337,7 +340,7 @@ module uartPC16550D( txstate <= #1 UART_IDLE; end - assign txbitsexpected = 1 + (5 + LCR[1:0]) + LCR[3] + 1 + LCR[2] - 1; // start bit + data bits + (parity bit) + stop bit(s) + assign txbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1 + {3'b000, LCR[2]} - 4'd1; // start bit + data bits + (parity bit) + stop bit(s) assign txnextbit = txbaudpulse && (txoversampledcnt == 4'b0000); // implies txstate = UART_ACTIVE /////////////////////////////////////////// @@ -400,8 +403,10 @@ module uartPC16550D( end assign txfifoempty = (txfifohead == txfifotail); + // verilator lint_off WIDTH assign txfifoentries = (txfifohead >= txfifotail) ? (txfifohead-txfifotail) : (txfifohead + 16 - txfifotail); + // verilator lint_on WIDTH assign txfifofull = (txfifoentries == 4'b1111); // transmit buffer ready bit diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 4dab4e9dc..e67606ec1 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -516,6 +516,10 @@ string tests32f[] = '{ flopenr #(`XLEN) PCWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.PCM, PCW); flopenr #(32) InstrWReg(clk, reset, ~dut.hart.ieu.dp.StallW, dut.hart.ifu.InstrM, InstrW); + + // check assertions for a legal configuration + riscvassertions riscvassertions(); + // pick tests based on modes supported initial begin if (`XLEN == 64) begin // RV64 @@ -713,6 +717,13 @@ string tests32f[] = '{ endmodule +module riscvassertions(); + // Legal number of PMP entries are 0, 16, or 64 + initial begin + assert (`PMP_ENTRIES == 0 || `PMP_ENTRIES==16 || `PMP_ENTRIES==64) else $error("Illegal number of PMP entries"); + end +endmodule + /* verilator lint_on STMTDLY */ /* verilator lint_on WIDTH */