mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally into main
This commit is contained in:
		
						commit
						e11c565a6f
					
				| @ -25,8 +25,6 @@ | ||||
| 
 | ||||
| `include "wally-config.vh" | ||||
| /* verilator lint_off DECLFILENAME */ | ||||
| // Note that non-zero RESET_VAL's are only ever intended for simulation purposes (to start mid-execution from a checkpoint)
 | ||||
| 
 | ||||
| 
 | ||||
| // ordinary flip-flop
 | ||||
| module flop #(parameter WIDTH = 8) (  | ||||
| @ -42,11 +40,10 @@ endmodule | ||||
| module flopr #(parameter WIDTH = 8) (  | ||||
|   input  logic             clk, reset, | ||||
|   input  logic [WIDTH-1:0] d,  | ||||
|   output logic [WIDTH-1:0] q, | ||||
|   input  var   [WIDTH-1:0] RESET_VAL=0); | ||||
|   output logic [WIDTH-1:0] q); | ||||
| 
 | ||||
|   always_ff @(posedge clk, posedge reset) | ||||
|     if (reset) q <= #1 RESET_VAL; | ||||
|     if (reset) q <= #1 0; | ||||
|     else       q <= #1 d; | ||||
| endmodule | ||||
| 
 | ||||
| @ -64,11 +61,10 @@ endmodule | ||||
| module flopenrc #(parameter WIDTH = 8) ( | ||||
|   input  logic             clk, reset, clear, en, | ||||
|   input  logic [WIDTH-1:0] d,  | ||||
|   output logic [WIDTH-1:0] q, | ||||
|   input  var   [WIDTH-1:0] RESET_VAL=0); | ||||
|   output logic [WIDTH-1:0] q); | ||||
| 
 | ||||
|   always_ff @(posedge clk, posedge reset) | ||||
|     if (reset)   q <= #1 RESET_VAL; | ||||
|     if (reset)   q <= #1 0; | ||||
|     else if (en)  | ||||
|       if (clear) q <= #1 0; | ||||
|       else       q <= #1 d; | ||||
| @ -78,11 +74,10 @@ endmodule | ||||
| module flopenr #(parameter WIDTH = 8) ( | ||||
|   input  logic             clk, reset, en, | ||||
|   input  logic [WIDTH-1:0] d,  | ||||
|   output logic [WIDTH-1:0] q, | ||||
|   input  var   [WIDTH-1:0] RESET_VAL=0); | ||||
|   output logic [WIDTH-1:0] q); | ||||
| 
 | ||||
|   always_ff @(posedge clk, posedge reset) | ||||
|     if (reset)   q <= #1 RESET_VAL; | ||||
|     if (reset)   q <= #1 0; | ||||
|     else if (en) q <= #1 d; | ||||
| endmodule | ||||
| 
 | ||||
| @ -104,11 +99,10 @@ module floprc #(parameter WIDTH = 8) ( | ||||
|   input  logic reset, | ||||
|   input  logic clear, | ||||
|   input  logic [WIDTH-1:0] d,  | ||||
|   output logic [WIDTH-1:0] q, | ||||
|   input  var RESET_VAL=0); | ||||
|   output logic [WIDTH-1:0] q); | ||||
| 
 | ||||
|   always_ff @(posedge clk, posedge reset) | ||||
|     if (reset) q <= #1 RESET_VAL; | ||||
|     if (reset) q <= #1 0; | ||||
|     else        | ||||
|       if (clear) q <= #1 0; | ||||
|       else       q <= #1 d; | ||||
|  | ||||
| @ -44,13 +44,7 @@ module regfile ( | ||||
|   // reset is intended for simulation only, not synthesis
 | ||||
|      | ||||
|   always_ff @(negedge clk or posedge reset) | ||||
|     if (reset) | ||||
|     `ifdef CHECKPOINT | ||||
|       $readmemh({`LINUX_CHECKPOINT,"checkpoint-regfile.txt"}, rf); | ||||
|     `else | ||||
|       for(i=1; i<32; i++) rf[i] <= 0; | ||||
|     `endif | ||||
|      | ||||
|     if (reset) for(i=1; i<32; i++) rf[i] <= 0; | ||||
|     else if (we3) rf[a3] <= wd3;	 | ||||
| 
 | ||||
|   assign #2 rd1 = (a1 != 0) ? rf[a1] : 0; | ||||
|  | ||||
| @ -70,24 +70,24 @@ module csrc #(parameter | ||||
|   //  ... more counters
 | ||||
|   //HPMCOUNTER31H = 12'hC9F
 | ||||
| ) ( | ||||
|     input logic              clk, reset, | ||||
|     input logic              StallD, StallE, StallM, StallW, | ||||
|     input logic 	     clk, reset, | ||||
|     input logic 	     StallD, StallE, StallM, StallW, | ||||
|     input  logic             FlushD, FlushE, FlushM, FlushW,    | ||||
|     input logic              InstrValidM, LoadStallD, CSRMWriteM, | ||||
|     input logic              BPPredDirWrongM, | ||||
|     input logic              BTBPredPCWrongM, | ||||
|     input logic              RASPredPCWrongM, | ||||
|     input logic              BPPredClassNonCFIWrongM, | ||||
|     input logic [4:0]              InstrClassM, | ||||
|     input logic              DCacheMiss, | ||||
|     input logic              DCacheAccess, | ||||
|     input logic [11:0]              CSRAdrM, | ||||
|     input logic [1:0]              PrivilegeModeW, | ||||
|     input logic 	     InstrValidM, LoadStallD, CSRMWriteM, | ||||
|     input logic 	     BPPredDirWrongM, | ||||
|     input logic 	     BTBPredPCWrongM, | ||||
|     input logic 	     RASPredPCWrongM, | ||||
|     input logic 	     BPPredClassNonCFIWrongM, | ||||
|     input logic [4:0] 	     InstrClassM, | ||||
|     input logic 	     DCacheMiss, | ||||
|     input logic 	     DCacheAccess, | ||||
|     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, | ||||
|     input logic [63:0]              MTIME_CLINT, MTIMECMP_CLINT, | ||||
|     input logic [31:0] 	     MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW, | ||||
|     input logic [63:0] 	     MTIME_CLINT, MTIMECMP_CLINT, | ||||
|     output logic [`XLEN-1:0] CSRCReadValM, | ||||
|     output logic              IllegalCSRCAccessM | ||||
|     output logic 	     IllegalCSRCAccessM | ||||
|   ); | ||||
| 
 | ||||
