Broken state. address translation not working after changes to hptw to support atomic updates to PT.

This commit is contained in:
Ross Thompson 2022-02-16 23:37:36 -06:00
parent 460b37b21a
commit 565ca4e4a3
10 changed files with 160 additions and 146 deletions

File diff suppressed because one or more lines are too long

View File

@ -75,7 +75,7 @@ module ifu (
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP,
input logic ITLBWriteF, ITLBFlushF,
output logic ITLBMissF,
output logic ITLBMissF, InstrDAPageFaultF,
// pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0],
@ -156,6 +156,7 @@ module ifu (
.InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(),
.InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(),
.LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(),
.DAPageFault(InstrDAPageFaultF),
.AtomicAccessM(1'b0),.ExecuteAccessF(1'b1), .WriteAccessM(1'b0), .ReadAccessM(1'b0),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);

View File

@ -35,9 +35,9 @@ module interlockfsm
(input logic clk,
input logic reset,
input logic AnyCPUReqM,
input logic ITLBMissF,
input logic ITLBMissOrDAFaultF,
input logic ITLBWriteF,
input logic DTLBMissM,
input logic DTLBMissOrDAFaultM,
input logic DTLBWriteM,
input logic TrapM,
input logic DCacheStallM,
@ -66,10 +66,10 @@ module interlockfsm
always_comb begin
case(InterlockCurrState)
STATE_T0_READY: if (TrapM) InterlockNextState = STATE_T0_READY;
else if(~ITLBMissF & DTLBMissM & AnyCPUReqM) InterlockNextState = STATE_T3_DTLB_MISS;
else if(ITLBMissF & ~DTLBMissM & ~AnyCPUReqM) InterlockNextState = STATE_T4_ITLB_MISS;
else if(ITLBMissF & ~DTLBMissM & AnyCPUReqM) InterlockNextState = STATE_T5_ITLB_MISS;
else if(ITLBMissF & DTLBMissM & AnyCPUReqM) InterlockNextState = STATE_T7_DITLB_MISS;
else if(~ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM) InterlockNextState = STATE_T3_DTLB_MISS;
else if(ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & ~AnyCPUReqM) InterlockNextState = STATE_T4_ITLB_MISS;
else if(ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & AnyCPUReqM) InterlockNextState = STATE_T5_ITLB_MISS;
else if(ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM) InterlockNextState = STATE_T7_DITLB_MISS;
else InterlockNextState = STATE_T0_READY;
STATE_T0_REPLAY: if(DCacheStallM) InterlockNextState = STATE_T0_REPLAY;
else InterlockNextState = STATE_T0_READY;
@ -90,7 +90,7 @@ module interlockfsm
// this code has a problem with imperas64mmu as it reads in an invalid uninitalized instruction. InterlockStall becomes x and it propagates
// everywhere. The case statement below implements the same logic but any x on the inputs will resolve to 0.
// Note this will cause a problem for post synthesis gate simulation.
assign InterlockStall = (InterlockCurrState == STATE_T0_READY & (DTLBMissM | ITLBMissF)) |
assign InterlockStall = (InterlockCurrState == STATE_T0_READY & (DTLBMissOrDAFaultM | ITLBMissOrDAFaultF)) |
(InterlockCurrState == STATE_T3_DTLB_MISS) | (InterlockCurrState == STATE_T4_ITLB_MISS) |
(InterlockCurrState == STATE_T5_ITLB_MISS) | (InterlockCurrState == STATE_T7_DITLB_MISS);
@ -99,7 +99,7 @@ module interlockfsm
always_comb begin
InterlockStall = 1'b0;
case(InterlockCurrState)
STATE_T0_READY: if((DTLBMissM | ITLBMissF) & ~TrapM) InterlockStall = 1'b1;
STATE_T0_READY: if((DTLBMissOrDAFaultM | ITLBMissOrDAFaultF) & ~TrapM) InterlockStall = 1'b1;
STATE_T3_DTLB_MISS: InterlockStall = 1'b1;
STATE_T4_ITLB_MISS: InterlockStall = 1'b1;
STATE_T5_ITLB_MISS: InterlockStall = 1'b1;
@ -112,7 +112,7 @@ module interlockfsm
assign SelReplayCPURequest = (InterlockNextState == STATE_T0_REPLAY);
assign SelHPTW = (InterlockCurrState == STATE_T3_DTLB_MISS) | (InterlockCurrState == STATE_T4_ITLB_MISS) |
(InterlockCurrState == STATE_T5_ITLB_MISS) | (InterlockCurrState == STATE_T7_DITLB_MISS);
assign IgnoreRequestTLB = (InterlockCurrState == STATE_T0_READY & (ITLBMissF | DTLBMissM));
assign IgnoreRequestTLB = (InterlockCurrState == STATE_T0_READY & (ITLBMissOrDAFaultF | DTLBMissOrDAFaultM));
assign IgnoreRequestTrapM = (InterlockCurrState == STATE_T0_READY & (TrapM)) |
((InterlockCurrState == STATE_T0_REPLAY) & (TrapM));

View File

@ -74,6 +74,7 @@ module lsu (
input logic [1:0] STATUS_MPP,
input logic [`XLEN-1:0] PCF,
input logic ITLBMissF,
input logic InstrDAPageFaultF,
output logic [`XLEN-1:0] PTE,
output logic [1:0] PageType,
output logic ITLBWriteF,
@ -101,7 +102,8 @@ module lsu (
logic IgnoreRequestTLB, IgnoreRequestTrapM;
logic BusCommittedM, DCacheCommittedM;
logic LSUBusWriteCrit;
logic DataDAPageFaultM;
flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM);
assign IEUAdrExtM = {2'b00, IEUAdrM};
assign LSUStallM = DCacheStallM | InterlockStall | BusStall;
@ -113,7 +115,8 @@ module lsu (
if(`VIRTMEM_SUPPORTED) begin : VIRTMEM_SUPPORTED
lsuvirtmem lsuvirtmem(.clk, .reset, .StallW, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF,
.DTLBMissM, .DTLBWriteM, .TrapM, .DCacheStallM, .SATP_REGW, .PCF,
.DTLBMissM, .DTLBWriteM, .InstrDAPageFaultF, .DataDAPageFaultM,
.TrapM, .DCacheStallM, .SATP_REGW, .PCF,
.ReadDataM, .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M, .IEUAdrM,
.IEUAdrExtM, .PTE, .PageType, .PreLSURWM, .LSUAtomicM, .IEUAdrE,
.LSUAdrE, .PreLSUPAdrM, .CPUBusy, .InterlockStall, .SelHPTW,
@ -152,7 +155,8 @@ module lsu (
.Cacheable(CacheableM), .Idempotent(), .AtomicAllowed(),
.InstrAccessFaultF(), .LoadAccessFaultM, .StoreAmoAccessFaultM,
.InstrPageFaultF(),.LoadPageFaultM, .StoreAmoPageFaultM,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
.DAPageFault(DataDAPageFaultM),
.AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0), // **** change this to just use PreLSURWM
.WriteAccessM(PreLSURWM[0]), .ReadAccessM(PreLSURWM[1]),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
@ -168,7 +172,7 @@ module lsu (
// Memory System
// Either Data Cache or Data Tightly Integrated Memory or just bus interface
/////////////////////////////////////////////////////////////////////////////////////////////
logic [`XLEN-1:0] FinalAMOWriteDataM, FinalWriteDataM;
logic [`XLEN-1:0] FinalAMOWriteDataM, FinalWriteDataM, PostSWWWriteDataM;
logic [`XLEN-1:0] ReadDataWordM;
logic [`XLEN-1:0] ReadDataWordMuxM;
logic IgnoreRequest;
@ -244,9 +248,11 @@ module lsu (
assign ReadDataWordMaskedM = CacheableM ? ReadDataWordM : '0; // AND-gate
subwordwrite subwordwrite(.HRDATA(ReadDataWordMaskedM), .HADDRD(LSUPAdrM[2:0]),
.HSIZED({LSUFunct3M[2], 1'b0, LSUFunct3M[1:0]}),
.HWDATAIN(FinalAMOWriteDataM), .HWDATA(FinalWriteDataM));
.HWDATAIN(FinalAMOWriteDataM), .HWDATA(PostSWWWriteDataM));
end else
assign FinalWriteDataM = FinalAMOWriteDataM;
assign PostSWWWriteDataM = FinalAMOWriteDataM;
assign FinalWriteDataM = SelHPTW ? PTE : PostSWWWriteDataM;
/////////////////////////////////////////////////////////////////////////////////////////////
// Atomic operations

View File

@ -37,6 +37,8 @@ module lsuvirtmem(
output logic ITLBWriteF,
input logic DTLBMissM,
output logic DTLBWriteM,
input logic InstrDAPageFaultF,
input logic DataDAPageFaultM,
input logic TrapM,
input logic DCacheStallM,
input logic [`XLEN-1:0] SATP_REGW, // from csr
@ -69,23 +71,25 @@ module lsuvirtmem(
logic [2:0] HPTWSize;
logic SelReplayCPURequest;
logic [11:0] PreLSUAdrE;
logic ITLBMissOrDAFaultF;
logic DTLBMissOrDAFaultM;
logic HPTWWrite;
assign AnyCPUReqM = (|MemRWM) | (|AtomicM);
assign ITLBMissOrDAFaultF = ITLBWriteF | InstrDAPageFaultF;
assign DTLBMissOrDAFaultM = DTLBWriteM | DataDAPageFaultM;
interlockfsm interlockfsm (
.clk, .reset, .AnyCPUReqM, .ITLBMissF, .ITLBWriteF,
.DTLBMissM, .DTLBWriteM, .TrapM, .DCacheStallM,
.clk, .reset, .AnyCPUReqM, .ITLBMissOrDAFaultF, .ITLBWriteF,
.DTLBMissOrDAFaultM, .DTLBWriteM, .TrapM, .DCacheStallM,
.InterlockStall, .SelReplayCPURequest, .SelHPTW, .IgnoreRequestTLB, .IgnoreRequestTrapM);
hptw hptw( // *** remove logic from (), mention this in style guide CH3
.clk, .reset, .SATP_REGW, .PCF, .IEUAdrM,
.ITLBMissF(ITLBMissF & ~TrapM), .DTLBMissM(DTLBMissM & ~TrapM),
.clk, .reset, .SATP_REGW, .PCF, .IEUAdrM, .MemRWM, .AtomicM,
.ITLBMissF(ITLBMissOrDAFaultF & ~TrapM), .DTLBMissM(DTLBMissOrDAFaultM & ~TrapM), // *** Fix me.
.PTE, .PageType, .ITLBWriteF, .DTLBWriteM, .HPTWReadPTE(ReadDataM),
.DCacheStallM, .HPTWAdr, .HPTWRead, .HPTWSize);
.DCacheStallM, .HPTWAdr, .HPTWRead, .HPTWWrite, .HPTWSize);
// multiplex the outputs to LSU
mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, PreLSURWM);
mux2 #(2) rwmux(MemRWM, {HPTWRead, HPTWWrite}, SelHPTW, PreLSURWM);
mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M);
mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M);
mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM);

View File

@ -29,12 +29,13 @@
///////////////////////////////////////////
`include "wally-config.vh"
`define HTPW_DA_WRITES_SUPPORTED 1
module hptw
(
input logic clk, reset,
input logic [`XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table
input logic [`XLEN-1:0] PCF, IEUAdrM, // addresses to translate
input logic [1:0] MemRWM, AtomicM,
(* mark_debug = "true" *) input logic ITLBMissF, DTLBMissM, // TLB Miss
input logic [`XLEN-1:0] HPTWReadPTE, // page table entry from LSU
input logic DCacheStallM, // stall from LSU
@ -43,6 +44,7 @@ module hptw
(* mark_debug = "true" *) output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry
output logic [`PA_BITS-1:0] HPTWAdr,
output logic HPTWRead, // HPTW requesting to read memory
output logic HPTWWrite,
output logic [2:0] HPTWSize // 32 or 64 bit access.
);
@ -50,7 +52,7 @@ module hptw
L1_ADR, L1_RD,
L2_ADR, L2_RD,
L3_ADR, L3_RD,
LEAF, IDLE} statetype;
LEAF, IDLE, UPDATE_PTE} statetype;
logic DTLBWalk; // register TLBs translation miss requests
logic [`PPN_BITS-1:0] BasePageTablePPN;
@ -65,7 +67,12 @@ module hptw
logic [1:0] NextPageType;
logic [`SVMODE_BITS-1:0] SvMode;
logic [`XLEN-1:0] TranslationVAdr;
logic Dirty, Accessed;
logic [`XLEN-1:0] NextPTE;
logic UpdatePTE;
logic SetDirty;
logic DAPageFault;
(* mark_debug = "true" *) statetype WalkerState, NextWalkerState, InitialWalkerState;
// Extract bits from CSRs and inputs
@ -80,21 +87,30 @@ module hptw
// State flops
flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB)
assign PRegEn = HPTWRead & ~DCacheStallM;
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, PTE); // Capture page table entry from data cache
assign NextPTE = UpdatePTE ? {PTE[`XLEN-1:8], SetDirty , 1'b1, PTE[5:0]} : HPTWReadPTE;
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn | HPTWWrite, NextPTE, PTE); // Capture page table entry from data cache
// Assign PTE descriptors common across all XLEN values
// For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table
assign {Executable, Writable, Readable, Valid} = PTE[3:0];
assign {Executable, Writable, Readable, Valid} = PTE[3:0];
assign {Dirty, Accessed} = PTE[7:6];
assign LeafPTE = Executable | Writable | Readable;
assign ValidPTE = Valid & ~(Writable & ~Readable);
assign ValidLeafPTE = ValidPTE & LeafPTE;
assign ValidNonLeafPTE = ValidPTE & ~LeafPTE;
assign SetDirty = ~Dirty & & DTLBWalk & (MemRWM[0] | |AtomicM);
assign DAPageFault = ValidLeafPTE & (~Accessed) | (SetDirty);
// Enable and select signals based on states
assign StartWalk = (WalkerState == IDLE) & TLBMiss;
assign HPTWRead = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
assign DTLBWriteM = (WalkerState == LEAF) & DTLBWalk;
assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBWalk;
assign HPTWWrite = (WalkerState == UPDATE_PTE);
assign UpdatePTE = ((WalkerState == L2_ADR | WalkerState == L1_ADR | WalkerState == L0_ADR)
& ValidLeafPTE & ~Misaligned & DAPageFault);
// FSM to track PageType based on the levels of the page table traversed
flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType);
@ -156,39 +172,35 @@ module hptw
always_comb
case (WalkerState)
IDLE: if (TLBMiss) NextWalkerState = InitialWalkerState;
else NextWalkerState = IDLE;
L3_ADR: NextWalkerState = L3_RD; // first access in SV48
L3_RD: if (DCacheStallM) NextWalkerState = L3_RD;
else NextWalkerState = L2_ADR;
// LEVEL3: if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF;
// else if (ValidNonLeafPTE) NextWalkerState = L2_ADR;
// else NextWalkerState = FAULT;
L2_ADR: if (InitialWalkerState == L2_ADR) NextWalkerState = L2_RD; // first access in SV39
else if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
else if (ValidNonLeafPTE) NextWalkerState = L2_RD;
else NextWalkerState = LEAF;
L2_RD: if (DCacheStallM) NextWalkerState = L2_RD;
else NextWalkerState = L1_ADR;
// LEVEL2: if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF;
// else if (ValidNonLeafPTE) NextWalkerState = L1_ADR;
// else NextWalkerState = FAULT;
L1_ADR: if (InitialWalkerState == L1_ADR) NextWalkerState = L1_RD; // first access in SV32
else if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
else if (ValidNonLeafPTE) NextWalkerState = L1_RD;
else NextWalkerState = LEAF;
L1_RD: if (DCacheStallM) NextWalkerState = L1_RD;
else NextWalkerState = L0_ADR;
// LEVEL1: if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF;
// else if (ValidNonLeafPTE) NextWalkerState = L0_ADR;
// else NextWalkerState = FAULT;
L0_ADR: if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
else if (ValidNonLeafPTE) NextWalkerState = L0_RD;
else NextWalkerState = LEAF;
L0_RD: if (DCacheStallM) NextWalkerState = L0_RD;
else NextWalkerState = LEAF;
// LEVEL0: if (ValidLeafPTE) NextWalkerState = LEAF;
// else NextWalkerState = FAULT;
LEAF: NextWalkerState = IDLE; // updates TLB
else NextWalkerState = IDLE;
L3_ADR: NextWalkerState = L3_RD; // first access in SV48
L3_RD: if (DCacheStallM) NextWalkerState = L3_RD;
else NextWalkerState = L2_ADR;
L2_ADR: if (InitialWalkerState == L2_ADR) NextWalkerState = L2_RD; // first access in SV39
else if (ValidLeafPTE & ~Misaligned & ~DAPageFault) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
else if (ValidLeafPTE & ~Misaligned & DAPageFault) NextWalkerState = UPDATE_PTE;
else if (ValidNonLeafPTE) NextWalkerState = L2_RD;
else NextWalkerState = LEAF;
L2_RD: if (DCacheStallM) NextWalkerState = L2_RD;
else NextWalkerState = L1_ADR;
L1_ADR: if (InitialWalkerState == L1_ADR) NextWalkerState = L1_RD; // first access in SV32
else if (ValidLeafPTE & ~Misaligned & ~DAPageFault) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
else if (ValidLeafPTE & ~Misaligned & DAPageFault) NextWalkerState = UPDATE_PTE;
else if (ValidNonLeafPTE) NextWalkerState = L1_RD;
else NextWalkerState = LEAF;
L1_RD: if (DCacheStallM) NextWalkerState = L1_RD;
else NextWalkerState = L0_ADR;
L0_ADR: if (ValidLeafPTE & ~Misaligned & ~DAPageFault) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
else if (ValidLeafPTE & ~Misaligned & DAPageFault) NextWalkerState = UPDATE_PTE;
else if (ValidNonLeafPTE) NextWalkerState = L0_RD;
else NextWalkerState = LEAF;
L0_RD: if (DCacheStallM) NextWalkerState = L0_RD;
else NextWalkerState = LEAF;
LEAF: NextWalkerState = IDLE;
// *** TODO update PTE with dirty/access. write to TLB and update memory.
// probably want to write the PTE in UPDATE_PTE then go to leaf and update TLB.
UPDATE_PTE: if(DCacheStallM) NextWalkerState = UPDATE_PTE;
else NextWalkerState = LEAF;
default: begin
// synthesis translate_off
if (WalkerState !== 'x)

View File

@ -34,20 +34,20 @@
module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
parameter IMMU = 0) (
input logic clk, reset,
input logic clk, reset,
// Current value of satp CSR (from privileged unit)
input logic [`XLEN-1:0] SATP_REGW,
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP,
input logic [`XLEN-1:0] SATP_REGW,
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP,
// Current privilege level of the processeor
input logic [1:0] PrivilegeModeW,
input logic [1:0] PrivilegeModeW,
// 00 - TLB is not being accessed
// 1x - TLB is accessed for a read (or an instruction)
// x1 - TLB is accessed for a write
// 11 - TLB is accessed for both read and write
input logic DisableTranslation,
input logic DisableTranslation,
// VAdr goes to the TLB only. Virtual if the TLB is active.
// PAdr goes to address mux bypassing the TLB. PAdr used when there is no translation.
@ -57,32 +57,33 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
// performed.
// PhysicalAddress is selected to be PAdr when no translation or the translated VAdr (TLBPAdr)
// when there is translation.
input logic [`PA_BITS-1:0] PAdr, // *** consider renaming this.
input logic [`XLEN-1:0] VAdr,
input logic [1:0] Size, // 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits
input logic [`PA_BITS-1:0] PAdr, // *** consider renaming this.
input logic [`XLEN-1:0] VAdr,
input logic [1:0] Size, // 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits
// Controls for writing a new entry to the TLB
input logic [`XLEN-1:0] PTE,
input logic [1:0] PageTypeWriteVal,
input logic TLBWrite,
input logic [`XLEN-1:0] PTE,
input logic [1:0] PageTypeWriteVal,
input logic TLBWrite,
// Invalidate all TLB entries
input logic TLBFlush,
input logic TLBFlush,
// Physical address outputs
output logic [`PA_BITS-1:0] PhysicalAddress,
output logic TLBMiss,
output logic Cacheable, Idempotent, AtomicAllowed,
output logic TLBMiss,
output logic Cacheable, Idempotent, AtomicAllowed,
// Faults
output logic InstrAccessFaultF, LoadAccessFaultM, StoreAmoAccessFaultM,
output logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM,
output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM,
output logic InstrAccessFaultF, LoadAccessFaultM, StoreAmoAccessFaultM,
output logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM,
output logic DAPageFault,
output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM,
// PMA checker signals
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM,
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0]
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM,
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0]
);
logic [`PA_BITS-1:0] TLBPAdr;
@ -109,7 +110,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
.PrivilegeModeW, .ReadAccess, .WriteAccess,
.DisableTranslation, .PTE, .PageTypeWriteVal,
.TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit,
.Translate, .TLBPageFault);
.Translate, .TLBPageFault, .DAPageFault);
end else begin:tlb// just pass address through as physical
assign Translate = 0;
assign TLBMiss = 0;

View File

@ -56,43 +56,44 @@
// The TLB will have 2**ENTRY_BITS total entries
module tlb #(parameter TLB_ENTRIES = 8,
parameter ITLB = 0) (
input logic clk, reset,
input logic clk, reset,
// Current value of satp CSR (from privileged unit)
input logic [`SVMODE_BITS-1:0] SATP_MODE,
input logic [`ASID_BITS-1:0] SATP_ASID,
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP,
input logic [`SVMODE_BITS-1:0] SATP_MODE,
input logic [`ASID_BITS-1:0] SATP_ASID,
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP,
// Current privilege level of the processeor
input logic [1:0] PrivilegeModeW,
input logic [1:0] PrivilegeModeW,
// 00 - TLB is not being accessed
// 1x - TLB is accessed for a read (or an instruction)
// x1 - TLB is accessed for a write
// 11 - TLB is accessed for both read and write
input logic ReadAccess, WriteAccess,
input logic DisableTranslation,
input logic ReadAccess, WriteAccess,
input logic DisableTranslation,
// address input before translation (could be physical or virtual)
input logic [`XLEN-1:0] VAdr,
input logic [`XLEN-1:0] VAdr,
// Controls for writing a new entry to the TLB
input logic [`XLEN-1:0] PTE,
input logic [1:0] PageTypeWriteVal,
input logic TLBWrite,
input logic [`XLEN-1:0] PTE,
input logic [1:0] PageTypeWriteVal,
input logic TLBWrite,
// Invalidate all TLB entries
input logic TLBFlush,
input logic TLBFlush,
// Physical address outputs
output logic [`PA_BITS-1:0] TLBPAdr,
output logic TLBMiss,
output logic TLBHit,
output logic Translate,
output logic [`PA_BITS-1:0] TLBPAdr,
output logic TLBMiss,
output logic TLBHit,
output logic Translate,
// Faults
output logic TLBPageFault
output logic TLBPageFault,
output logic DAPageFault
);
logic [TLB_ENTRIES-1:0] Matches, WriteEnables, PTE_Gs; // used as the one-hot encoding of WriteIndex
@ -132,7 +133,7 @@ module tlb #(parameter TLB_ENTRIES = 8,
tlbcontrol #(ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .DisableTranslation, .TLBFlush,
.PTEAccessBits, .CAMHit, .Misaligned, .TLBMiss, .TLBHit, .TLBPageFault,
.SV39Mode, .Translate);
.DAPageFault, .SV39Mode, .Translate);
tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .TLBFlush, .Matches, .CAMHit, .WriteEnables);
tlbcam #(TLB_ENTRIES, `VPN_BITS + `ASID_BITS, `VPN_SEGMENT_BITS)

