This commit is contained in:
David Harris 2021-09-30 23:15:34 -04:00
commit 35e5a5cef3
8 changed files with 174 additions and 277 deletions

View File

@ -25,8 +25,6 @@
`include "wally-config.vh" `include "wally-config.vh"
/* verilator lint_off DECLFILENAME */ /* 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 // ordinary flip-flop
module flop #(parameter WIDTH = 8) ( module flop #(parameter WIDTH = 8) (
@ -42,11 +40,10 @@ endmodule
module flopr #(parameter WIDTH = 8) ( module flopr #(parameter WIDTH = 8) (
input logic clk, reset, input logic clk, reset,
input logic [WIDTH-1:0] d, input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q, output logic [WIDTH-1:0] q);
input var [WIDTH-1:0] RESET_VAL=0);
always_ff @(posedge clk, posedge reset) always_ff @(posedge clk, posedge reset)
if (reset) q <= #1 RESET_VAL; if (reset) q <= #1 0;
else q <= #1 d; else q <= #1 d;
endmodule endmodule
@ -64,11 +61,10 @@ endmodule
module flopenrc #(parameter WIDTH = 8) ( module flopenrc #(parameter WIDTH = 8) (
input logic clk, reset, clear, en, input logic clk, reset, clear, en,
input logic [WIDTH-1:0] d, input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q, output logic [WIDTH-1:0] q);
input var [WIDTH-1:0] RESET_VAL=0);
always_ff @(posedge clk, posedge reset) always_ff @(posedge clk, posedge reset)
if (reset) q <= #1 RESET_VAL; if (reset) q <= #1 0;
else if (en) else if (en)
if (clear) q <= #1 0; if (clear) q <= #1 0;
else q <= #1 d; else q <= #1 d;
@ -78,11 +74,10 @@ endmodule
module flopenr #(parameter WIDTH = 8) ( module flopenr #(parameter WIDTH = 8) (
input logic clk, reset, en, input logic clk, reset, en,
input logic [WIDTH-1:0] d, input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q, output logic [WIDTH-1:0] q);
input var [WIDTH-1:0] RESET_VAL=0);
always_ff @(posedge clk, posedge reset) always_ff @(posedge clk, posedge reset)
if (reset) q <= #1 RESET_VAL; if (reset) q <= #1 0;
else if (en) q <= #1 d; else if (en) q <= #1 d;
endmodule endmodule
@ -104,11 +99,10 @@ module floprc #(parameter WIDTH = 8) (
input logic reset, input logic reset,
input logic clear, input logic clear,
input logic [WIDTH-1:0] d, input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q, output logic [WIDTH-1:0] q);
input var RESET_VAL=0);
always_ff @(posedge clk, posedge reset) always_ff @(posedge clk, posedge reset)
if (reset) q <= #1 RESET_VAL; if (reset) q <= #1 0;
else else
if (clear) q <= #1 0; if (clear) q <= #1 0;
else q <= #1 d; else q <= #1 d;

View File

@ -44,13 +44,7 @@ module regfile (
// reset is intended for simulation only, not synthesis // reset is intended for simulation only, not synthesis
always_ff @(negedge clk or posedge reset) always_ff @(negedge clk or posedge reset)
if (reset) if (reset) for(i=1; i<32; i++) rf[i] <= 0;
`ifdef CHECKPOINT
$readmemh({`LINUX_CHECKPOINT,"checkpoint-regfile.txt"}, rf);
`else
for(i=1; i<32; i++) rf[i] <= 0;
`endif
else if (we3) rf[a3] <= wd3; else if (we3) rf[a3] <= wd3;
assign #2 rd1 = (a1 != 0) ? rf[a1] : 0; assign #2 rd1 = (a1 != 0) ? rf[a1] : 0;

View File

@ -70,24 +70,24 @@ module csrc #(parameter
// ... more counters // ... more counters
//HPMCOUNTER31H = 12'hC9F //HPMCOUNTER31H = 12'hC9F
) ( ) (
input logic clk, reset, input logic clk, reset,
input logic StallD, StallE, StallM, StallW, input logic StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW, input logic FlushD, FlushE, FlushM, FlushW,
input logic InstrValidM, LoadStallD, CSRMWriteM, input logic InstrValidM, LoadStallD, CSRMWriteM,
input logic BPPredDirWrongM, input logic BPPredDirWrongM,
input logic BTBPredPCWrongM, input logic BTBPredPCWrongM,
input logic RASPredPCWrongM, input logic RASPredPCWrongM,
input logic BPPredClassNonCFIWrongM, input logic BPPredClassNonCFIWrongM,
input logic [4:0] InstrClassM, input logic [4:0] InstrClassM,
input logic DCacheMiss, input logic DCacheMiss,
input logic DCacheAccess, input logic DCacheAccess,
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] CSRWriteValM, 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,
input logic [63:0] MTIME_CLINT, MTIMECMP_CLINT, input logic [63:0] MTIME_CLINT, MTIMECMP_CLINT,
output logic [`XLEN-1:0] CSRCReadValM, output logic [`XLEN-1:0] CSRCReadValM,
output logic IllegalCSRCAccessM output logic IllegalCSRCAccessM
); );
generate 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] HPMCOUNTER3_REGW, HPMCOUNTER4_REGW; // add more performance counters here if desired
logic [63:0] CYCLEPlusM, INSTRETPlusM; logic [63:0] CYCLEPlusM, INSTRETPlusM;
logic [63:0] HPMCOUNTER3PlusM, HPMCOUNTER4PlusM; 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] NextCYCLEM, NextINSTRETM;
logic [`XLEN-1:0] NextHPMCOUNTER3M, NextHPMCOUNTER4M; logic [`XLEN-1:0] NextHPMCOUNTER3M, NextHPMCOUNTER4M;
logic WriteCYCLEM, WriteINSTRETM; logic WriteCYCLEM, WriteINSTRETM;
logic WriteHPMCOUNTER3M, WriteHPMCOUNTER4M; logic WriteHPMCOUNTER3M, WriteHPMCOUNTER4M;
logic [4:0] CounterNumM; logic [4:0] CounterNumM;
logic [`COUNTERS-1:3][`XLEN-1:0] HPMCOUNTER_REGW, HPMCOUNTERH_REGW; logic [`COUNTERS-1:3][`XLEN-1:0] HPMCOUNTER_REGW, HPMCOUNTERH_REGW;
var [`COUNTERS-1:3][`XLEN-1:0] initHPMCOUNTER; logic InstrValidNotFlushedM;
logic InstrValidNotFlushedM;
initial
`ifdef CHECKPOINT
$readmemh({`LINUX_CHECKPOINT,"checkpoint-HPMCOUNTER.txt"}, initHPMCOUNTER);
`else
initHPMCOUNTER = {(`COUNTERS-3){`XLEN'b0}};
`endif
assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW; assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW;
@ -138,116 +130,121 @@ module csrc #(parameter
//assign NextHPMCOUNTER3M = WriteHPMCOUNTER3M ? CSRWriteValM : HPMCOUNTER3PlusM[`XLEN-1:0]; //assign NextHPMCOUNTER3M = WriteHPMCOUNTER3M ? CSRWriteValM : HPMCOUNTER3PlusM[`XLEN-1:0];
//assign NextHPMCOUNTER4M = WriteHPMCOUNTER4M ? CSRWriteValM : HPMCOUNTER4PlusM[`XLEN-1:0]; //assign NextHPMCOUNTER4M = WriteHPMCOUNTER4M ? CSRWriteValM : HPMCOUNTER4PlusM[`XLEN-1:0];
// parameterized number of additional counters // parameterized number of additional counters
if (`COUNTERS > 3) begin if (`COUNTERS > 3) begin
logic [`COUNTERS-1:3] WriteHPMCOUNTERM; logic [`COUNTERS-1:3] WriteHPMCOUNTERM;
logic [`COUNTERS-1:0] CounterEvent; logic [`COUNTERS-1:0] CounterEvent;
logic [63:0] /*HPMCOUNTER_REGW[`COUNTERS-1:3], */ HPMCOUNTERPlusM[`COUNTERS-1:3]; logic [63:0] /*HPMCOUNTER_REGW[`COUNTERS-1:3], */ HPMCOUNTERPlusM[`COUNTERS-1:3];
logic [`XLEN-1:0] NextHPMCOUNTERM[`COUNTERS-1:3]; logic [`XLEN-1:0] NextHPMCOUNTERM[`COUNTERS-1:3];
genvar i; genvar i;
// could replace special counters 0-2 with this loop for all counters // could replace special counters 0-2 with this loop for all counters
assign CounterEvent[0] = 1'b1; assign CounterEvent[0] = 1'b1;
assign CounterEvent[1] = 1'b0; assign CounterEvent[1] = 1'b0;
if(`QEMU) assign CounterEvent[`COUNTERS-1:2] = 0; if(`QEMU) begin
else begin assign CounterEvent[`COUNTERS-1:2] = 0;
logic LoadStallE, LoadStallM; end else begin
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 (`XLEN==32) begin logic LoadStallE, LoadStallM;
logic [`COUNTERS-1:3] WriteHPMCOUNTERHM;
logic [`XLEN-1:0] NextHPMCOUNTERHM[`COUNTERS-1:3]; flopenrc #(1) LoadStallEReg(.clk, .reset, .clear(FlushE), .en(~StallE), .d(LoadStallD), .q(LoadStallE));
assign HPMCOUNTERPlusM[i] = {HPMCOUNTERH_REGW[i], HPMCOUNTER_REGW[i]} + {63'b0, CounterEvent[i] & ~MCOUNTINHIBIT_REGW[i]}; flopenrc #(1) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d(LoadStallE), .q(LoadStallM));
assign WriteHPMCOUNTERHM[i] = CSRMWriteM && (CSRAdrM == MHPMCOUNTERHBASE + i);
assign NextHPMCOUNTERHM[i] = WriteHPMCOUNTERHM[i] ? CSRWriteValM : HPMCOUNTERPlusM[i][63:32]; assign CounterEvent[2] = InstrValidNotFlushedM;
always @(posedge clk, posedge reset) // ModelSim doesn't like syntax of passing array element to flop assign CounterEvent[3] = LoadStallM & InstrValidNotFlushedM;
if (reset) HPMCOUNTERH_REGW[i][`XLEN-1:0] <= #1 0; assign CounterEvent[4] = BPPredDirWrongM & InstrValidNotFlushedM;
else if (~StallW) HPMCOUNTERH_REGW[i][`XLEN-1:0] <= #1 NextHPMCOUNTERHM[i]; assign CounterEvent[5] = InstrClassM[0] & InstrValidNotFlushedM;
//flopr #(`XLEN) HPMCOUNTERHreg[i](clk, reset, NextHPMCOUNTERHM[i], HPMCOUNTER_REGW[i][63:32]); assign CounterEvent[6] = BTBPredPCWrongM & InstrValidNotFlushedM;
end else begin assign CounterEvent[7] = (InstrClassM[4] | InstrClassM[2] | InstrClassM[1]) & InstrValidNotFlushedM;
assign HPMCOUNTERPlusM[i] = HPMCOUNTER_REGW[i] + {63'b0, CounterEvent[i] & ~MCOUNTINHIBIT_REGW[i]}; assign CounterEvent[8] = RASPredPCWrongM & InstrValidNotFlushedM;
end assign CounterEvent[9] = InstrClassM[3] & InstrValidNotFlushedM;
end 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 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 // Write / update counters
// Only the Machine mode versions of the counter CSRs are writable // Only the Machine mode versions of the counter CSRs are writable
if (`XLEN==64) begin// 64-bit counters 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*** // 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); // flopenr #(64) TIMECMPreg(clk, reset, WriteTIMECMPM, CSRWriteValM, TIMECMP_REGW);
flopr #(64) CYCLEreg(clk, reset, NextCYCLEM, CYCLE_REGW); flopr #(64) CYCLEreg(clk, reset, NextCYCLEM, CYCLE_REGW);
flopr #(64) INSTRETreg(clk, reset, NextINSTRETM, INSTRET_REGW); flopr #(64) INSTRETreg(clk, reset, NextINSTRETM, INSTRET_REGW);
//flopr #(64) HPMCOUNTER3reg(clk, reset, NextHPMCOUNTER3M, HPMCOUNTER3_REGW); //flopr #(64) HPMCOUNTER3reg(clk, reset, NextHPMCOUNTER3M, HPMCOUNTER3_REGW);
//flopr #(64) HPMCOUNTER4reg(clk, reset, NextHPMCOUNTER4M, HPMCOUNTER4_REGW); //flopr #(64) HPMCOUNTER4reg(clk, reset, NextHPMCOUNTER4M, HPMCOUNTER4_REGW);
end else begin // 32-bit low and high counters end else begin // 32-bit low and high counters
logic WriteTIMEHM, WriteTIMECMPHM, WriteCYCLEHM, WriteINSTRETHM; logic WriteTIMEHM, WriteTIMECMPHM, WriteCYCLEHM, WriteINSTRETHM;
//logic WriteHPMCOUNTER3HM, WriteHPMCOUNTER4HM; //logic WriteHPMCOUNTER3HM, WriteHPMCOUNTER4HM;
logic [`XLEN-1:0] NextCYCLEHM, NextTIMEHM, NextINSTRETHM; logic [`XLEN-1:0] NextCYCLEHM, NextTIMEHM, NextINSTRETHM;
//logic [`XLEN-1:0] NextHPMCOUNTER3HM, NextHPMCOUNTER4HM; //logic [`XLEN-1:0] NextHPMCOUNTER3HM, NextHPMCOUNTER4HM;
// Write Enables // Write Enables
// assign WriteTIMEHM = CSRMWriteM && (CSRAdrM == MTIMEH); // assign WriteTIMEHM = CSRMWriteM && (CSRAdrM == MTIMEH);
// assign WriteTIMECMPHM = CSRMWriteM && (CSRAdrM == MTIMECMPH); // assign WriteTIMECMPHM = CSRMWriteM && (CSRAdrM == MTIMECMPH);
assign WriteCYCLEHM = CSRMWriteM && (CSRAdrM == MCYCLEH); assign WriteCYCLEHM = CSRMWriteM && (CSRAdrM == MCYCLEH);
assign WriteINSTRETHM = CSRMWriteM && (CSRAdrM == MINSTRETH); assign WriteINSTRETHM = CSRMWriteM && (CSRAdrM == MINSTRETH);
//assign WriteHPMCOUNTER3HM = CSRMWriteM && (CSRAdrM == MHPMCOUNTER3H); //assign WriteHPMCOUNTER3HM = CSRMWriteM && (CSRAdrM == MHPMCOUNTER3H);
//assign WriteHPMCOUNTER4HM = CSRMWriteM && (CSRAdrM == MHPMCOUNTER4H); //assign WriteHPMCOUNTER4HM = CSRMWriteM && (CSRAdrM == MHPMCOUNTER4H);
assign NextCYCLEHM = WriteCYCLEM ? CSRWriteValM : CYCLEPlusM[63:32]; assign NextCYCLEHM = WriteCYCLEM ? CSRWriteValM : CYCLEPlusM[63:32];
// assign NextTIMEHM = WriteTIMEHM ? CSRWriteValM : TIMEPlusM[63:32]; // assign NextTIMEHM = WriteTIMEHM ? CSRWriteValM : TIMEPlusM[63:32];
assign NextINSTRETHM = WriteINSTRETHM ? CSRWriteValM : INSTRETPlusM[63:32]; assign NextINSTRETHM = WriteINSTRETHM ? CSRWriteValM : INSTRETPlusM[63:32];
//assign NextHPMCOUNTER3HM = WriteHPMCOUNTER3HM ? CSRWriteValM : HPMCOUNTER3PlusM[63:32]; //assign NextHPMCOUNTER3HM = WriteHPMCOUNTER3HM ? CSRWriteValM : HPMCOUNTER3PlusM[63:32];
//assign NextHPMCOUNTER4HM = WriteHPMCOUNTER4HM ? CSRWriteValM : HPMCOUNTER4PlusM[63:32]; //assign NextHPMCOUNTER4HM = WriteHPMCOUNTER4HM ? CSRWriteValM : HPMCOUNTER4PlusM[63:32];
// Counter CSRs // Counter CSRs
// flopr #(32) TIMEreg(clk, reset, NextTIMEM, TIME_REGW); // may count off a different clock*** // 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]); // flopenr #(32) TIMECMPreg(clk, reset, WriteTIMECMPM, CSRWriteValM, TIMECMP_REGW[31:0]);
flopr #(32) CYCLEreg(clk, reset, NextCYCLEM, CYCLE_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) INSTRETreg(clk, reset, NextINSTRETM, INSTRET_REGW[31:0]);
// flopr #(32) HPMCOUNTER3reg(clk, reset, NextHPMCOUNTER3M, HPMCOUNTER3_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) HPMCOUNTER4reg(clk, reset, NextHPMCOUNTER4M, HPMCOUNTER4_REGW[31:0]);
// flopr #(32) TIMEHreg(clk, reset, NextTIMEHM, TIME_REGW); // may count off a different clock*** // 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]); // flopenr #(32) TIMECMPHreg(clk, reset, WriteTIMECMPHM, CSRWriteValM, TIMECMP_REGW[63:32]);
flopr #(32) CYCLEHreg(clk, reset, NextCYCLEHM, CYCLE_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) INSTRETHreg(clk, reset, NextINSTRETHM, INSTRET_REGW[63:32]);
//flopr #(32) HPMCOUNTER3Hreg(clk, reset, NextHPMCOUNTER3HM, HPMCOUNTER3_REGW[63:32]); //flopr #(32) HPMCOUNTER3Hreg(clk, reset, NextHPMCOUNTER3HM, HPMCOUNTER3_REGW[63:32]);
//flopr #(32) HPMCOUNTER4Hreg(clk, reset, NextHPMCOUNTER4HM, HPMCOUNTER4_REGW[63:32]); //flopr #(32) HPMCOUNTER4Hreg(clk, reset, NextHPMCOUNTER4HM, HPMCOUNTER4_REGW[63:32]);
end end
// eventually move TIME and TIMECMP to the CLINT -- Ben 06/17/21: sure let's give that a shot! // 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 // run TIME off asynchronous reference clock
// synchronize write enable to TIME // synchronize write enable to TIME
// four phase handshake to synchronize reads from TIME // four phase handshake to synchronize reads from TIME
// interrupt on timer compare // interrupt on timer compare
// ability to disable optional CSRs // ability to disable optional CSRs
// Read Counters, or cause excepiton if insufficient privilege in light of COUNTEREN flags // Read Counters, or cause excepiton if insufficient privilege in light of COUNTEREN flags
assign CounterNumM = CSRAdrM[4:0]; // which counter to read? assign CounterNumM = CSRAdrM[4:0]; // which counter to read?
if (`XLEN==64) // 64-bit counter reads if (`XLEN==64) // 64-bit counter reads
always_comb 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; IllegalCSRCAccessM = 0;
if (CSRAdrM >= MHPMCOUNTERBASE+3 && CSRAdrM < MHPMCOUNTERBASE+`COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CSRAdrM-MHPMCOUNTERBASE]; if (CSRAdrM >= MHPMCOUNTERBASE+3 && CSRAdrM < MHPMCOUNTERBASE+`COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CSRAdrM-MHPMCOUNTERBASE];
else if (CSRAdrM >= HPMCOUNTERBASE+3 && CSRAdrM < HPMCOUNTERBASE+`COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CSRAdrM-HPMCOUNTERBASE]; else if (CSRAdrM >= HPMCOUNTERBASE+3 && CSRAdrM < HPMCOUNTERBASE+`COUNTERS) CSRCReadValM = HPMCOUNTER_REGW[CSRAdrM-HPMCOUNTERBASE];
@ -312,7 +309,7 @@ module csrc #(parameter
IllegalCSRCAccessM = 1; // no privileges for this csr IllegalCSRCAccessM = 1; // no privileges for this csr
CSRCReadValM = 0; CSRCReadValM = 0;
end end
end else begin // not `ZICOUNTERS_SUPPORTED end else begin
assign CSRCReadValM = 0; assign CSRCReadValM = 0;
assign IllegalCSRCAccessM = 1; assign IllegalCSRCAccessM = 1;
end end
@ -359,20 +356,20 @@ module csrc #(parameter
MPHMEVENTBASE = 12'h320, MPHMEVENTBASE = 12'h320,
HPMCOUNTERBASE = 12'hC00, HPMCOUNTERBASE = 12'hC00,
HPMCOUNTERHBASE = 12'hC80, HPMCOUNTERHBASE = 12'hC80,
)(input logic clk, reset, )(input logic clk, reset,
input logic StallD, StallE, StallM, StallW, input logic StallD, StallE, StallM, StallW,
input logic InstrValidM, LoadStallD, CSRMWriteM, input logic InstrValidM, LoadStallD, CSRMWriteM,
input logic BPPredDirWrongM, input logic BPPredDirWrongM,
input logic BTBPredPCWrongM, input logic BTBPredPCWrongM,
input logic RASPredPCWrongM, input logic RASPredPCWrongM,
input logic BPPredClassNonCFIWrongM, input logic BPPredClassNonCFIWrongM,
input logic [4:0] InstrClassM, input logic [4:0] InstrClassM,
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] CSRWriteValM, 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 [`XLEN-1:0] CSRCReadValM,
output logic IllegalCSRCAccessM); output logic IllegalCSRCAccessM);
// counters // counters

View File

@ -79,24 +79,14 @@ module csri #(parameter
assign SIP_WRITE_MASK = 12'h000; assign SIP_WRITE_MASK = 12'h000;
end end
always @(posedge clk, posedge reset) begin // *** I strongly feel that IntInM should go directly to IP_REGW -- Ben 9/7/21 always @(posedge clk, posedge reset) begin // *** I strongly feel that IntInM should go directly to IP_REGW -- Ben 9/7/21
if (reset) if (reset) IP_REGW_writeable <= 10'b0;
`ifdef CHECKPOINT
$readmemh({`LINUX_CHECKPOINT,"checkpoint-MIP.txt"}, IP_REGW_writeable);
`else
IP_REGW_writeable <= 10'b0;
`endif
else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | IntInM[9:0]; // MTIP unclearable 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 (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 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 else IP_REGW_writeable <= IP_REGW_writeable | IntInM[9:0]; // *** check this turns off interrupts properly even when MIDELEG changes
end end
always @(posedge clk, posedge reset) begin always @(posedge clk, posedge reset) begin
if (reset) if (reset) IE_REGW <= 12'b0;
`ifdef CHECKPOINT
$readmemh({`LINUX_CHECKPOINT,"checkpoint-MIE.txt"}, IE_REGW);
`else
IE_REGW <= 12'b0;
`endif
else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields
else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields else if (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 // else if (WriteUIEM) IE_REGW = (CSRWriteValM & 12'h111) | (IE_REGW & 12'hAAA); // only U field

View File

@ -85,45 +85,15 @@ module csrm #(parameter
logic [`XLEN-1:0] MISA_REGW, MHARTID_REGW; logic [`XLEN-1:0] MISA_REGW, MHARTID_REGW;
logic [`XLEN-1:0] MSCRATCH_REGW, MCAUSE_REGW, MTVAL_REGW; logic [`XLEN-1:0] MSCRATCH_REGW, MCAUSE_REGW, MTVAL_REGW;
var [`XLEN-1:0] initMSCRATCH, initMCAUSE, initMEPC, initMTVEC, initMEDELEG, initMIDELEG; logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
var [31:0] initMCOUNTEREN, initMCOUNTINHIBIT; logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
var [`PMP_ENTRIES-1:0][7:0] initPMPCFG_ARRAY; logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
var [`PMP_ENTRIES-1:0][`XLEN-1:0] initPMPADDR_ARRAY;
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
logic [`PMP_ENTRIES-1:0] WritePMPCFGM; logic [`PMP_ENTRIES-1:0] WritePMPCFGM;
logic [`PMP_ENTRIES-1:0] WritePMPADDRM ; logic [`PMP_ENTRIES-1:0] WritePMPADDRM ;
logic [`PMP_ENTRIES-1:0] ADDRLocked, CFGLocked; logic [`PMP_ENTRIES-1:0] ADDRLocked, CFGLocked;
localparam MISA_26 = (`MISA) & 32'h03ffffff; 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 // 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]}; 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); assign IllegalCSRMWriteReadonlyM = CSRMWriteM && (CSRAdrM == MVENDORID || CSRAdrM == MARCHID || CSRAdrM == MIMPID || CSRAdrM == MHARTID);
// CSRs // 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 generate
if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin // DELEG registers should exist 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) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK /*12'h7FF*/, `XLEN'b0, MEDELEG_REGW);
flopenl #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, initMIDELEG, MIDELEG_REGW); flopenl #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, `XLEN'b0, MIDELEG_REGW);
end else begin end else begin
assign MEDELEG_REGW = 0; assign MEDELEG_REGW = 0;
assign MIDELEG_REGW = 0; assign MIDELEG_REGW = 0;
end end
endgenerate endgenerate
flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW, initMSCRATCH); // flopenl #(`XLEN) MIPreg(clk, reset, WriteMIPM, CSRWriteValM, zero, MIP_REGW);
flopenr #(`XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW, initMEPC); // flopenl #(`XLEN) MIEreg(clk, reset, WriteMIEM, CSRWriteValM, zero, MIE_REGW);
flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW, initMCAUSE); 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; if(`QEMU) assign MTVAL_REGW = `XLEN'b0;
else flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW); else flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW);
generate generate
if (`BUSYBEAR == 1) if (`BUSYBEAR == 1)
flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, MCOUNTEREN_REGW); flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, MCOUNTEREN_REGW);
else if (`BUILDROOT == 1) 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 else
flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], 32'hFFFFFFFF, MCOUNTEREN_REGW); flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], 32'hFFFFFFFF, MCOUNTEREN_REGW);
endgenerate 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 // 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 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]; 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 if (`XLEN==64) begin
assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+2*(i/8)))) & ~StallW & ~CFGLocked[i]; 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 end else begin
assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+i/4))) & ~StallW & ~CFGLocked[i]; assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+i/4))) & ~StallW & ~CFGLocked[i];
// assign WritePMPCFGHM[i] = (CSRMWriteM && (CSRAdrM == PMPCFG0+2*i+1)) && ~StallW; // 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]); // flopenr #(`XLEN) PMPCFGHreg(clk, reset, WritePMPCFGHM[i], CSRWriteValM, PMPCFG_ARRAY_REGW[i][63:32]);
end end
end end

