This commit is contained in:
bbracker 2021-07-19 17:11:49 -04:00
commit c8203c171e
6 changed files with 52 additions and 32 deletions

View File

@ -23,11 +23,11 @@ TestCase = namedtuple("TestCase", ['name', 'cmd', 'grepstr'])
# edit this list to add more test cases # edit this list to add more test cases
configs = [ configs = [
TestCase( #TestCase(
name="busybear", # name="busybear",
cmd="vsim -do wally-busybear-batch.do -c > {}", # cmd="vsim -do wally-busybear-batch.do -c > {}",
grepstr="loaded 100000 instructions" # grepstr="loaded 100000 instructions"
), #),
TestCase( TestCase(
name="buildroot", name="buildroot",
cmd="vsim -do wally-buildroot-batch.do -c > {}", cmd="vsim -do wally-buildroot-batch.do -c > {}",

View File

@ -34,9 +34,10 @@ module pmpadrdec (
input logic [7:0] PMPCfg, input logic [7:0] PMPCfg,
input logic [`XLEN-1:0] PMPAdr, input logic [`XLEN-1:0] PMPAdr,
input logic PAgePMPAdrIn, input logic PAgePMPAdrIn,
input logic NoLowerMatchIn, // input logic NoLowerMatchIn,
input logic FirstMatch,
output logic PAgePMPAdrOut, output logic PAgePMPAdrOut,
output logic NoLowerMatchOut, // output logic NoLowerMatchOut,
output logic Match, Active, output logic Match, Active,
output logic L, X, W, R output logic L, X, W, R
); );
@ -47,7 +48,7 @@ module pmpadrdec (
logic TORMatch, NAMatch; logic TORMatch, NAMatch;
logic PAltPMPAdr; logic PAltPMPAdr;
logic FirstMatch; // logic FirstMatch;
logic [`PA_BITS-1:0] CurrentAdrFull; logic [`PA_BITS-1:0] CurrentAdrFull;
logic [1:0] AdrMode; logic [1:0] AdrMode;
@ -69,16 +70,30 @@ module pmpadrdec (
// verilator lint_off UNOPTFLAT // verilator lint_off UNOPTFLAT
logic [`PA_BITS-1:0] Mask; logic [`PA_BITS-1:0] Mask;
genvar i; //genvar i;
// create a mask of which bits to ignore // create a mask of which bits to ignore
generate // generate
assign Mask[1:0] = 2'b11; // assign Mask[1:0] = 2'b11;
assign Mask[2] = (AdrMode == NAPOT); // mask has 0s in upper bis for NA4 region // assign Mask[2] = (AdrMode == NAPOT); // mask has 0s in upper bis for NA4 region
for (i=3; i < `PA_BITS; i=i+1) begin:mask // for (i=3; i < `PA_BITS; i=i+1) begin:mask
assign Mask[i] = Mask[i-1] & PMPAdr[i-3]; // NAPOT mask: 1's indicate bits to ignore // assign Mask[i] = Mask[i-1] & PMPAdr[i-3]; // NAPOT mask: 1's indicate bits to ignore
end // end
endgenerate // endgenerate
prioritycircuit #(.ENTRIES(`PA_BITS-2), .FINAL_OP("NONE")) maskgen(.a(~PMPAdr[`PA_BITS-3:0]), .FirstPin(AdrMode==NAPOT), .y(Mask[`PA_BITS-1:2]));
assign Mask[1:0] = 2'b11;
// *** possible experiments:
/* PA < PMP addr could be in its own module,
preeserving hierarchy so we can know if this is the culprit on the critical path
Should take logarthmic time, so more like 6 levels than 40 should be expected
update mask generation
Should be concurrent with the subtraction/comparison
if one is the critical path, the other shouldn't be which makes us think the mask generation is the culprit.
Hopefully just use the priority circuit here
*/
// verilator lint_on UNOPTFLAT // verilator lint_on UNOPTFLAT
assign NAMatch = &((PhysicalAddress ~^ CurrentAdrFull) | Mask); assign NAMatch = &((PhysicalAddress ~^ CurrentAdrFull) | Mask);
@ -87,8 +102,6 @@ module pmpadrdec (
(AdrMode == NA4 || AdrMode == NAPOT) ? NAMatch : (AdrMode == NA4 || AdrMode == NAPOT) ? NAMatch :
0; 0;
assign FirstMatch = NoLowerMatchIn & Match;
assign NoLowerMatchOut = NoLowerMatchIn & ~Match;
assign L = PMPCfg[7] & FirstMatch; assign L = PMPCfg[7] & FirstMatch;
assign X = PMPCfg[2] & FirstMatch; assign X = PMPCfg[2] & FirstMatch;
assign W = PMPCfg[1] & FirstMatch; assign W = PMPCfg[1] & FirstMatch;

View File

@ -55,12 +55,9 @@ module pmpchecker (
// Bit i is high when the address falls in PMP region i // Bit i is high when the address falls in PMP region i
logic EnforcePMP; logic EnforcePMP;
logic [7:0] PMPCfg[`PMP_ENTRIES-1:0]; logic [7:0] PMPCfg[`PMP_ENTRIES-1:0];
logic [`PMP_ENTRIES-1:0] Match; // PMP Entry matches logic [`PMP_ENTRIES-1:0] Match, FirstMatch; // PMP Entry matches
logic [`PMP_ENTRIES-1:0] Active; // PMP register i is non-null logic [`PMP_ENTRIES-1:0] Active; // PMP register i is non-null
logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set
// verilator lint_off UNOPTFLAT
logic [`PMP_ENTRIES-1:0] NoLowerMatch; // None of the lower PMP entries match
// verilator lint_on UNOPTFLAT
logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i] logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
genvar i,j; genvar i,j;
@ -70,9 +67,9 @@ module pmpchecker (
.PMPAdr(PMPADDR_ARRAY_REGW), .PMPAdr(PMPADDR_ARRAY_REGW),
.PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}), .PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}),
.PAgePMPAdrOut(PAgePMPAdr), .PAgePMPAdrOut(PAgePMPAdr),
.NoLowerMatchIn({NoLowerMatch[`PMP_ENTRIES-2:0], 1'b1}), .FirstMatch, .Match, .Active, .L, .X, .W, .R);
.NoLowerMatchOut(NoLowerMatch),
.Match, .Active, .L, .X, .W, .R); prioritycircuit #(.ENTRIES(`PMP_ENTRIES), .FINAL_OP("AND")) pmppriority(.a(Match), .FirstPin(1'b1), .y(FirstMatch)); // Take the ripple gates/signals out of the pmpadrdec and into another unit.
// Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region // Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region
assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |L : |Active; assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |L : |Active;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// tlbpriority.sv // prioritycircuit.sv
// //
// Written: tfleming@hmc.edu & jtorrey@hmc.edu 7 April 2021 // Written: tfleming@hmc.edu & jtorrey@hmc.edu 7 April 2021
// Modified: Teo Ene 15 Apr 2021: // Modified: Teo Ene 15 Apr 2021:
@ -30,8 +30,10 @@
`include "wally-config.vh" `include "wally-config.vh"
module tlbpriority #(parameter ENTRIES = 8) ( module prioritycircuit #(parameter ENTRIES = 8,
parameter FINAL_OP = "AND") (
input logic [ENTRIES-1:0] a, input logic [ENTRIES-1:0] a,
input logic FirstPin,
output logic [ENTRIES-1:0] y output logic [ENTRIES-1:0] y
); );
// verilator lint_off UNOPTFLAT // verilator lint_off UNOPTFLAT
@ -40,11 +42,19 @@ module tlbpriority #(parameter ENTRIES = 8) (
// generate thermometer code mask // generate thermometer code mask
genvar i; genvar i;
generate generate
assign nolower[0] = 1; assign nolower[0] = FirstPin;
for (i=1; i<ENTRIES; i++) begin:therm for (i=1; i<ENTRIES; i++) begin:therm
assign nolower[i] = nolower[i-1] & ~a[i-1]; assign nolower[i] = nolower[i-1] & ~a[i-1];
end end
endgenerate endgenerate
// verilator lint_on UNOPTFLAT // verilator lint_on UNOPTFLAT
assign y = a & nolower;
generate
if (FINAL_OP=="AND") begin
assign y = a & nolower;
end else if (FINAL_OP=="NONE") begin
assign y = nolower;
end // *** So far these are the only two operations I need to do at the end, but feel free to add more as needed.
endgenerate
// assign y = a & nolower;
endmodule endmodule

View File

@ -39,7 +39,7 @@ module tlblru #(parameter TLB_ENTRIES = 8) (
logic AllUsed; // High if the next access causes all RU bits to be 1 logic AllUsed; // High if the next access causes all RU bits to be 1
// Find the first line not recently used // Find the first line not recently used
tlbpriority #(TLB_ENTRIES) nru(~RUBits, WriteLines); prioritycircuit #(.ENTRIES(TLB_ENTRIES), .FINAL_OP("AND")) nru(.a(~RUBits), .FirstPin(1'b1), .y(WriteLines));
// Track recently used lines, updating on a CAM Hit or TLB write // Track recently used lines, updating on a CAM Hit or TLB write
assign WriteEnables = WriteLines & {(TLB_ENTRIES){TLBWrite}}; assign WriteEnables = WriteLines & {(TLB_ENTRIES){TLBWrite}};

View File

@ -82,7 +82,7 @@ module clint (
always_ff @(posedge HCLK or negedge HRESETn) always_ff @(posedge HCLK or negedge HRESETn)
if (~HRESETn) begin if (~HRESETn) begin
MSIP <= 0; MSIP <= 0;
MTIMECMP <= (64)'(-1); MTIMECMP <= (64)'(0);
// MTIMECMP is not reset // MTIMECMP is not reset
end else if (memwrite) begin end else if (memwrite) begin
if (entryd == 16'h0000) MSIP <= HWDATA[0]; if (entryd == 16'h0000) MSIP <= HWDATA[0];
@ -112,7 +112,7 @@ module clint (
always_ff @(posedge HCLK or negedge HRESETn) always_ff @(posedge HCLK or negedge HRESETn)
if (~HRESETn) begin if (~HRESETn) begin
MSIP <= 0; MSIP <= 0;
MTIMECMP <= (64)'(-1); MTIMECMP <= (64)'(0);
// MTIMECMP is not reset // MTIMECMP is not reset
end else if (memwrite) begin end else if (memwrite) begin
if (entryd == 16'h0000) MSIP <= HWDATA[0]; if (entryd == 16'h0000) MSIP <= HWDATA[0];