mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
merge
This commit is contained in:
commit
f0266f621b
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
4
wally-pipelined/src/cache/ICacheCntrl.sv
vendored
4
wally-pipelined/src/cache/ICacheCntrl.sv
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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?
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
*/
|
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user