View File

@ -74,30 +74,6 @@ module csrs #(parameter
logic WriteSSCRATCHM, WriteSEPCM; logic WriteSSCRATCHM, WriteSEPCM;
logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM; logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM;
logic [`XLEN-1:0] SSCRATCH_REGW, SCAUSE_REGW, STVAL_REGW; 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 WriteSSTATUSM = CSRSWriteM && (CSRAdrM == SSTATUS) && ~StallW;
assign WriteSTVECM = CSRSWriteM && (CSRAdrM == STVEC) && ~StallW; assign WriteSTVECM = CSRSWriteM && (CSRAdrM == STVEC) && ~StallW;
@ -109,28 +85,28 @@ module csrs #(parameter
assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN) && ~StallW; assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN) && ~StallW;
// CSRs // CSRs
flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, initSTVEC, STVEC_REGW); //busybear: change reset to 0 flopenl #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, `XLEN'b0, STVEC_REGW); //busybear: change reset to 0
flopenr #(`XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW, initSSCRATCH); flopenr #(`XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW);
flopenr #(`XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW, initSEPC); flopenr #(`XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW);
flopenl #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, initSCAUSE, SCAUSE_REGW); flopenl #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, `XLEN'b0, SCAUSE_REGW);
if(`QEMU) assign STVAL_REGW = `XLEN'b0; if(`QEMU) assign STVAL_REGW = `XLEN'b0;
else flopenr #(`XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW); else flopenr #(`XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW);
if (`MEM_VIRTMEM) if (`MEM_VIRTMEM)
flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW, initSATP); flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW);
else else
assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported
if (`BUSYBEAR == 1) if (`BUSYBEAR == 1)
flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, SCOUNTEREN_REGW); flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, 32'b0, SCOUNTEREN_REGW);
else if (`BUILDROOT == 1) 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 else
flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], 32'hFFFFFFFF, SCOUNTEREN_REGW); flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], 32'hFFFFFFFF, SCOUNTEREN_REGW);
if (`N_SUPPORTED) begin if (`N_SUPPORTED) begin
logic WriteSEDELEGM, WriteSIDELEGM; logic WriteSEDELEGM, WriteSIDELEGM;
assign WriteSEDELEGM = CSRSWriteM && (CSRAdrM == SEDELEG); assign WriteSEDELEGM = CSRSWriteM && (CSRAdrM == SEDELEG);
assign WriteSIDELEGM = CSRSWriteM && (CSRAdrM == SIDELEG); assign WriteSIDELEGM = CSRSWriteM && (CSRAdrM == SIDELEG);
flopenl #(`XLEN) SEDELEGreg(clk, reset, WriteSEDELEGM, CSRWriteValM & SEDELEG_MASK /* 12'h1FF */, initSEDELEG, SEDELEG_REGW); flopenl #(`XLEN) SEDELEGreg(clk, reset, WriteSEDELEGM, CSRWriteValM & SEDELEG_MASK /* 12'h1FF */, `XLEN'b0, SEDELEG_REGW);
flopenl #(`XLEN) SIDELEGreg(clk, reset, WriteSIDELEGM, CSRWriteValM, initSIDELEG, SIDELEG_REGW); flopenl #(`XLEN) SIDELEGreg(clk, reset, WriteSIDELEGM, CSRWriteValM, `XLEN'b0, SIDELEG_REGW);
end else begin end else begin
assign SEDELEG_REGW = 0; assign SEDELEG_REGW = 0;
assign SIDELEG_REGW = 0; assign SIDELEG_REGW = 0;

