forked from Github_Repos/cvw
remove redundant decodes, fixed mmu logic ins/outs
This commit is contained in:
parent
1e174a8244
commit
49515245d9
@ -30,28 +30,28 @@
|
||||
|
||||
module camline #(parameter KEY_BITS = 20,
|
||||
parameter SEGMENT_BITS = 10) (
|
||||
input clk, reset,
|
||||
input logic clk, reset,
|
||||
|
||||
// input to check which SvMode is running
|
||||
input [`SVMODE_BITS-1:0] SvMode,
|
||||
input logic [`SVMODE_BITS-1:0] SvMode,
|
||||
|
||||
// The requested page number to compare against the key
|
||||
input [KEY_BITS-1:0] VirtualPageNumber,
|
||||
input logic [KEY_BITS-1:0] VirtualPageNumber,
|
||||
|
||||
// Signals to write a new entry to this line
|
||||
input CAMLineWrite,
|
||||
input [1:0] PageTypeWrite,
|
||||
input logic CAMLineWrite,
|
||||
input logic [1:0] PageTypeWrite,
|
||||
|
||||
// Flush this line (set valid to 0)
|
||||
input TLBFlush,
|
||||
input logic TLBFlush,
|
||||
|
||||
// This entry is a key for a tera, giga, mega, or kilopage.
|
||||
// PageType == 2'b00 --> kilopage
|
||||
// PageType == 2'b01 --> megapage
|
||||
// PageType == 2'b10 --> gigapage
|
||||
// PageType == 2'b11 --> terapage
|
||||
output [1:0] PageType, // *** should this be the stored version or the always updated one?
|
||||
output Match
|
||||
output logic [1:0] PageType, // *** should this be the stored version or the always updated one?
|
||||
output logic Match
|
||||
);
|
||||
|
||||
// This entry has KEY_BITS for the key plus one valid bit.
|
||||
|
@ -26,8 +26,8 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module decoder #(parameter BINARY_BITS = 3) (
|
||||
input [BINARY_BITS-1:0] binary,
|
||||
output [(2**BINARY_BITS)-1:0] onehot
|
||||
input logic [BINARY_BITS-1:0] binary,
|
||||
output logic [(2**BINARY_BITS)-1:0] onehot
|
||||
);
|
||||
|
||||
// *** Double check whether this synthesizes as expected
|
||||
|
@ -28,11 +28,11 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module physicalpagemask (
|
||||
input [`VPN_BITS-1:0] VPN,
|
||||
input [`PPN_BITS-1:0] PPN,
|
||||
input [1:0] PageType,
|
||||
input logic [`VPN_BITS-1:0] VPN,
|
||||
input logic [`PPN_BITS-1:0] PPN,
|
||||
input logic [1:0] PageType,
|
||||
|
||||
output [`PPN_BITS-1:0] MixedPageNumber
|
||||
output logic [`PPN_BITS-1:0] MixedPageNumber
|
||||
);
|
||||
|
||||
localparam EXTRA_BITS = `PPN_BITS - `VPN_BITS;
|
||||
|
@ -94,6 +94,7 @@ module tlb #(parameter ENTRY_BITS = 3,
|
||||
|
||||
// Index (currently random) to write the next TLB entry
|
||||
logic [ENTRY_BITS-1:0] WriteIndex;
|
||||
logic [2**ENTRY_BITS-1:0] WriteLines; // used as the one-hot encoding of WriteIndex
|
||||
|
||||
// Sections of the virtual and physical addresses
|
||||
logic [`VPN_BITS-1:0] VirtualPageNumber;
|
||||
@ -117,6 +118,9 @@ module tlb #(parameter ENTRY_BITS = 3,
|
||||
// Grab the sv mode from SATP
|
||||
assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS];
|
||||
|
||||
// Decode the integer encoded WriteIndex into the one-hot encoded WriteLines
|
||||
decoder writedecoder(WriteIndex, WriteLines);
|
||||
|
||||
// The bus width is always the largest it could be for that XLEN. For example, vpn will be 36 bits wide in rv64
|
||||
// this, even though it could be 27 bits (SV39) or 36 bits (SV48) wide. When the value of VPN is narrower,
|
||||
// is shorter, the extra bits are used as padded zeros on the left of the full value.
|
||||
|
@ -31,27 +31,25 @@
|
||||
module tlbcam #(parameter ENTRY_BITS = 3,
|
||||
parameter KEY_BITS = 20,
|
||||
parameter SEGMENT_BITS = 10) (
|
||||
input clk, reset,
|
||||
input [KEY_BITS-1:0] VirtualPageNumber,
|
||||
input [1:0] PageTypeWrite,
|
||||
input [ENTRY_BITS-1:0] WriteIndex,
|
||||
input [`SVMODE_BITS-1:0] SvMode,
|
||||
input TLBWrite,
|
||||
input TLBFlush,
|
||||
output [ENTRY_BITS-1:0] VPNIndex,
|
||||
output [1:0] HitPageType,
|
||||
output CAMHit
|
||||
input logic clk, reset,
|
||||
input logic [KEY_BITS-1:0] VirtualPageNumber,
|
||||
input logic [1:0] PageTypeWrite,
|
||||
input logic [`SVMODE_BITS-1:0] SvMode,
|
||||
input logic TLBWrite,
|
||||
input logic TLBFlush,
|
||||
input logic [2**ENTRY_BITS-1:0] WriteLines,
|
||||
|
||||
output logic [ENTRY_BITS-1:0] VPNIndex,
|
||||
output logic [1:0] HitPageType,
|
||||
output logic CAMHit
|
||||
);
|
||||
|
||||
localparam NENTRIES = 2**ENTRY_BITS;
|
||||
|
||||
logic [NENTRIES-1:0] CAMLineWrite;
|
||||
|
||||
logic [1:0] PageTypeList [0:NENTRIES-1];
|
||||
logic [NENTRIES-1:0] Matches;
|
||||
|
||||
// Determine which CAM line should be written, based on a binary index
|
||||
decoder #(ENTRY_BITS) decoder(WriteIndex, CAMLineWrite);
|
||||
|
||||
// Create NENTRIES CAM lines, each of which will independently consider
|
||||
// whether the requested virtual address is a match. Each line stores the
|
||||
// original virtual page number from when the address was written, regardless
|
||||
@ -61,7 +59,7 @@ module tlbcam #(parameter ENTRY_BITS = 3,
|
||||
genvar i;
|
||||
for (i = 0; i < NENTRIES; i++) begin
|
||||
camline #(KEY_BITS, SEGMENT_BITS) camline(
|
||||
.CAMLineWrite(CAMLineWrite[i] && TLBWrite),
|
||||
.CAMLineWrite(WriteLines[i] && TLBWrite),
|
||||
.PageType(PageTypeList[i]),
|
||||
.Match(Matches[i]),
|
||||
.*);
|
||||
|
@ -25,12 +25,14 @@
|
||||
///////////////////////////////////////////
|
||||
|
||||
module tlblru #(parameter ENTRY_BITS = 3) (
|
||||
input clk, reset,
|
||||
input TLBWrite,
|
||||
input TLBFlush,
|
||||
input [ENTRY_BITS-1:0] VPNIndex,
|
||||
input CAMHit,
|
||||
output [ENTRY_BITS-1:0] WriteIndex
|
||||
input logic clk, reset,
|
||||
input logic TLBWrite,
|
||||
input logic TLBFlush,
|
||||
input logic [ENTRY_BITS-1:0] VPNIndex,
|
||||
input logic CAMHit,
|
||||
input logic [2**ENTRY_BITS-1:0] WriteLines,
|
||||
|
||||
output logic [ENTRY_BITS-1:0] WriteIndex
|
||||
);
|
||||
|
||||
localparam NENTRIES = 2**ENTRY_BITS;
|
||||
@ -39,21 +41,19 @@ module tlblru #(parameter ENTRY_BITS = 3) (
|
||||
logic [NENTRIES-1:0] RUBits, RUBitsNext, RUBitsAccessed;
|
||||
|
||||
// One-hot encodings of which line is being accessed
|
||||
logic [NENTRIES-1:0] ReadLineOneHot, WriteLineOneHot, AccessLineOneHot;
|
||||
logic [NENTRIES-1:0] ReadLineOneHot, AccessLineOneHot;
|
||||
|
||||
// High if the next access causes all RU bits to be 1
|
||||
logic AllUsed;
|
||||
|
||||
// Convert indices to one-hot encodings
|
||||
decoder #(ENTRY_BITS) readdecoder(VPNIndex, ReadLineOneHot);
|
||||
// *** should output writelineonehot so we don't have to decode WriteIndex outside
|
||||
decoder #(ENTRY_BITS) writedecoder(WriteIndex, WriteLineOneHot);
|
||||
|
||||
// Find the first line not recently used
|
||||
priorityencoder #(ENTRY_BITS) firstnru(~RUBits, WriteIndex);
|
||||
|
||||
// Access either the hit line or written line
|
||||
assign AccessLineOneHot = (TLBWrite) ? WriteLineOneHot : ReadLineOneHot;
|
||||
assign AccessLineOneHot = (TLBWrite) ? WriteLines : ReadLineOneHot;
|
||||
|
||||
// Raise the bit of the recently accessed line
|
||||
assign RUBitsAccessed = AccessLineOneHot | RUBits;
|
||||
|
@ -28,14 +28,15 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module tlbram #(parameter ENTRY_BITS = 3) (
|
||||
input clk, reset,
|
||||
input [ENTRY_BITS-1:0] VPNIndex, // Index to read from
|
||||
input [ENTRY_BITS-1:0] WriteIndex,
|
||||
input [`XLEN-1:0] PageTableEntryWrite,
|
||||
input TLBWrite,
|
||||
input logic clk, reset,
|
||||
input logic [ENTRY_BITS-1:0] VPNIndex, // Index to read from
|
||||
input logic [ENTRY_BITS-1:0] WriteIndex,
|
||||
input logic [`XLEN-1:0] PageTableEntryWrite,
|
||||
input logic TLBWrite,
|
||||
input logic [2**ENTRY_BITS-1:0] WriteLines,
|
||||
|
||||
output [`PPN_BITS-1:0] PhysicalPageNumber,
|
||||
output [7:0] PTEAccessBits
|
||||
output logic [`PPN_BITS-1:0] PhysicalPageNumber,
|
||||
output logic [7:0] PTEAccessBits
|
||||
);
|
||||
|
||||
localparam NENTRIES = 2**ENTRY_BITS;
|
||||
@ -43,15 +44,11 @@ module tlbram #(parameter ENTRY_BITS = 3) (
|
||||
logic [`XLEN-1:0] ram [0:NENTRIES-1];
|
||||
logic [`XLEN-1:0] PageTableEntry;
|
||||
|
||||
logic [NENTRIES-1:0] RAMEntryWrite;
|
||||
|
||||
decoder #(ENTRY_BITS) tlbramdecoder(WriteIndex, RAMEntryWrite);
|
||||
|
||||
// Generate a flop for every entry in the RAM
|
||||
generate
|
||||
genvar i;
|
||||
for (i = 0; i < NENTRIES; i++) begin: tlb_ram_flops
|
||||
flopenr #(`XLEN) pteflop(clk, reset, RAMEntryWrite[i] & TLBWrite,
|
||||
flopenr #(`XLEN) pteflop(clk, reset, WriteLines[i] & TLBWrite,
|
||||
PageTableEntryWrite, ram[i]);
|
||||
end
|
||||
endgenerate
|
||||
|
Loading…
Reference in New Issue
Block a user