From f0ec36511738dfac6178f4b0fe052baaf10480ec Mon Sep 17 00:00:00 2001
From: Shreya Sanghai <ssanghai@hmc.edu>
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 246dbd05e7f25240b382fa831ee74ee91156d8ca Mon Sep 17 00:00:00 2001
From: Shreya Sanghai <ssanghai@hmc.edu>
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