|   generate | ||||
| @ -97,22 +97,14 @@ module csrc #(parameter | ||||
|       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] 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; | ||||
|       var [`COUNTERS-1:3][`XLEN-1:0] initHPMCOUNTER; | ||||
|       logic                            InstrValidNotFlushedM; | ||||
| 
 | ||||
|       initial | ||||
|       `ifdef CHECKPOINT | ||||
|         $readmemh({`LINUX_CHECKPOINT,"checkpoint-HPMCOUNTER.txt"}, initHPMCOUNTER); | ||||
|       `else | ||||
|         initHPMCOUNTER = {(`COUNTERS-3){`XLEN'b0}}; | ||||
|       `endif | ||||
|       logic 			       InstrValidNotFlushedM; | ||||
| 
 | ||||
|       assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW; | ||||
|        | ||||
| @ -138,116 +130,121 @@ module csrc #(parameter | ||||
|       //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 | ||||
|     // parameterized number of additional counters
 | ||||
|     if (`COUNTERS > 3) begin | ||||
|         logic [`COUNTERS-1:3] WriteHPMCOUNTERM; | ||||
|         logic [`COUNTERS-1:0] CounterEvent; | ||||
|         logic [63:0] /*HPMCOUNTER_REGW[`COUNTERS-1:3], */ HPMCOUNTERPlusM[`COUNTERS-1:3]; | ||||
|         logic [`XLEN-1:0] NextHPMCOUNTERM[`COUNTERS-1:3]; | ||||
|         genvar i; | ||||
| 
 | ||||
|         // could replace special counters 0-2 with this loop for all counters
 | ||||
|         assign CounterEvent[0] = 1'b1; | ||||
|         assign CounterEvent[1] = 1'b0; | ||||
|         if(`QEMU) assign CounterEvent[`COUNTERS-1:2] = 0; | ||||
|         else begin | ||||
|           logic LoadStallE, LoadStallM; | ||||
|           flopenrc #(1) LoadStallEReg(.clk, .reset, .clear(FlushE), .en(~StallE), .d(LoadStallD), .q(LoadStallE)); | ||||
|           flopenrc #(1) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d(LoadStallE), .q(LoadStallM));         | ||||
|            | ||||
|           assign CounterEvent[2] = InstrValidNotFlushedM; | ||||
|           assign CounterEvent[3] = LoadStallM & InstrValidNotFlushedM; | ||||
|           assign CounterEvent[4] = BPPredDirWrongM & InstrValidNotFlushedM; | ||||
|           assign CounterEvent[5] = InstrClassM[0] & InstrValidNotFlushedM; | ||||
|           assign CounterEvent[6] = BTBPredPCWrongM & InstrValidNotFlushedM; | ||||
|           assign CounterEvent[7] = (InstrClassM[4] | InstrClassM[2] | InstrClassM[1]) & InstrValidNotFlushedM; | ||||
|           assign CounterEvent[8] = RASPredPCWrongM & InstrValidNotFlushedM; | ||||
|           assign CounterEvent[9] = InstrClassM[3] & InstrValidNotFlushedM; | ||||
|           assign CounterEvent[10] = BPPredClassNonCFIWrongM & InstrValidNotFlushedM; | ||||
|           assign CounterEvent[11] = DCacheAccess & InstrValidNotFlushedM; | ||||
|           assign CounterEvent[12] = DCacheMiss & InstrValidNotFlushedM;       | ||||
|           assign CounterEvent[`COUNTERS-1:13] = 0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions
 | ||||
|         end | ||||
|          | ||||
|         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 initHPMCOUNTER[i]; | ||||
|             else if (~StallW) HPMCOUNTER_REGW[i][`XLEN-1:0] <= #1 NextHPMCOUNTERM[i]; | ||||
|           //flopr #(`XLEN) HPMCOUNTERreg[i](clk, reset, NextHPMCOUNTERM[i], HPMCOUNTER_REGW[i]);
 | ||||
|       if(`QEMU) begin | ||||
|         assign CounterEvent[`COUNTERS-1:2] = 0; | ||||
|       end else begin | ||||
| 
 | ||||
|           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 if (~StallW) 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 | ||||
| 	logic LoadStallE, LoadStallM; | ||||
| 	 | ||||
| 	flopenrc #(1) LoadStallEReg(.clk, .reset, .clear(FlushE), .en(~StallE), .d(LoadStallD), .q(LoadStallE)); | ||||
| 	flopenrc #(1) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d(LoadStallE), .q(LoadStallM));	 | ||||
| 	 | ||||
|         assign CounterEvent[2] = InstrValidNotFlushedM; | ||||
|         assign CounterEvent[3] = LoadStallM & InstrValidNotFlushedM; | ||||
|         assign CounterEvent[4] = BPPredDirWrongM & InstrValidNotFlushedM; | ||||
|         assign CounterEvent[5] = InstrClassM[0] & InstrValidNotFlushedM; | ||||
|         assign CounterEvent[6] = BTBPredPCWrongM & InstrValidNotFlushedM; | ||||
|         assign CounterEvent[7] = (InstrClassM[4] | InstrClassM[2] | InstrClassM[1]) & InstrValidNotFlushedM; | ||||
|         assign CounterEvent[8] = RASPredPCWrongM & InstrValidNotFlushedM; | ||||
|         assign CounterEvent[9] = InstrClassM[3] & InstrValidNotFlushedM; | ||||
|         assign CounterEvent[10] = BPPredClassNonCFIWrongM & InstrValidNotFlushedM; | ||||
|         assign CounterEvent[11] = DCacheAccess & InstrValidNotFlushedM; | ||||
|         assign CounterEvent[12] = DCacheMiss & InstrValidNotFlushedM;       | ||||
|         assign CounterEvent[`COUNTERS-1:13] = 0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions
 | ||||
|       end | ||||
|        | ||||
|         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 if (~StallW) 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 if (~StallW) 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;
 | ||||
|         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];
 | ||||
|           // 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 | ||||
|           // 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 -- Ben 06/17/21: sure let's give that a shot!
 | ||||
|       //  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 -- Ben 06/17/21: sure let's give that a shot!
 | ||||
|     //  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
 | ||||
|     // 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 | ||||
|             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]; | ||||
| @ -312,7 +309,7 @@ module csrc #(parameter | ||||
|               IllegalCSRCAccessM = 1; // no privileges for this csr
 | ||||
|               CSRCReadValM = 0; | ||||
|             end | ||||
|     end else begin // not `ZICOUNTERS_SUPPORTED
 | ||||
|     end else begin | ||||
|       assign CSRCReadValM = 0; | ||||
|       assign IllegalCSRCAccessM = 1; | ||||
|     end | ||||
| @ -359,20 +356,20 @@ module csrc #(parameter | ||||
|   MPHMEVENTBASE = 12'h320, | ||||
|   HPMCOUNTERBASE = 12'hC00, | ||||
|   HPMCOUNTERHBASE = 12'hC80, | ||||
|   )(input logic              clk, reset, | ||||
|     input logic              StallD, StallE, StallM, StallW, | ||||
|     input logic              InstrValidM, LoadStallD, CSRMWriteM, | ||||
|     input logic              BPPredDirWrongM, | ||||
|     input logic              BTBPredPCWrongM, | ||||
|     input logic              RASPredPCWrongM, | ||||
|     input logic              BPPredClassNonCFIWrongM, | ||||
|     input logic [4:0]              InstrClassM, | ||||
|     input logic [11:0]              CSRAdrM, | ||||
|     input logic [1:0]              PrivilegeModeW, | ||||
|   )(input logic 	     clk, reset, | ||||
|     input logic 	     StallD, StallE, StallM, StallW, | ||||
|     input logic 	     InstrValidM, LoadStallD, CSRMWriteM, | ||||
|     input logic 	     BPPredDirWrongM, | ||||
|     input logic 	     BTBPredPCWrongM, | ||||
|     input logic 	     RASPredPCWrongM, | ||||
|     input logic 	     BPPredClassNonCFIWrongM, | ||||
|     input logic [4:0] 	     InstrClassM, | ||||
|     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, | ||||
|     input logic [31:0] 	     MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW, | ||||
|     output logic [`XLEN-1:0] CSRCReadValM, | ||||
|     output logic              IllegalCSRCAccessM); | ||||
|     output logic 	     IllegalCSRCAccessM); | ||||
| 
 | ||||
|     // counters
 | ||||
| 
 | ||||
|  | ||||
| @ -79,24 +79,14 @@ module csri #(parameter | ||||
|       assign SIP_WRITE_MASK = 12'h000; | ||||
|     end | ||||
|     always @(posedge clk, posedge reset) begin // *** I strongly feel that IntInM should go directly to IP_REGW -- Ben 9/7/21
 | ||||
|       if (reset)           | ||||
|       `ifdef CHECKPOINT | ||||
|         $readmemh({`LINUX_CHECKPOINT,"checkpoint-MIP.txt"}, IP_REGW_writeable); | ||||
|       `else | ||||
|         IP_REGW_writeable <= 10'b0; | ||||
|       `endif | ||||
|       if (reset)          IP_REGW_writeable <= 10'b0; | ||||
|       else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | IntInM[9:0]; // MTIP unclearable
 | ||||
|       else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & SIP_WRITE_MASK[9:0]) | IntInM[9:0]; // MTIP unclearable
 | ||||
| //      else if (WriteUIPM) IP_REGW = (CSRWriteValM & 12'hBBB) | (NextIPM & 12'h080); // MTIP unclearable
 | ||||
|       else                IP_REGW_writeable <= IP_REGW_writeable | IntInM[9:0]; // *** check this turns off interrupts properly even when MIDELEG changes
 | ||||
|     end | ||||
|     always @(posedge clk, posedge reset) begin | ||||
|       if (reset) | ||||
|       `ifdef CHECKPOINT | ||||
|         $readmemh({`LINUX_CHECKPOINT,"checkpoint-MIE.txt"}, IE_REGW); | ||||
|       `else | ||||
|         IE_REGW <= 12'b0; | ||||
|       `endif | ||||
|       if (reset)          IE_REGW <= 12'b0; | ||||
|       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
 | ||||
|  | ||||
| @ -85,45 +85,15 @@ module csrm #(parameter | ||||
|   logic [`XLEN-1:0] MISA_REGW, MHARTID_REGW; | ||||
|   logic [`XLEN-1:0] MSCRATCH_REGW, MCAUSE_REGW, MTVAL_REGW; | ||||
| 
 | ||||
|   var [`XLEN-1:0] initMSCRATCH, initMCAUSE, initMEPC, initMTVEC, initMEDELEG, initMIDELEG; | ||||
|   var [31:0] initMCOUNTEREN, initMCOUNTINHIBIT; | ||||
|   var [`PMP_ENTRIES-1:0][7:0] initPMPCFG_ARRAY; | ||||
|   var [`PMP_ENTRIES-1:0][`XLEN-1:0] initPMPADDR_ARRAY; | ||||
| 
 | ||||
|   logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; | ||||
|   logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; | ||||
|   logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM; | ||||
|   logic            WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; | ||||
|   logic            WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; | ||||
|   logic            WriteMCOUNTERENM, WriteMCOUNTINHIBITM; | ||||
|   logic [`PMP_ENTRIES-1:0] WritePMPCFGM; | ||||
|   logic [`PMP_ENTRIES-1:0] WritePMPADDRM ;  | ||||
|   logic [`PMP_ENTRIES-1:0] ADDRLocked, CFGLocked; | ||||
| 
 | ||||
|   localparam MISA_26 = (`MISA) & 32'h03ffffff; | ||||
| 
 | ||||
|   initial begin | ||||
|   `ifdef CHECKPOINT | ||||
|     $readmemh({`LINUX_CHECKPOINT,"checkpoint-MSCRATCH.txt"}, initMSCRATCH); | ||||
|     $readmemh({`LINUX_CHECKPOINT,"checkpoint-MCAUSE.txt"}, initMCAUSE); | ||||
|     $readmemh({`LINUX_CHECKPOINT,"checkpoint-MEPC.txt"}, initMEPC); | ||||
|     $readmemh({`LINUX_CHECKPOINT,"checkpoint-MTVEC.txt"}, initMTVEC); | ||||
|     $readmemh({`LINUX_CHECKPOINT,"checkpoint-MEDELEG.txt"}, initMEDELEG); | ||||
|     $readmemh({`LINUX_CHECKPOINT,"checkpoint-MIDELEG.txt"}, initMIDELEG); | ||||
|     $readmemh({`LINUX_CHECKPOINT,"checkpoint-MCOUNTEREN.txt"}, initMCOUNTEREN); | ||||
|     $readmemh({`LINUX_CHECKPOINT,"checkpoint-PMPCFG.txt"}, initPMPCFG_ARRAY); | ||||
|     $readmemh({`LINUX_CHECKPOINT,"checkpoint-PMPADDR.txt"}, initPMPADDR_ARRAY); | ||||
|   `else | ||||
|     initMSCRATCH = `XLEN'b0; | ||||
|     initMCAUSE = `XLEN'b0; | ||||
|     initMEPC = `XLEN'b0; | ||||
|     initMTVEC = `XLEN'b0; | ||||
|     initMEDELEG = `XLEN'b0; | ||||
|     initMIDELEG = `XLEN'b0; | ||||
|     initMCOUNTEREN = 32'b0; | ||||
|     initMCOUNTINHIBIT = 32'b0; | ||||
|     initPMPCFG_ARRAY = {`PMP_ENTRIES{8'b0}}; | ||||
|     initPMPADDR_ARRAY = {`PMP_ENTRIES{`XLEN'b0}}; | ||||
|   `endif | ||||
|   end | ||||
| 
 | ||||
|   // MISA is hardwired.  Spec says it could be written to disable features, but this is not supported by Wally
 | ||||
|   assign MISA_REGW = {(`XLEN == 32 ? 2'b01 : 2'b10), {(`XLEN-28){1'b0}}, MISA_26[25:0]}; | ||||
| 
 | ||||
| @ -145,31 +115,33 @@ module csrm #(parameter | ||||
|   assign IllegalCSRMWriteReadonlyM = CSRMWriteM && (CSRAdrM == MVENDORID || CSRAdrM == MARCHID || CSRAdrM == MIMPID || CSRAdrM == MHARTID); | ||||
| 
 | ||||
|   // CSRs
 | ||||
|   flopenl #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, initMTVEC, MTVEC_REGW); //busybear: changed reset value to 0
 | ||||
|   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 /*12'h7FF*/, initMEDELEG, MEDELEG_REGW); | ||||
|       flopenl #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, initMIDELEG, MIDELEG_REGW); | ||||
|       flopenl #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK /*12'h7FF*/, `XLEN'b0, MEDELEG_REGW); | ||||
|       flopenl #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, `XLEN'b0, MIDELEG_REGW); | ||||
|     end else begin | ||||
|       assign MEDELEG_REGW = 0; | ||||
|       assign MIDELEG_REGW = 0; | ||||
|     end | ||||
|   endgenerate | ||||
| 
 | ||||
|   flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW, initMSCRATCH); | ||||
|   flopenr #(`XLEN)     MEPCreg(clk, reset, WriteMEPCM,     NextEPCM,     MEPC_REGW,     initMEPC);  | ||||
|   flopenr #(`XLEN)   MCAUSEreg(clk, reset, WriteMCAUSEM,   NextCauseM,   MCAUSE_REGW,   initMCAUSE); | ||||
| //  flopenl #(`XLEN) MIPreg(clk, reset, WriteMIPM, CSRWriteValM, zero, MIP_REGW);
 | ||||
| //  flopenl #(`XLEN) MIEreg(clk, reset, WriteMIEM, CSRWriteValM, zero, MIE_REGW);
 | ||||
|   flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW); | ||||
|   flopenr #(`XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW);  | ||||
|   flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW); | ||||
|   if(`QEMU) assign MTVAL_REGW = `XLEN'b0; | ||||
|   else flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW); | ||||
|   generate | ||||
|     if (`BUSYBEAR == 1) | ||||
|       flopenl #(32)   MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, MCOUNTEREN_REGW); | ||||
|     else if (`BUILDROOT == 1) | ||||
|       flopenl #(32)   MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], initMCOUNTEREN, MCOUNTEREN_REGW); | ||||
|       flopenl #(32)   MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], 32'h0, MCOUNTEREN_REGW); | ||||
|     else | ||||
|       flopenl #(32)   MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], 32'hFFFFFFFF, MCOUNTEREN_REGW); | ||||
|   endgenerate | ||||
|   flopenl #(32)   MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], initMCOUNTINHIBIT, MCOUNTINHIBIT_REGW); | ||||
|   flopenl #(32)   MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], 32'h0, MCOUNTINHIBIT_REGW); | ||||
| 
 | ||||
|   // There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop
 | ||||
| 
 | ||||
| @ -186,14 +158,14 @@ module csrm #(parameter | ||||
|         assign ADDRLocked[i] = PMPCFG_ARRAY_REGW[i][7] | (PMPCFG_ARRAY_REGW[i+1][7] & PMPCFG_ARRAY_REGW[i+1][4:3] == 2'b01); | ||||
|        | ||||
|       assign WritePMPADDRM[i] = (CSRMWriteM & (CSRAdrM == (PMPADDR0+i))) & ~StallW & ~ADDRLocked[i]; | ||||
|       flopenr #(`XLEN) PMPADDRreg(clk, reset, WritePMPADDRM[i], CSRWriteValM, PMPADDR_ARRAY_REGW[i], initPMPADDR_ARRAY[i]); | ||||
|       flopenr #(`XLEN) PMPADDRreg(clk, reset, WritePMPADDRM[i], CSRWriteValM, PMPADDR_ARRAY_REGW[i]); | ||||
|       if (`XLEN==64) begin | ||||
|         assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+2*(i/8)))) & ~StallW & ~CFGLocked[i]; | ||||
|         flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM[(i%8)*8+7:(i%8)*8], PMPCFG_ARRAY_REGW[i], initPMPCFG_ARRAY[i]); | ||||
|         flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM[(i%8)*8+7:(i%8)*8], PMPCFG_ARRAY_REGW[i]); | ||||
|       end else begin | ||||
|         assign WritePMPCFGM[i]  = (CSRMWriteM & (CSRAdrM == (PMPCFG0+i/4))) & ~StallW & ~CFGLocked[i]; | ||||
| //        assign WritePMPCFGHM[i] = (CSRMWriteM && (CSRAdrM == PMPCFG0+2*i+1)) && ~StallW;
 | ||||
|         flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM[(i%4)*8+7:(i%4)*8], PMPCFG_ARRAY_REGW[i], initPMPCFG_ARRAY[i]); | ||||
|         flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM[(i%4)*8+7:(i%4)*8], PMPCFG_ARRAY_REGW[i]); | ||||
| //        flopenr #(`XLEN) PMPCFGHreg(clk, reset, WritePMPCFGHM[i], CSRWriteValM, PMPCFG_ARRAY_REGW[i][63:32]);
 | ||||
|       end | ||||
|     end | ||||
|  | ||||
| @ -74,30 +74,6 @@ module csrs #(parameter | ||||
|       logic WriteSSCRATCHM, WriteSEPCM; | ||||
|       logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM; | ||||
|       logic [`XLEN-1:0] SSCRATCH_REGW, SCAUSE_REGW, STVAL_REGW; | ||||
|       var [`XLEN-1:0] initSSCRATCH, initSCAUSE, initSEPC, initSTVEC, initSEDELEG, initSIDELEG, initSATP; | ||||
|       var [31:0] initSCOUNTEREN; | ||||
| 
 | ||||
|       initial begin | ||||
|       `ifdef CHECKPOINT | ||||
|         $readmemh({`LINUX_CHECKPOINT,"checkpoint-SSCRATCH.txt"}, initSSCRATCH); | ||||
|         $readmemh({`LINUX_CHECKPOINT,"checkpoint-SCAUSE.txt"}, initSCAUSE); | ||||
|         $readmemh({`LINUX_CHECKPOINT,"checkpoint-SEPC.txt"}, initSEPC); | ||||
|         $readmemh({`LINUX_CHECKPOINT,"checkpoint-STVEC.txt"}, initSTVEC); | ||||
|         $readmemh({`LINUX_CHECKPOINT,"checkpoint-SEDELEG.txt"}, initSEDELEG); | ||||
|         $readmemh({`LINUX_CHECKPOINT,"checkpoint-SIDELEG.txt"}, initSIDELEG); | ||||
|         $readmemh({`LINUX_CHECKPOINT,"checkpoint-SCOUNTEREN.txt"}, initSCOUNTEREN); | ||||
|         $readmemh({`LINUX_CHECKPOINT,"checkpoint-SATP.txt"}, initSATP); | ||||
|       `else | ||||
|         initSSCRATCH = `XLEN'b0; | ||||
|         initSCAUSE = `XLEN'b0; | ||||
|         initSEPC = `XLEN'b0; | ||||
|         initSTVEC = `XLEN'b0; | ||||
|         initSEDELEG = `XLEN'b0; | ||||
|         initSIDELEG = `XLEN'b0; | ||||
|         initSCOUNTEREN = 32'b0; | ||||
|         initSATP = `XLEN'b0; | ||||
|       `endif | ||||
|       end | ||||
|        | ||||
|       assign WriteSSTATUSM = CSRSWriteM && (CSRAdrM == SSTATUS)  && ~StallW; | ||||
|       assign WriteSTVECM = CSRSWriteM && (CSRAdrM == STVEC) && ~StallW; | ||||
| @ -109,28 +85,28 @@ module csrs #(parameter | ||||
|       assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN) && ~StallW; | ||||
| 
 | ||||
|       // CSRs
 | ||||
|       flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, initSTVEC, STVEC_REGW); //busybear: change reset to 0
 | ||||
|       flopenr #(`XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW, initSSCRATCH); | ||||
|       flopenr #(`XLEN)     SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW, initSEPC);  | ||||
|       flopenl #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, initSCAUSE, SCAUSE_REGW); | ||||
|       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, `XLEN'b0, SCAUSE_REGW); | ||||
|       if(`QEMU) assign STVAL_REGW = `XLEN'b0; | ||||
|       else flopenr #(`XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW); | ||||
|       if (`MEM_VIRTMEM) | ||||
|         flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW, initSATP); | ||||
|         flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW); | ||||
|       else | ||||
|         assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported
 | ||||
|       if (`BUSYBEAR == 1) | ||||
|         flopenl #(32)   SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, SCOUNTEREN_REGW); | ||||
|       else if (`BUILDROOT == 1) | ||||
|         flopenl #(32)   SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], initSCOUNTEREN, SCOUNTEREN_REGW); | ||||
|         flopenl #(32)   SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], 32'h0, SCOUNTEREN_REGW); | ||||
|       else | ||||
|         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 /* 12'h1FF */, initSEDELEG, SEDELEG_REGW); | ||||
|         flopenl #(`XLEN) SIDELEGreg(clk, reset, WriteSIDELEGM, CSRWriteValM, initSIDELEG, SIDELEG_REGW); | ||||
|         flopenl #(`XLEN) SEDELEGreg(clk, reset, WriteSEDELEGM, CSRWriteValM & SEDELEG_MASK /* 12'h1FF */, `XLEN'b0, SEDELEG_REGW); | ||||
|         flopenl #(`XLEN) SIDELEGreg(clk, reset, WriteSIDELEGM, CSRWriteValM, `XLEN'b0, SIDELEG_REGW); | ||||
|       end else begin | ||||
|         assign SEDELEG_REGW = 0; | ||||
|         assign SIDELEG_REGW = 0; | ||||
|  | ||||
| @ -46,15 +46,6 @@ module csrsr ( | ||||
|   logic [1:0] STATUS_SXL, STATUS_UXL, STATUS_XS, STATUS_FS, STATUS_FS_INT, STATUS_MPP_NEXT; | ||||
|   logic STATUS_MPIE, STATUS_SPIE, STATUS_UPIE, STATUS_UIE; | ||||
| 
 | ||||
|   var [`XLEN-1:0] initMSTATUS; | ||||
|   initial begin | ||||
|   `ifdef CHECKPOINT | ||||
|       $readmemh({`LINUX_CHECKPOINT,"checkpoint-MSTATUS.txt"}, initMSTATUS); | ||||
|     `else | ||||
|       initMSTATUS = `XLEN'b0; | ||||
|     `endif | ||||
|   end | ||||
| 
 | ||||
|   // STATUS REGISTER FIELD
 | ||||
|   // See Privileged Spec Section 3.1.6
 | ||||
|   // Lower privilege status registers are a subset of the full status register
 | ||||
| @ -117,33 +108,23 @@ module csrsr ( | ||||
| 
 | ||||
|   // registers for STATUS bits
 | ||||
|   // complex register with reset, write enable, and the ability to update other bits in certain cases
 | ||||
|   // these null things are needed to make the following LHS assignment legal; this is probably a crappy way of doing things
 | ||||
|   always_ff @(posedge clk, posedge reset) | ||||
|     if (reset) begin | ||||
|       //STATUS_TSR_INT <= #1 0;
 | ||||
|       //STATUS_TW_INT <= #1 0;
 | ||||
|       //STATUS_TVM_INT <= #1 0;
 | ||||
|       //STATUS_MXR_INT <= #1 0;
 | ||||
|       //STATUS_SUM_INT <= #1 0;
 | ||||
|       //STATUS_MPRV_INT <= #1 0; // Per Priv 3.3
 | ||||
|       //STATUS_FS_INT <= #1 0; //2'b01; // busybear: change all these reset values to 0
 | ||||
|       //STATUS_MPP <= #1 0; //`M_MODE;
 | ||||
|       //STATUS_SPP <= #1 0; //1'b1;
 | ||||
|       //STATUS_MPIE <= #1 0; //1;
 | ||||
|       //STATUS_SPIE <= #1 0; //`S_SUPPORTED;
 | ||||
|       //STATUS_UPIE <= #1 0; // `U_SUPPORTED;
 | ||||
|       //STATUS_MIE <= #1 0; // Per Priv 3.3
 | ||||
|       //STATUS_SIE <= #1 0; //`S_SUPPORTED;
 | ||||
|       //STATUS_UIE <= #1 0; //`U_SUPPORTED;
 | ||||
|       //
 | ||||
|       // *** this assumes XLEN == 64.
 | ||||
|       // I don't like using generates to respond to XLEN.
 | ||||
|       // I'd rather have an XLEN64 so that we could use `ifdefs -- Ben 9/21
 | ||||
|       {STATUS_TSR_INT,STATUS_TW_INT,STATUS_TVM_INT,STATUS_MXR_INT,STATUS_SUM_INT,STATUS_MPRV_INT} <= #1 initMSTATUS[22:17]; | ||||
|       {STATUS_FS_INT,STATUS_MPP} <= #1 initMSTATUS[14:11]; | ||||
|       {STATUS_SPP,STATUS_MPIE} <= #1 initMSTATUS[8:7]; | ||||
|       {STATUS_SPIE,STATUS_UPIE,STATUS_MIE} <= #1 initMSTATUS[5:3]; | ||||
|       {STATUS_SIE,STATUS_UIE} <= #1 initMSTATUS[1:0]; | ||||
|       STATUS_TSR_INT <= #1 0; | ||||
|       STATUS_TW_INT <= #1 0; | ||||
|       STATUS_TVM_INT <= #1 0; | ||||
|       STATUS_MXR_INT <= #1 0; | ||||
|       STATUS_SUM_INT <= #1 0; | ||||
|       STATUS_MPRV_INT <= #1 0; // Per Priv 3.3
 | ||||
|       STATUS_FS_INT <= #1 0; //2'b01; // busybear: change all these reset values to 0
 | ||||
|       STATUS_MPP <= #1 0; //`M_MODE;
 | ||||
|       STATUS_SPP <= #1 0; //1'b1;
 | ||||
|       STATUS_MPIE <= #1 0; //1;
 | ||||
|       STATUS_SPIE <= #1 0; //`S_SUPPORTED;
 | ||||
|       STATUS_UPIE <= #1 0; // `U_SUPPORTED;
 | ||||
|       STATUS_MIE <= #1 0; // Per Priv 3.3
 | ||||
|       STATUS_SIE <= #1 0; //`S_SUPPORTED;
 | ||||
|       STATUS_UIE <= #1 0; //`U_SUPPORTED;
 | ||||
|     end else if (~StallW) begin | ||||
|       if (FRegWriteM | WriteFRMM | WriteFFLAGSM) STATUS_FS_INT <= #12'b11; // mark Float State dirty  *** this should happen in M stage, be part of if/else;
 | ||||
|   | ||||
|  | ||||
| @ -27,9 +27,6 @@ | ||||
| 
 | ||||
| `include "wally-config.vh" | ||||
| 
 | ||||
| //`define CHECKPOINT
 | ||||
| `define LINUX_CHECKPOINT "../linux-testgen/linux-testvectors/checkpoint1K" | ||||
| 
 | ||||
| `define DEBUG_TRACE 0 | ||||
| // Debug Levels
 | ||||
| // 0: don't check against QEMU
 | ||||
| @ -411,11 +408,7 @@ module testbench(); | ||||
|   // initial loading of memories
 | ||||
|   initial begin | ||||
|     $readmemh({`LINUX_TEST_VECTORS,"bootmem.txt"}, dut.uncore.bootdtim.bootdtim.RAM, 'h1000 >> 3); | ||||
|     `ifdef CHECKPOINT | ||||
|       $readmemh({`LINUX_CHECKPOINT,"ram.txt"}, dut.uncore.dtim.RAM); | ||||
|     `else | ||||
|       $readmemh({`LINUX_TEST_VECTORS,"ram.txt"}, dut.uncore.dtim.RAM); | ||||
|     `endif | ||||
|     $readmemh({`LINUX_TEST_VECTORS,"ram.txt"}, dut.uncore.dtim.RAM); | ||||
|     $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.bpred.Predictor.DirPredictor.PHT.memory); | ||||
|     $readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.bpred.TargetPredictor.memory.memory); | ||||
|     ProgramAddrMapFile = {`LINUX_TEST_VECTORS,"vmlinux.objdump.addr"}; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user