Removed AHB address, etc signals from physical memory checkers, replaced with physical address from cpu or ptw. Passes lint but not simulations.

This commit is contained in:
Kip Macsai-Goren 2021-06-24 19:59:29 -04:00
parent 6bab454b17
commit ac597d78c8
8 changed files with 96 additions and 88 deletions

View File

@ -75,15 +75,15 @@ module ifu (
output logic ITLBMissF, ITLBHitF,
// pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H
input logic [31:0] HADDR,
input logic [2:0] HSIZE,
input logic HWRITE,
// input logic [31:0] HADDR,
// input logic [2:0] HSIZE,
// input logic HWRITE,
input logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so they're gonna have to come over into ifu and dmem
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
output logic PMPInstrAccessFaultF, PMAInstrAccessFaultF,
output logic ISquashBusAccessF,
output logic [5:0] IHSELRegionsF
output logic ISquashBusAccessF
// output logic [5:0] IHSELRegionsF
);
@ -104,13 +104,17 @@ module ifu (
logic PMPLoadAccessFaultM, PMPStoreAccessFaultM; // *** these are just so that the mmu has somewhere to put these outputs, they're unused in this stage
// if you're allowed to parameterize outputs/ inputs existence, these are an easy delete.
logic [`PA_BITS-1:0] PCPFmmu;
logic [`PA_BITS-1:0] PCPFmmu, PCNextFPhys; // used to either truncate or expand PCPF and PCNextF into `PA_BITS width.
;
generate
if (`XLEN==32)
if (`XLEN==32) begin
assign PCPF = PCPFmmu[31:0];
else
assign PCNextFPhys = {{(`PA_BITS-`XLEN){1'b0}}, PCNextF};
end else begin
assign PCPF = {8'b0, PCPFmmu};
assign PCNextFPhys = PCNextF[`PA_BITS-1:0];
end
endgenerate
mmu #(.ENTRY_BITS(`ITLB_ENTRY_BITS), .IMMU(1))
@ -125,12 +129,12 @@ module ifu (
.TLBMiss(ITLBMissF),
.TLBHit(ITLBHitF),
.TLBPageFault(ITLBInstrPageFaultF),
.ExecuteAccessF(1'b1),
.InstrReadF(InstrReadF),
.AtomicAccessM(1'b0),
.WriteAccessM(1'b0),
.ReadAccessM(1'b0),
.MemReadM(1'b0),
.MemWriteM(1'b0),
.SquashBusAccess(ISquashBusAccessF),
.HSELRegions(IHSELRegionsF),
// .HSELRegions(IHSELRegionsF),
.DisableTranslation(1'b0),
.*);
@ -147,7 +151,7 @@ module ifu (
// assign InstrReadF = 1; // *** & ICacheMissF; add later
icache icache(.*,
.PCNextF(PCNextF[`PA_BITS-1:0]),
.PCNextF(PCNextFPhys),
.PCPF(PCPFmmu));
flopenl #(32) AlignedInstrRawDFlop(clk, reset | reset_q, ~StallD, FlushD ? nop : FinalInstrRawF, nop, InstrRawD);

View File

@ -92,8 +92,8 @@ module lsu (
output logic PMALoadAccessFaultM, PMAStoreAccessFaultM,
output logic PMPLoadAccessFaultM, PMPStoreAccessFaultM, // *** can these be parameterized? we dont need the m stage ones for the immu and vice versa.
output logic DSquashBusAccessM,
output logic [5:0] DHSELRegionsM
output logic DSquashBusAccessM
// output logic [5:0] DHSELRegionsM
);
@ -127,12 +127,12 @@ module lsu (
.TLBMiss(DTLBMissM),
.TLBHit(DTLBHitM),
.TLBPageFault(DTLBPageFaultM),
.ExecuteAccessF(1'b0),
.AtomicAccessM(|AtomicM),
.WriteAccessM(MemRWM[0]),
.ReadAccessM(MemRWM[1]),
.InstrReadF(1'b0),
.AtomicAccessM(AtomicMaskedM[1]),
.MemWriteM(MemRWM[0]),
.MemReadM(MemRWM[1]),
.SquashBusAccess(DSquashBusAccessM),
.HSELRegions(DHSELRegionsM),
// .SelRegions(DHSELRegionsM),
.*); // *** the pma/pmp instruction acess faults don't really matter here. is it possible to parameterize which outputs exist?
// Specify which type of page fault is occurring
@ -214,13 +214,13 @@ module lsu (
else NextState = STATE_READY;
STATE_FETCH_AMO: if (MemAckW) NextState = STATE_FETCH;
else NextState = STATE_FETCH_AMO;
STATE_FETCH: if (MemAckW & ~StallW) NextState = STATE_READY;
STATE_FETCH: if (MemAckW & ~StallW) NextState = STATE_READY; // StallW will stay high if datastall stays high, so right now, once we get into STATE_FETCH, datastall goes high, and we never leave
else if (MemAckW & StallW) NextState = STATE_STALLED;
else NextState = STATE_FETCH;
STATE_STALLED: if (~StallW) NextState = STATE_READY;
else NextState = STATE_STALLED;
default: NextState = STATE_READY;
endcase // case (CurrState)
endcase
end
endmodule

View File

@ -26,13 +26,13 @@
`include "wally-config.vh"
module adrdec (
input logic [31:0] HADDR,
input logic [31:0] Base, Range,
input logic Supported,
input logic AccessValid,
input logic [2:0] Size,
input logic [3:0] SizeMask,
output logic HSEL
input logic [`PA_BITS-1:0] PhysicalAddress,
input logic [`PA_BITS-1:0] Base, Range,
input logic Supported,
input logic AccessValid,
input logic [1:0] Size,
input logic [3:0] SizeMask,
output logic Sel
);
logic Match;
@ -41,12 +41,12 @@ module adrdec (
// determine if an address is in a range starting at the base
// for example, if Base = 0x04002000 and range = 0x00000FFF,
// then anything address between 0x04002000 and 0x04002FFF should match (HSEL=1)
assign Match = &((HADDR ~^ Base) | Range);
assign Match = &((PhysicalAddress ~^ Base) | Range);
// determine if legal size of access is being made (byte, halfword, word, doubleword)
assign SizeValid = SizeMask[Size[1:0]];
assign SizeValid = SizeMask[Size];
assign HSEL = Match && Supported && AccessValid && SizeValid;
assign Sel = Match && Supported && AccessValid && SizeValid;
endmodule

View File

@ -26,19 +26,20 @@
`include "wally-config.vh"
module adrdecs (
input logic [31:0] HADDR, // *** will need to use PAdr in mmu, stick with HADDR in uncore
input logic AccessRW, AccessRX, AccessRWX,
input logic [2:0] HSIZE,
output logic [5:0] HSELRegions
input logic [`PA_BITS-1:0] PhysicalAddress,
input logic AccessRW, AccessRX, AccessRWX,
input logic [1:0] Size,
output logic [5:0] SelRegions
);
// Determine which region of physical memory (if any) is being accessed
// *** eventually uncomment Access signals
adrdec boottimdec(HADDR, `BOOTTIM_BASE, `BOOTTIM_RANGE, `BOOTTIM_SUPPORTED, 1'b1/*AccessRX*/, HSIZE, 4'b1111, HSELRegions[5]);
adrdec timdec(HADDR, `TIM_BASE, `TIM_RANGE, `TIM_SUPPORTED, 1'b1/*AccessRWX*/, HSIZE, 4'b1111, HSELRegions[4]);
adrdec clintdec(HADDR, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, HSIZE, 4'b1111, HSELRegions[3]);
adrdec gpiodec(HADDR, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, HSIZE, 4'b0100, HSELRegions[2]);
adrdec uartdec(HADDR, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, HSIZE, 4'b0001, HSELRegions[1]);
adrdec plicdec(HADDR, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, HSIZE, 4'b0100, HSELRegions[0]);
adrdec boottimdec(PhysicalAddress, `BOOTTIM_BASE, `BOOTTIM_RANGE, `BOOTTIM_SUPPORTED, 1'b1/*AccessRX*/, Size, 4'b1111, SelRegions[5]);
adrdec timdec(PhysicalAddress, `TIM_BASE, `TIM_RANGE, `TIM_SUPPORTED, 1'b1/*AccessRWX*/, Size, 4'b1111, SelRegions[4]);
adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, 4'b1111, SelRegions[3]);
adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[2]);
adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[1]);
adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[0]);
endmodule

View File

@ -67,17 +67,17 @@ module mmu #(parameter ENTRY_BITS = 3,
output logic TLBPageFault,
// PMA checker signals
input logic [31:0] HADDR,
input logic [2:0] HSIZE,
input logic HWRITE,
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM,
// input logic [31:0] HADDR,
// input logic [2:0] HSIZE,
// input logic HWRITE,
input logic AtomicAccessM, InstrReadF, MemWriteM, MemReadM,
input logic [63:0] PMPCFG01_REGW, PMPCFG23_REGW, // *** all of these come from the privileged unit, so thwyre gonna have to come over into ifu and dmem
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
output logic SquashBusAccess, // *** send to privileged unit
output logic PMPInstrAccessFaultF, PMPLoadAccessFaultM, PMPStoreAccessFaultM,
output logic PMAInstrAccessFaultF, PMALoadAccessFaultM, PMAStoreAccessFaultM,
output logic [5:0] HSELRegions
output logic PMAInstrAccessFaultF, PMALoadAccessFaultM, PMAStoreAccessFaultM
// output logic [5:0] SelRegions
);

View File

@ -32,17 +32,15 @@ module pmachecker (
input logic [`PA_BITS-1:0] PhysicalAddress,
input logic [1:0] Size,
input logic [31:0] HADDR,
input logic [2:0] HSIZE,
// input logic [31:0] HADDR,
// input logic [2:0] HSIZE,
// input logic [2:0] HBURST, // *** in AHBlite, HBURST is hardwired to zero for single bursts only allowed. consider removing from this module if unused.
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // *** atomicaccessM is unused but might want to stay in for future use.
input logic AtomicAccessM, InstrReadF, MemWriteM, MemReadM, // *** atomicaccessM is unused but might want to stay in for future use.
output logic Cacheable, Idempotent, AtomicAllowed,
output logic PMASquashBusAccess,
output logic [5:0] HSELRegions,
output logic PMAInstrAccessFaultF,
output logic PMALoadAccessFaultM,
output logic PMAStoreAccessFaultM
@ -51,24 +49,25 @@ module pmachecker (
// logic BootTim, Tim, CLINT, GPIO, UART, PLIC;
logic PMAAccessFault;
logic AccessRW, AccessRWX, AccessRX;
logic [5:0] SelRegions;
// Determine what type of access is being made
assign AccessRW = ReadAccessM | WriteAccessM;
assign AccessRWX = ReadAccessM | WriteAccessM | ExecuteAccessF;
assign AccessRX = ReadAccessM | ExecuteAccessF;
assign AccessRW = MemReadM | MemWriteM;
assign AccessRWX = MemReadM | MemWriteM | InstrReadF;
assign AccessRX = MemReadM | InstrReadF;
// Determine which region of physical memory (if any) is being accessed
adrdecs adrdecs(HADDR, AccessRW, AccessRX, AccessRWX, HSIZE, HSELRegions);
adrdecs adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWX, Size, SelRegions);
// Only RAM memory regions are cacheable
assign Cacheable = HSELRegions[5] | HSELRegions[4];
assign Idempotent = HSELRegions[4];
assign AtomicAllowed = HSELRegions[4];
assign Cacheable = SelRegions[5] | SelRegions[4];
assign Idempotent = SelRegions[4];
assign AtomicAllowed = SelRegions[4];
// Detect access faults
assign PMAAccessFault = (~|HSELRegions) && AccessRWX;
assign PMAInstrAccessFaultF = ExecuteAccessF && PMAAccessFault;
assign PMALoadAccessFaultM = ReadAccessM && PMAAccessFault;
assign PMAStoreAccessFaultM = WriteAccessM && PMAAccessFault;
assign PMAAccessFault = (~|SelRegions) & AccessRWX;
assign PMAInstrAccessFaultF = InstrReadF & PMAAccessFault;
assign PMALoadAccessFaultM = MemReadM & PMAAccessFault;
assign PMAStoreAccessFaultM = MemWriteM & PMAAccessFault;
assign PMASquashBusAccess = PMAAccessFault;
endmodule

View File

@ -30,7 +30,8 @@
`include "wally-config.vh"
module pmpadrdec (
input logic [31:0] HADDR, // *** replace with PAdr
input logic [`PA_BITS-1:0] PhysicalAddress,
// input logic [31:0] HADDR, // *** replace with PAdr
input logic [1:0] AdrMode,
input logic [`XLEN-1:0] CurrentPMPAdr,
input logic AdrAtLeastPreviousPMP,
@ -45,15 +46,15 @@ module pmpadrdec (
logic TORMatch, NAMatch;
logic AdrBelowCurrentPMP;
logic [`PA_BITS-1:0] CurrentAdrFull;
logic [`PA_BITS-1:0] FakePhysAdr;
// logic [`PA_BITS-1:0] FakePhysAdr;
// ***replace this when the true physical address from MMU is available
assign FakePhysAdr = {{(`PA_BITS-32){1'b0}}, HADDR};
// assign FakePhysAdr = {{(`PA_BITS-32){1'b0}}, HADDR};
// Top-of-range (TOR)
// Append two implicit trailing 0's to PMPAdr value
assign CurrentAdrFull = {CurrentPMPAdr[`PA_BITS-3:0], 2'b00};
assign AdrBelowCurrentPMP = /*HADDR */FakePhysAdr < CurrentAdrFull; // *** make sure unsigned comparison works correctly
assign AdrBelowCurrentPMP = PhysicalAddress < CurrentAdrFull; // *** make sure unsigned comparison works correctly
assign AdrAtLeastCurrentPMP = ~AdrBelowCurrentPMP;
assign TORMatch = AdrAtLeastPreviousPMP && AdrBelowCurrentPMP;
@ -73,7 +74,7 @@ module pmpadrdec (
endgenerate
// verilator lint_on UNOPTFLAT
assign NAMatch = &((FakePhysAdr ~^ CurrentAdrFull) | Mask);
assign NAMatch = &((PhysicalAddress ~^ CurrentAdrFull) | Mask);
/* generate
if (`XLEN == 32 || `XLEN == 64) begin // ***redo for various sizes

View File

@ -30,8 +30,8 @@
module pmpchecker (
// input logic clk, reset, //*** it seems like clk, reset is also not needed here?
input logic [31:0] HADDR,
input logic [`PA_BITS-1:0] PhysicalAddress,
// input logic [31:0] HADDR,
input logic [1:0] PrivilegeModeW,
@ -50,7 +50,7 @@ module pmpchecker (
// we don't have to pass around 16 whole registers.
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
input logic ExecuteAccessF, WriteAccessM, ReadAccessM,
input logic InstrReadF, MemWriteM, MemReadM,
output logic PMPSquashBusAccess,
@ -84,17 +84,20 @@ module pmpchecker (
assign {PMPCFG[7], PMPCFG[6], PMPCFG[5], PMPCFG[4],
PMPCFG[3], PMPCFG[2], PMPCFG[1], PMPCFG[0]} = PMPCFG01_REGW;
pmpadrdec pmpadrdec(.HADDR(HADDR), .AdrMode(PMPCFG[0][4:3]),
pmpadrdec pmpadrdec(.PhysicalAddress(PhysicalAddress),
.AdrMode(PMPCFG[0][4:3]),
.CurrentPMPAdr(PMPADDR_ARRAY_REGW[0]),
.AdrAtLeastPreviousPMP(1'b1),
.AdrAtLeastCurrentPMP(AboveRegion[0]),
.Match(Regions[0]));
assign ActiveRegion[0] = |PMPCFG[0][4:3];
generate // *** only for PMP_ENTRIES > 0
genvar i;
for (i = 1; i < `PMP_ENTRIES; i++) begin
pmpadrdec pmpadrdec(.HADDR(HADDR), .AdrMode(PMPCFG[i][4:3]),
pmpadrdec pmpadrdec(.PhysicalAddress(PhysicalAddress),
.AdrMode(PMPCFG[i][4:3]),
.CurrentPMPAdr(PMPADDR_ARRAY_REGW[i]),
.AdrAtLeastPreviousPMP(AboveRegion[i-1]),
.AdrAtLeastCurrentPMP(AboveRegion[i]),
@ -131,26 +134,26 @@ module pmpchecker (
default: MatchedRegion = 0; // Should only occur if there is no match
endcase
assign L_Bit = PMPCFG[MatchedRegion][7] && Match;
assign X_Bit = PMPCFG[MatchedRegion][2] && Match;
assign W_Bit = PMPCFG[MatchedRegion][1] && Match;
assign R_Bit = PMPCFG[MatchedRegion][0] && Match;
assign L_Bit = PMPCFG[MatchedRegion][7] & Match;
assign X_Bit = PMPCFG[MatchedRegion][2] & Match;
assign W_Bit = PMPCFG[MatchedRegion][1] & Match;
assign R_Bit = PMPCFG[MatchedRegion][0] & Match;
assign InvalidExecute = ExecuteAccessF && ~X_Bit;
assign InvalidWrite = WriteAccessM && ~W_Bit;
assign InvalidRead = ReadAccessM && ~R_Bit;
assign InvalidExecute = InstrReadF & ~X_Bit;
assign InvalidWrite = MemWriteM & ~W_Bit;
assign InvalidRead = MemReadM & ~R_Bit;
// *** don't cause faults when there are no PMPs
assign PMPInstrAccessFaultF = (PrivilegeModeW == `M_MODE) ?
Match && L_Bit && InvalidExecute :
EnforcePMP && InvalidExecute;
Match & L_Bit & InvalidExecute :
EnforcePMP & InvalidExecute;
assign PMPStoreAccessFaultM = (PrivilegeModeW == `M_MODE) ?
Match && L_Bit && InvalidWrite :
EnforcePMP && InvalidWrite;
Match & L_Bit & InvalidWrite :
EnforcePMP & InvalidWrite;
assign PMPLoadAccessFaultM = (PrivilegeModeW == `M_MODE) ?
Match && L_Bit && InvalidRead :
EnforcePMP && InvalidRead;
Match & L_Bit & InvalidRead :
EnforcePMP & InvalidRead;
assign PMPSquashBusAccess = PMPInstrAccessFaultF || PMPLoadAccessFaultM || PMPStoreAccessFaultM;
assign PMPSquashBusAccess = PMPInstrAccessFaultF | PMPLoadAccessFaultM | PMPStoreAccessFaultM;
endmodule