View File

@ -46,15 +46,6 @@ module csrsr (
logic [1:0] STATUS_SXL, STATUS_UXL, STATUS_XS, STATUS_FS, STATUS_FS_INT, STATUS_MPP_NEXT; 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; 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 // STATUS REGISTER FIELD
// See Privileged Spec Section 3.1.6 // See Privileged Spec Section 3.1.6
// Lower privilege status registers are a subset of the full status register // Lower privilege status registers are a subset of the full status register
@ -117,33 +108,23 @@ module csrsr (
// registers for STATUS bits // registers for STATUS bits
// complex register with reset, write enable, and the ability to update other bits in certain cases // 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) always_ff @(posedge clk, posedge reset)
if (reset) begin if (reset) begin
//STATUS_TSR_INT <= #1 0; STATUS_TSR_INT <= #1 0;
//STATUS_TW_INT <= #1 0; STATUS_TW_INT <= #1 0;
//STATUS_TVM_INT <= #1 0; STATUS_TVM_INT <= #1 0;
//STATUS_MXR_INT <= #1 0; STATUS_MXR_INT <= #1 0;
//STATUS_SUM_INT <= #1 0; STATUS_SUM_INT <= #1 0;
//STATUS_MPRV_INT <= #1 0; // Per Priv 3.3 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_FS_INT <= #1 0; //2'b01; // busybear: change all these reset values to 0
//STATUS_MPP <= #1 0; //`M_MODE; STATUS_MPP <= #1 0; //`M_MODE;
//STATUS_SPP <= #1 0; //1'b1; STATUS_SPP <= #1 0; //1'b1;
//STATUS_MPIE <= #1 0; //1; STATUS_MPIE <= #1 0; //1;
//STATUS_SPIE <= #1 0; //`S_SUPPORTED; STATUS_SPIE <= #1 0; //`S_SUPPORTED;
//STATUS_UPIE <= #1 0; // `U_SUPPORTED; STATUS_UPIE <= #1 0; // `U_SUPPORTED;
//STATUS_MIE <= #1 0; // Per Priv 3.3 STATUS_MIE <= #1 0; // Per Priv 3.3
//STATUS_SIE <= #1 0; //`S_SUPPORTED; STATUS_SIE <= #1 0; //`S_SUPPORTED;
//STATUS_UIE <= #1 0; //`U_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];
end else if (~StallW) begin 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; if (FRegWriteM | WriteFRMM | WriteFFLAGSM) STATUS_FS_INT <= #12'b11; // mark Float State dirty *** this should happen in M stage, be part of if/else;

View File

@ -27,9 +27,6 @@
`include "wally-config.vh" `include "wally-config.vh"
//`define CHECKPOINT
`define LINUX_CHECKPOINT "../linux-testgen/linux-testvectors/checkpoint1K"
`define DEBUG_TRACE 0 `define DEBUG_TRACE 0
// Debug Levels // Debug Levels
// 0: don't check against QEMU // 0: don't check against QEMU
@ -411,11 +408,7 @@ module testbench();
// initial loading of memories // initial loading of memories
initial begin initial begin
$readmemh({`LINUX_TEST_VECTORS,"bootmem.txt"}, dut.uncore.bootdtim.bootdtim.RAM, 'h1000 >> 3); $readmemh({`LINUX_TEST_VECTORS,"bootmem.txt"}, dut.uncore.bootdtim.bootdtim.RAM, 'h1000 >> 3);
`ifdef CHECKPOINT $readmemh({`LINUX_TEST_VECTORS,"ram.txt"}, dut.uncore.dtim.RAM);
$readmemh({`LINUX_CHECKPOINT,"ram.txt"}, dut.uncore.dtim.RAM);
`else
$readmemh({`LINUX_TEST_VECTORS,"ram.txt"}, dut.uncore.dtim.RAM);
`endif
$readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.bpred.Predictor.DirPredictor.PHT.memory); $readmemb(`TWO_BIT_PRELOAD, dut.hart.ifu.bpred.bpred.Predictor.DirPredictor.PHT.memory);
$readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.bpred.TargetPredictor.memory.memory); $readmemb(`BTB_PRELOAD, dut.hart.ifu.bpred.bpred.TargetPredictor.memory.memory);
ProgramAddrMapFile = {`LINUX_TEST_VECTORS,"vmlinux.objdump.addr"}; ProgramAddrMapFile = {`LINUX_TEST_VECTORS,"vmlinux.objdump.addr"};