View File

@ -33,27 +33,28 @@
module tlbcontrol #(parameter ITLB = 0) (
// Current value of satp CSR (from privileged unit)
input logic [`SVMODE_BITS-1:0] SATP_MODE,
input logic [`XLEN-1:0] VAdr,
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP,
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
input logic [`SVMODE_BITS-1:0] SATP_MODE,
input logic [`XLEN-1:0] VAdr,
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP,
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
// 00 - TLB is not being accessed
// 1x - TLB is accessed for a read (or an instruction)
// x1 - TLB is accessed for a write
// 11 - TLB is accessed for both read and write
input logic ReadAccess, WriteAccess,
input logic DisableTranslation,
input logic TLBFlush, // Invalidate all TLB entries
input logic [7:0] PTEAccessBits,
input logic CAMHit,
input logic Misaligned,
output logic TLBMiss,
output logic TLBHit,
output logic TLBPageFault,
output logic SV39Mode,
output logic Translate
input logic ReadAccess, WriteAccess,
input logic DisableTranslation,
input logic TLBFlush, // Invalidate all TLB entries
input logic [7:0] PTEAccessBits,
input logic CAMHit,
input logic Misaligned,
output logic TLBMiss,
output logic TLBHit,
output logic TLBPageFault,
output logic DAPageFault,
output logic SV39Mode,
output logic Translate
);
// Sections of the page table entry
@ -63,7 +64,6 @@ module tlbcontrol #(parameter ITLB = 0) (
logic PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R, PTE_V; // Useful PTE Control Bits
logic UpperBitsUnequalPageFault;
logic DAPageFault;
logic TLBAccess;
logic ImproperPrivilege;
@ -98,8 +98,8 @@ module tlbcontrol #(parameter ITLB = 0) (
assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) & ~PTE_U) |
((EffectivePrivilegeMode == `S_MODE) & PTE_U);
// fault for software handling if access bit is off
assign DAPageFault = ~PTE_A;
assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | ~PTE_X | DAPageFault | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
assign DAPageFault = Translate & TLBHit & ~PTE_A;
assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | ~PTE_X | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
end else begin:dtlb // Data TLB fault checking
logic InvalidRead, InvalidWrite;
@ -115,8 +115,8 @@ module tlbcontrol #(parameter ITLB = 0) (
// low.
assign InvalidWrite = WriteAccess & ~PTE_W;
// Fault for software handling if access bit is off or writing a page with dirty bit off
assign DAPageFault = ~PTE_A | WriteAccess & ~PTE_D;
assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | DAPageFault | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
assign DAPageFault = Translate & TLBHit & (~PTE_A | WriteAccess & ~PTE_D);
assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
end
assign TLBHit = CAMHit & TLBAccess;

View File

@ -163,7 +163,7 @@ module wallypipelinedcore (
logic ICacheMiss;
logic ICacheAccess;
logic BreakpointFaultM, EcallFaultM;
logic InstrDAPageFaultF;
ifu ifu(
.clk, .reset,
@ -201,8 +201,8 @@ module wallypipelinedcore (
// pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.InstrAccessFaultF
.InstrAccessFaultF,
.InstrDAPageFaultF
); // instruction fetch unit: PC, branch prediction, instruction cache
@ -276,6 +276,7 @@ module wallypipelinedcore (
.LoadAccessFaultM, // connects to privilege
.StoreAmoMisalignedFaultM, // connects to privilege
.StoreAmoAccessFaultM, // connects to privilege
.InstrDAPageFaultF,
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF,
.LSUStallM); // change to LSUStallM