From 7cd8f1a5927114cb32c2be9d883b51f46f7a82fe Mon Sep 17 00:00:00 2001 From: Shreya Sanghai Date: Thu, 4 Mar 2021 11:40:18 -0500 Subject: [PATCH 1/2] added performance counters --- .../config/coremark/wally-config.vh | 1 + wally-pipelined/config/rv32ic/wally-config.vh | 1 + wally-pipelined/config/rv64ic/wally-config.vh | 1 + .../config/rv64icfd/wally-config.vh | 1 + wally-pipelined/src/privileged/csrc.sv | 306 +++++++----------- 5 files changed, 122 insertions(+), 188 deletions(-) diff --git a/wally-pipelined/config/coremark/wally-config.vh b/wally-pipelined/config/coremark/wally-config.vh index 906373f90..5e7f7b7de 100644 --- a/wally-pipelined/config/coremark/wally-config.vh +++ b/wally-pipelined/config/coremark/wally-config.vh @@ -37,6 +37,7 @@ `define S_SUPPORTED ((`MISA >> 18) % 2 == 1) `define U_SUPPORTED ((`MISA >> 20) % 2 == 1) `define ZCSR_SUPPORTED 1 +`define COUNTERS 31 `define ZCOUNTERS_SUPPORTED 1 // N-mode user-level interrupts are depricated per Andrew Waterman 1/13/21 //`define N_SUPPORTED ((MISA >> 13) % 2 == 1) diff --git a/wally-pipelined/config/rv32ic/wally-config.vh b/wally-pipelined/config/rv32ic/wally-config.vh index a5d3ba302..6d6a19da9 100644 --- a/wally-pipelined/config/rv32ic/wally-config.vh +++ b/wally-pipelined/config/rv32ic/wally-config.vh @@ -36,6 +36,7 @@ `define S_SUPPORTED ((`MISA >> 18) % 2 == 1) `define U_SUPPORTED ((`MISA >> 20) % 2 == 1) `define ZCSR_SUPPORTED 1 +`define COUNTERS 31 `define ZCOUNTERS_SUPPORTED 1 // N-mode user-level interrupts are depricated per Andrew Waterman 1/13/21 //`define N_SUPPORTED ((MISA >> 13) % 2 == 1) diff --git a/wally-pipelined/config/rv64ic/wally-config.vh b/wally-pipelined/config/rv64ic/wally-config.vh index 4a9c303d4..2ce4f195d 100644 --- a/wally-pipelined/config/rv64ic/wally-config.vh +++ b/wally-pipelined/config/rv64ic/wally-config.vh @@ -37,6 +37,7 @@ `define S_SUPPORTED ((`MISA >> 18) % 2 == 1) `define U_SUPPORTED ((`MISA >> 20) % 2 == 1) `define ZCSR_SUPPORTED 1 +`define COUNTERS 31 `define ZCOUNTERS_SUPPORTED 1 // N-mode user-level interrupts are depricated per Andrew Waterman 1/13/21 //`define N_SUPPORTED ((MISA >> 13) % 2 == 1) diff --git a/wally-pipelined/config/rv64icfd/wally-config.vh b/wally-pipelined/config/rv64icfd/wally-config.vh index 9e8dccc96..314eb03df 100644 --- a/wally-pipelined/config/rv64icfd/wally-config.vh +++ b/wally-pipelined/config/rv64icfd/wally-config.vh @@ -37,6 +37,7 @@ `define S_SUPPORTED ((`MISA >> 18) % 2 == 1) `define U_SUPPORTED ((`MISA >> 20) % 2 == 1) `define ZCSR_SUPPORTED 1 +`define COUNTERS 31 `define ZCOUNTERS_SUPPORTED 1 // N-mode user-level interrupts are depricated per Andrew Waterman 1/13/21 //`define N_SUPPORTED ((MISA >> 13) % 2 == 1) diff --git a/wally-pipelined/src/privileged/csrc.sv b/wally-pipelined/src/privileged/csrc.sv index a4390c949..cde970c0f 100644 --- a/wally-pipelined/src/privileged/csrc.sv +++ b/wally-pipelined/src/privileged/csrc.sv @@ -2,7 +2,8 @@ // csrc.sv // // Written: David_Harris@hmc.edu 9 January 2021 -// Modified: +// Modified:ssanghai@hmc.edu 2nd March +// Added a configurable number of counters // // Purpose: Counter CSRs // See RISC-V Privileged Mode Specification 20190608 3.1.10-11 @@ -26,43 +27,7 @@ `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, - 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, - MHPMCOUNTER3H = 12'hB83, - MHPMCOUNTER4H = 12'hB84, - // ... more counters - MHPMCOUNTER31H = 12'hB9F, - MCOUNTERINHIBIT = 12'h320, - MHPMEVENT3 = 12'h323, - MHPMEVENT4 = 12'h324, - // ... more counters - MHPMEVENT31 = 12'h33F, - CYCLE = 12'hC00, -// TIME = 12'hC01, // not specified - INSTRET = 12'hC02, - HPMCOUNTER3 = 12'hC03, - HPMCOUNTER4 = 12'hC04, - // ...more counters - HPMCOUNTER31 = 12'hC1F, - CYCLEH = 12'hC80, -// TIMEH = 12'hC81, // not specified - INSTRETH = 12'hC82, - HPMCOUNTER3H = 12'hC83, - HPMCOUNTER4H = 12'hC84, - // ... more counters - HPMCOUNTER31H = 12'hC9F -) ( +module csrc ( input logic clk, reset, input logic InstrValidW, LoadStallD, CSRMWriteM, input logic [11:0] CSRAdrM, @@ -70,163 +35,128 @@ module csrc #(parameter 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 - ); + 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; + // create Counter arrays to store address of each counter + integer MHPMCOUNTER [`COUNTERS:0]; + integer MHPMCOUNTERH [`COUNTERS:0]; + integer HPMCOUNTER [`COUNTERS:0]; + integer HPMCOUNTERH [`COUNTERS:0]; + integer MHPEVENT [`COUNTERS:0]; - // 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); + initial begin + integer i; + for (i=0; i<= `COUNTERS; i = i+1) begin + if (i !==1) begin + MHPMCOUNTER[i] = 12'hB00 + i; // not sure this addition is legit + MHPMCOUNTERH[i] = 12'hB83 + i; + HPMCOUNTER[i] = 12'hC00 + i; + HPMCOUNTERH[i] = 12'hC80 + i; + MHPEVENT[i] = 12'h320 + i; // MHPEVENT[0] = MCOUNTERINHIBIT + end + end //end for loop + end // end for initial - // 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]; + logic [`COUNTERS:0] MCOUNTEN; + assign MCOUNTEN[0] = 1'b1; + assign MCOUNTEN[1] = 1'b0; + assign MCOUNTEN[2] = InstrValidW; + assign MCOUNTEN[3] = LoadStallD; + assign MCOUNTEN[`COUNTERS:4] = 0; - // 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; + genvar j; + generate + if (`ZCOUNTERS_SUPPORTED) begin + logic [`COUNTERS:0][63:0] HPMCOUNTER_REGW; + logic [`COUNTERS:0][63:0] HPMCOUNTERPlusM; + logic [`COUNTERS:0][`XLEN-1:0] NextHPMCOUNTERM; + logic [`COUNTERS:0] WriteHPMCOUNTERM; + logic [4:0] CounterNumM; - // 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]; + for (j=0; j<= `COUNTERS; j = j+1) begin + // Write enables + if (j !==1) begin + assign WriteHPMCOUNTERM[j] = CSRMWriteM && (CSRAdrM == MHPMCOUNTER[j]); + // Count Signals + assign HPMCOUNTERPlusM[j] = HPMCOUNTER_REGW[j] + {63'b0, MCOUNTEN[j] & ~MCOUNTINHIBIT_REGW[j]}; + + assign NextHPMCOUNTERM[j] = WriteHPMCOUNTERM[j] ? CSRWriteValM : HPMCOUNTERPlusM[j][`XLEN-1:0]; + end - // 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; - 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; + // Write / update counters + // Only the Machine mode versions of the counter CSRs are writable + if (`XLEN==64) begin // 64-bit counters + flopr #(64) HPMCOUNTERreg_j(clk, reset, NextHPMCOUNTERM[j], HPMCOUNTER_REGW[j]); 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; - 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; + else begin // 32-bit low and high counters + logic [`COUNTERS:0] WriteHPMCOUNTERHM; + logic [`COUNTERS:0] [`XLEN-1:0] NextHPMCOUNTERHM; + + // Write Enables + assign WriteHPMCOUNTERHM[j] = CSRMWriteM && (CSRAdrM == MHPMCOUNTERH[j]); + assign NextHPMCOUNTERHM[j] = WriteHPMCOUNTERHM[j] ? CSRWriteValM : HPMCOUNTERPlusM[j][63:32]; + + // Counter CSRs + flopr #(32) HPMCOUNTERreg_j(clk, reset, NextHPMCOUNTERM[j], HPMCOUNTER_REGW[j][31:0]); + flopr #(32) HPMCOUNTERHreg_j(clk, reset, NextHPMCOUNTERHM[j], HPMCOUNTER_REGW[j][63:32]); 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 + + // 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) begin // 64-bit counter reads + always_comb + if (PrivilegeModeW == `M_MODE || + MCOUNTEREN_REGW[CounterNumM] && (PrivilegeModeW == `S_MODE || SCOUNTEREN_REGW[CounterNumM])) begin + IllegalCSRCAccessM = 0; + case (CSRAdrM) + MHPMCOUNTER[j]: CSRCReadValM = HPMCOUNTER_REGW[j]; + HPMCOUNTER[j]: CSRCReadValM = HPMCOUNTER_REGW[j]; + default: begin + CSRCReadValM = 0; + IllegalCSRCAccessM = 1; + end + endcase + end + else begin + IllegalCSRCAccessM = 1; // no privileges for this csr + CSRCReadValM = 0; + end + end + else begin // 32-bit counter reads + always_comb + if (PrivilegeModeW == `M_MODE || + MCOUNTEREN_REGW[CounterNumM] && (PrivilegeModeW == `S_MODE || SCOUNTEREN_REGW[CounterNumM])) begin + IllegalCSRCAccessM = 0; + case (CSRAdrM) + MHPMCOUNTER[j]: CSRCReadValM = HPMCOUNTER_REGW[j][31:0]; + HPMCOUNTER[j]: CSRCReadValM = HPMCOUNTER_REGW[j][31:0]; + MHPMCOUNTERH[j]: CSRCReadValM = HPMCOUNTER_REGW[j][63:32]; + HPMCOUNTERH[j]: CSRCReadValM = HPMCOUNTER_REGW[j][63:32]; + default: begin + CSRCReadValM = 0; + IllegalCSRCAccessM = 1; + end + endcase + end + else begin + IllegalCSRCAccessM = 1; // no privileges for this csr + CSRCReadValM = 0; + end + end // 32-bit counter end + end // end for loop + end // end for if + else begin + assign CSRCReadValM = 0; + assign IllegalCSRCAccessM = 1; + end // end for else + endgenerate endmodule From f95a1eadd9bb2b8ef088d8e0b1380d8b3a4cc8ac Mon Sep 17 00:00:00 2001 From: Shreya Sanghai Date: Thu, 4 Mar 2021 12:59:45 -0500 Subject: [PATCH 2/2] fixed bugs --- wally-pipelined/src/privileged/csrc.sv | 112 +++++++++++++++---------- 1 file changed, 67 insertions(+), 45 deletions(-) diff --git a/wally-pipelined/src/privileged/csrc.sv b/wally-pipelined/src/privileged/csrc.sv index cde970c0f..ae14f0f3b 100644 --- a/wally-pipelined/src/privileged/csrc.sv +++ b/wally-pipelined/src/privileged/csrc.sv @@ -49,7 +49,7 @@ module csrc ( for (i=0; i<= `COUNTERS; i = i+1) begin if (i !==1) begin MHPMCOUNTER[i] = 12'hB00 + i; // not sure this addition is legit - MHPMCOUNTERH[i] = 12'hB83 + i; + MHPMCOUNTERH[i] = 12'hB80 + i; HPMCOUNTER[i] = 12'hC00 + i; HPMCOUNTERH[i] = 12'hC80 + i; MHPEVENT[i] = 12'h320 + i; // MHPEVENT[0] = MCOUNTERINHIBIT @@ -73,6 +73,8 @@ module csrc ( logic [`COUNTERS:0] WriteHPMCOUNTERM; logic [4:0] CounterNumM; + assign CounterNumM = CSRAdrM[4:0]; // which counter to read? *** + for (j=0; j<= `COUNTERS; j = j+1) begin // Write enables if (j !==1) begin @@ -100,62 +102,82 @@ module csrc ( flopr #(32) HPMCOUNTERreg_j(clk, reset, NextHPMCOUNTERM[j], HPMCOUNTER_REGW[j][31:0]); flopr #(32) HPMCOUNTERHreg_j(clk, reset, NextHPMCOUNTERHM[j], HPMCOUNTER_REGW[j][63:32]); end + end // end for - // 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 + // 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) begin // 64-bit counter reads - always_comb - if (PrivilegeModeW == `M_MODE || - MCOUNTEREN_REGW[CounterNumM] && (PrivilegeModeW == `S_MODE || SCOUNTEREN_REGW[CounterNumM])) begin - IllegalCSRCAccessM = 0; - case (CSRAdrM) - MHPMCOUNTER[j]: CSRCReadValM = HPMCOUNTER_REGW[j]; - HPMCOUNTER[j]: CSRCReadValM = HPMCOUNTER_REGW[j]; - default: begin - CSRCReadValM = 0; - IllegalCSRCAccessM = 1; - end - endcase + // interrupt on timer compare + // ability to disable optional CSRs + + // Read Counters, or cause excepiton if insufficient privilege in light of COUNTEREN flags + if (`XLEN==64) begin // 64-bit counter reads + always_comb + if (PrivilegeModeW == `M_MODE || + MCOUNTEREN_REGW[CounterNumM] && (PrivilegeModeW == `S_MODE || SCOUNTEREN_REGW[CounterNumM])) begin + + if (CSRAdrM[11:5] == MHPMCOUNTER[0][11:5] || CSRAdrM[11:5] == HPMCOUNTER[0][11:5]) begin + CSRCReadValM = HPMCOUNTER_REGW[CSRAdrM[4:0]]; + IllegalCSRCAccessM = 0; end + // //case (CSRAdrM) + // MHPMCOUNTER[j]: CSRCReadValM = HPMCOUNTER_REGW[j]; + // HPMCOUNTER[j]: CSRCReadValM = HPMCOUNTER_REGW[j]; + // default: begin + // CSRCReadValM = 0; + // IllegalCSRCAccessM = 1; + // end + // endcase + // end else begin IllegalCSRCAccessM = 1; // no privileges for this csr CSRCReadValM = 0; - end + end + end + else begin + IllegalCSRCAccessM = 1; // no privileges for this csr + CSRCReadValM = 0; end - else begin // 32-bit counter reads - always_comb - if (PrivilegeModeW == `M_MODE || - MCOUNTEREN_REGW[CounterNumM] && (PrivilegeModeW == `S_MODE || SCOUNTEREN_REGW[CounterNumM])) begin - IllegalCSRCAccessM = 0; - case (CSRAdrM) - MHPMCOUNTER[j]: CSRCReadValM = HPMCOUNTER_REGW[j][31:0]; - HPMCOUNTER[j]: CSRCReadValM = HPMCOUNTER_REGW[j][31:0]; - MHPMCOUNTERH[j]: CSRCReadValM = HPMCOUNTER_REGW[j][63:32]; - HPMCOUNTERH[j]: CSRCReadValM = HPMCOUNTER_REGW[j][63:32]; - default: begin - CSRCReadValM = 0; - IllegalCSRCAccessM = 1; - end - endcase + end + else begin // 32-bit counter reads + always_comb + if (PrivilegeModeW == `M_MODE || + MCOUNTEREN_REGW[CounterNumM] && (PrivilegeModeW == `S_MODE || SCOUNTEREN_REGW[CounterNumM])) begin + + if (CSRAdrM[11:5] == MHPMCOUNTER[0][11:5] || CSRAdrM[11:5] == HPMCOUNTER[0][11:5] || + CSRAdrM[11:5] == MHPMCOUNTERH[0][11:5] || CSRAdrM[11:5] == HPMCOUNTERH[0][11:5]) begin + CSRCReadValM = HPMCOUNTER_REGW[CSRAdrM[4:0]]; + IllegalCSRCAccessM = 0; end + else begin IllegalCSRCAccessM = 1; // no privileges for this csr CSRCReadValM = 0; - end - end // 32-bit counter end - end // end for loop - end // end for if + end + + // IllegalCSRCAccessM = 0; + // case (CSRAdrM) + // MHPMCOUNTER[j]: CSRCReadValM = HPMCOUNTER_REGW[j][31:0]; + // HPMCOUNTER[j]: CSRCReadValM = HPMCOUNTER_REGW[j][31:0]; + // MHPMCOUNTERH[j]: CSRCReadValM = HPMCOUNTER_REGW[j][63:32]; + // HPMCOUNTERH[j]: CSRCReadValM = HPMCOUNTER_REGW[j][63:32]; + // default: begin + // CSRCReadValM = 0; + // IllegalCSRCAccessM = 1; + // end + // endcase + end + else begin + IllegalCSRCAccessM = 1; // no privileges for this csr + CSRCReadValM = 0; + end + end // 32-bit counter end + end // end for big if else begin - assign CSRCReadValM = 0; - assign IllegalCSRCAccessM = 1; + assign CSRCReadValM = 0; + assign IllegalCSRCAccessM = 1; end // end for else endgenerate endmodule