Cleaned up priority thermometer verilog. passses regression, ideally shortens critical path through pmp's

This commit is contained in:
kipmacsaigoren 2021-07-23 11:57:58 -05:00
parent 5d2b30e332
commit f3579032bd
6 changed files with 70 additions and 40 deletions

View File

@ -48,6 +48,12 @@ module hptw
output logic WalkerInstrPageFaultF, WalkerLoadPageFaultM,WalkerStorePageFaultM // faults output logic WalkerInstrPageFaultF, WalkerLoadPageFaultM,WalkerStorePageFaultM // faults
); );
typedef enum {L0_ADR, L0_RD,
L1_ADR, L1_RD,
L2_ADR, L2_RD,
L3_ADR, L3_RD,
LEAF, IDLE, FAULT} statetype; // *** placed outside generate statement to remove synthesis errors
generate generate
if (`MEM_VIRTMEM) begin if (`MEM_VIRTMEM) begin
logic DTLBWalk; // register TLBs translation miss requests logic DTLBWalk; // register TLBs translation miss requests
@ -64,12 +70,6 @@ module hptw
logic [`SVMODE_BITS-1:0] SvMode; logic [`SVMODE_BITS-1:0] SvMode;
logic [`XLEN-1:0] TranslationVAdr; logic [`XLEN-1:0] TranslationVAdr;
typedef enum {L0_ADR, L0_RD,
L1_ADR, L1_RD,
L2_ADR, L2_RD,
L3_ADR, L3_RD,
LEAF, IDLE, FAULT} statetype;
statetype WalkerState, NextWalkerState, InitialWalkerState; statetype WalkerState, NextWalkerState, InitialWalkerState;
// Extract bits from CSRs and inputs // Extract bits from CSRs and inputs

View File

@ -67,9 +67,7 @@ module pmpadrdec (
assign TORMatch = PAgePMPAdrIn && PAltPMPAdr; assign TORMatch = PAgePMPAdrIn && PAltPMPAdr;
// Naturally aligned regions // Naturally aligned regions
logic [`PA_BITS-1:0] NAMask;
// verilator lint_off UNOPTFLAT
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
@ -80,23 +78,14 @@ module pmpadrdec (
// 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: assign NAMask[1:0] = {2'b11};
/* 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 prioritythemometer #(`PA_BITS-2) namaskgen(
Should be concurrent with the subtraction/comparison .a({PMPAdr[`PA_BITS-4:0], (AdrMode == NAPOT)}),
if one is the critical path, the other shouldn't be which makes us think the mask generation is the culprit. .y(NAMask[`PA_BITS-1:2]));
Hopefully just use the priority circuit here assign NAMatch = &((PhysicalAddress ~^ CurrentAdrFull) | NAMask);
*/
// verilator lint_on UNOPTFLAT
assign NAMatch = &((PhysicalAddress ~^ CurrentAdrFull) | Mask);
assign Match = (AdrMode == TOR) ? TORMatch : assign Match = (AdrMode == TOR) ? TORMatch :
(AdrMode == NA4 || AdrMode == NAPOT) ? NAMatch : (AdrMode == NA4 || AdrMode == NAPOT) ? NAMatch :

View File

@ -69,7 +69,7 @@ module pmpchecker (
.PAgePMPAdrOut(PAgePMPAdr), .PAgePMPAdrOut(PAgePMPAdr),
.FirstMatch, .Match, .Active, .L, .X, .W, .R); .FirstMatch, .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. priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .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 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// prioritycircuit.sv // priorityonehot.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,31 +30,22 @@
`include "wally-config.vh" `include "wally-config.vh"
module prioritycircuit #(parameter ENTRIES = 8, module priorityonehot #(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
logic [ENTRIES-1:0] nolower; logic [ENTRIES-1:0] nolower;
// generate thermometer code mask // generate thermometer code mask
genvar i; genvar i;
generate generate
assign nolower[0] = FirstPin; assign nolower[0] = 1'b1;
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
generate assign y = a & nolower;
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

@ -0,0 +1,50 @@
///////////////////////////////////////////
// priritythermometer.sv
//
// Written: tfleming@hmc.edu & jtorrey@hmc.edu 7 April 2021
// Modified: Teo Ene 15 Apr 2021:
// Temporarily removed paramterized priority encoder for non-parameterized one
// To get synthesis working quickly
// Kmacsaigoren@hmc.edu 28 May 2021:
// Added working version of parameterized priority encoder.
// David_Harris@Hmc.edu switched to one-hot output
//
// Purpose: Priority circuit to choose most significant one-hot output
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
`include "wally-config.vh"
module prioritythemometer #(parameter N = 8) (
input logic [N-1:0] a,
output logic [N-1:0] y
);
// generate thermometer code mask
genvar i;
generate
assign y[0] = a[0];
for (i=1; i<N; i++) begin
assign y[i] = y[i-1] & a[i];
end
endgenerate
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
prioritycircuit #(.ENTRIES(TLB_ENTRIES), .FINAL_OP("AND")) nru(.a(~RUBits), .FirstPin(1'b1), .y(WriteLines)); priorityonehot #(TLB_ENTRIES) nru(.a(~RUBits), .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}};