forked from Github_Repos/cvw
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:
parent
6bab454b17
commit
ac597d78c8
@ -75,15 +75,15 @@ module ifu (
|
|||||||
output logic ITLBMissF, ITLBHitF,
|
output logic ITLBMissF, ITLBHitF,
|
||||||
|
|
||||||
// pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H
|
// pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H
|
||||||
input logic [31:0] HADDR,
|
// input logic [31:0] HADDR,
|
||||||
input logic [2:0] HSIZE,
|
// input logic [2:0] HSIZE,
|
||||||
input logic HWRITE,
|
// 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 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],
|
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
|
||||||
|
|
||||||
output logic PMPInstrAccessFaultF, PMAInstrAccessFaultF,
|
output logic PMPInstrAccessFaultF, PMAInstrAccessFaultF,
|
||||||
output logic ISquashBusAccessF,
|
output logic ISquashBusAccessF
|
||||||
output logic [5:0] IHSELRegionsF
|
// 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
|
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.
|
// 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
|
generate
|
||||||
if (`XLEN==32)
|
if (`XLEN==32) begin
|
||||||
assign PCPF = PCPFmmu[31:0];
|
assign PCPF = PCPFmmu[31:0];
|
||||||
else
|
assign PCNextFPhys = {{(`PA_BITS-`XLEN){1'b0}}, PCNextF};
|
||||||
|
end else begin
|
||||||
assign PCPF = {8'b0, PCPFmmu};
|
assign PCPF = {8'b0, PCPFmmu};
|
||||||
|
assign PCNextFPhys = PCNextF[`PA_BITS-1:0];
|
||||||
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
mmu #(.ENTRY_BITS(`ITLB_ENTRY_BITS), .IMMU(1))
|
mmu #(.ENTRY_BITS(`ITLB_ENTRY_BITS), .IMMU(1))
|
||||||
@ -125,12 +129,12 @@ module ifu (
|
|||||||
.TLBMiss(ITLBMissF),
|
.TLBMiss(ITLBMissF),
|
||||||
.TLBHit(ITLBHitF),
|
.TLBHit(ITLBHitF),
|
||||||
.TLBPageFault(ITLBInstrPageFaultF),
|
.TLBPageFault(ITLBInstrPageFaultF),
|
||||||
.ExecuteAccessF(1'b1),
|
.InstrReadF(InstrReadF),
|
||||||
.AtomicAccessM(1'b0),
|
.AtomicAccessM(1'b0),
|
||||||
.WriteAccessM(1'b0),
|
.MemReadM(1'b0),
|
||||||
.ReadAccessM(1'b0),
|
.MemWriteM(1'b0),
|
||||||
.SquashBusAccess(ISquashBusAccessF),
|
.SquashBusAccess(ISquashBusAccessF),
|
||||||
.HSELRegions(IHSELRegionsF),
|
// .HSELRegions(IHSELRegionsF),
|
||||||
.DisableTranslation(1'b0),
|
.DisableTranslation(1'b0),
|
||||||
.*);
|
.*);
|
||||||
|
|
||||||
@ -147,7 +151,7 @@ module ifu (
|
|||||||
// assign InstrReadF = 1; // *** & ICacheMissF; add later
|
// assign InstrReadF = 1; // *** & ICacheMissF; add later
|
||||||
|
|
||||||
icache icache(.*,
|
icache icache(.*,
|
||||||
.PCNextF(PCNextF[`PA_BITS-1:0]),
|
.PCNextF(PCNextFPhys),
|
||||||
.PCPF(PCPFmmu));
|
.PCPF(PCPFmmu));
|
||||||
|
|
||||||
flopenl #(32) AlignedInstrRawDFlop(clk, reset | reset_q, ~StallD, FlushD ? nop : FinalInstrRawF, nop, InstrRawD);
|
flopenl #(32) AlignedInstrRawDFlop(clk, reset | reset_q, ~StallD, FlushD ? nop : FinalInstrRawF, nop, InstrRawD);
|
||||||
|
@ -92,8 +92,8 @@ module lsu (
|
|||||||
output logic PMALoadAccessFaultM, PMAStoreAccessFaultM,
|
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 PMPLoadAccessFaultM, PMPStoreAccessFaultM, // *** can these be parameterized? we dont need the m stage ones for the immu and vice versa.
|
||||||
|
|
||||||
output logic DSquashBusAccessM,
|
output logic DSquashBusAccessM
|
||||||
output logic [5:0] DHSELRegionsM
|
// output logic [5:0] DHSELRegionsM
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -127,12 +127,12 @@ module lsu (
|
|||||||
.TLBMiss(DTLBMissM),
|
.TLBMiss(DTLBMissM),
|
||||||
.TLBHit(DTLBHitM),
|
.TLBHit(DTLBHitM),
|
||||||
.TLBPageFault(DTLBPageFaultM),
|
.TLBPageFault(DTLBPageFaultM),
|
||||||
.ExecuteAccessF(1'b0),
|
.InstrReadF(1'b0),
|
||||||
.AtomicAccessM(|AtomicM),
|
.AtomicAccessM(AtomicMaskedM[1]),
|
||||||
.WriteAccessM(MemRWM[0]),
|
.MemWriteM(MemRWM[0]),
|
||||||
.ReadAccessM(MemRWM[1]),
|
.MemReadM(MemRWM[1]),
|
||||||
.SquashBusAccess(DSquashBusAccessM),
|
.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?
|
.*); // *** 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
|
// Specify which type of page fault is occurring
|
||||||
@ -214,13 +214,13 @@ module lsu (
|
|||||||
else NextState = STATE_READY;
|
else NextState = STATE_READY;
|
||||||
STATE_FETCH_AMO: if (MemAckW) NextState = STATE_FETCH;
|
STATE_FETCH_AMO: if (MemAckW) NextState = STATE_FETCH;
|
||||||
else NextState = STATE_FETCH_AMO;
|
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 if (MemAckW & StallW) NextState = STATE_STALLED;
|
||||||
else NextState = STATE_FETCH;
|
else NextState = STATE_FETCH;
|
||||||
STATE_STALLED: if (~StallW) NextState = STATE_READY;
|
STATE_STALLED: if (~StallW) NextState = STATE_READY;
|
||||||
else NextState = STATE_STALLED;
|
else NextState = STATE_STALLED;
|
||||||
default: NextState = STATE_READY;
|
default: NextState = STATE_READY;
|
||||||
endcase // case (CurrState)
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -26,13 +26,13 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module adrdec (
|
module adrdec (
|
||||||
input logic [31:0] HADDR,
|
input logic [`PA_BITS-1:0] PhysicalAddress,
|
||||||
input logic [31:0] Base, Range,
|
input logic [`PA_BITS-1:0] Base, Range,
|
||||||
input logic Supported,
|
input logic Supported,
|
||||||
input logic AccessValid,
|
input logic AccessValid,
|
||||||
input logic [2:0] Size,
|
input logic [1:0] Size,
|
||||||
input logic [3:0] SizeMask,
|
input logic [3:0] SizeMask,
|
||||||
output logic HSEL
|
output logic Sel
|
||||||
);
|
);
|
||||||
|
|
||||||
logic Match;
|
logic Match;
|
||||||
@ -41,12 +41,12 @@ module adrdec (
|
|||||||
// determine if an address is in a range starting at the base
|
// determine if an address is in a range starting at the base
|
||||||
// for example, if Base = 0x04002000 and range = 0x00000FFF,
|
// for example, if Base = 0x04002000 and range = 0x00000FFF,
|
||||||
// then anything address between 0x04002000 and 0x04002FFF should match (HSEL=1)
|
// 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)
|
// 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
|
endmodule
|
||||||
|
|
||||||
|
@ -26,19 +26,20 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module adrdecs (
|
module adrdecs (
|
||||||
input logic [31:0] HADDR, // *** will need to use PAdr in mmu, stick with HADDR in uncore
|
input logic [`PA_BITS-1:0] PhysicalAddress,
|
||||||
input logic AccessRW, AccessRX, AccessRWX,
|
input logic AccessRW, AccessRX, AccessRWX,
|
||||||
input logic [2:0] HSIZE,
|
input logic [1:0] Size,
|
||||||
output logic [5:0] HSELRegions
|
output logic [5:0] SelRegions
|
||||||
);
|
);
|
||||||
|
|
||||||
// Determine which region of physical memory (if any) is being accessed
|
// Determine which region of physical memory (if any) is being accessed
|
||||||
// *** eventually uncomment Access signals
|
// *** eventually uncomment Access signals
|
||||||
adrdec boottimdec(HADDR, `BOOTTIM_BASE, `BOOTTIM_RANGE, `BOOTTIM_SUPPORTED, 1'b1/*AccessRX*/, HSIZE, 4'b1111, HSELRegions[5]);
|
adrdec boottimdec(PhysicalAddress, `BOOTTIM_BASE, `BOOTTIM_RANGE, `BOOTTIM_SUPPORTED, 1'b1/*AccessRX*/, Size, 4'b1111, SelRegions[5]);
|
||||||
adrdec timdec(HADDR, `TIM_BASE, `TIM_RANGE, `TIM_SUPPORTED, 1'b1/*AccessRWX*/, HSIZE, 4'b1111, HSELRegions[4]);
|
adrdec timdec(PhysicalAddress, `TIM_BASE, `TIM_RANGE, `TIM_SUPPORTED, 1'b1/*AccessRWX*/, Size, 4'b1111, SelRegions[4]);
|
||||||
adrdec clintdec(HADDR, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, HSIZE, 4'b1111, HSELRegions[3]);
|
adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, 4'b1111, SelRegions[3]);
|
||||||
adrdec gpiodec(HADDR, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, HSIZE, 4'b0100, HSELRegions[2]);
|
adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[2]);
|
||||||
adrdec uartdec(HADDR, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, HSIZE, 4'b0001, HSELRegions[1]);
|
adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[1]);
|
||||||
adrdec plicdec(HADDR, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, HSIZE, 4'b0100, HSELRegions[0]);
|
adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[0]);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -67,17 +67,17 @@ module mmu #(parameter ENTRY_BITS = 3,
|
|||||||
output logic TLBPageFault,
|
output logic TLBPageFault,
|
||||||
|
|
||||||
// PMA checker signals
|
// PMA checker signals
|
||||||
input logic [31:0] HADDR,
|
// input logic [31:0] HADDR,
|
||||||
input logic [2:0] HSIZE,
|
// input logic [2:0] HSIZE,
|
||||||
input logic HWRITE,
|
// input logic HWRITE,
|
||||||
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM,
|
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 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],
|
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
|
||||||
|
|
||||||
output logic SquashBusAccess, // *** send to privileged unit
|
output logic SquashBusAccess, // *** send to privileged unit
|
||||||
output logic PMPInstrAccessFaultF, PMPLoadAccessFaultM, PMPStoreAccessFaultM,
|
output logic PMPInstrAccessFaultF, PMPLoadAccessFaultM, PMPStoreAccessFaultM,
|
||||||
output logic PMAInstrAccessFaultF, PMALoadAccessFaultM, PMAStoreAccessFaultM,
|
output logic PMAInstrAccessFaultF, PMALoadAccessFaultM, PMAStoreAccessFaultM
|
||||||
output logic [5:0] HSELRegions
|
// output logic [5:0] SelRegions
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -32,17 +32,15 @@ module pmachecker (
|
|||||||
|
|
||||||
input logic [`PA_BITS-1:0] PhysicalAddress,
|
input logic [`PA_BITS-1:0] PhysicalAddress,
|
||||||
input logic [1:0] Size,
|
input logic [1:0] Size,
|
||||||
input logic [31:0] HADDR,
|
// input logic [31:0] HADDR,
|
||||||
input logic [2:0] HSIZE,
|
// 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 [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 Cacheable, Idempotent, AtomicAllowed,
|
||||||
output logic PMASquashBusAccess,
|
output logic PMASquashBusAccess,
|
||||||
|
|
||||||
output logic [5:0] HSELRegions,
|
|
||||||
|
|
||||||
output logic PMAInstrAccessFaultF,
|
output logic PMAInstrAccessFaultF,
|
||||||
output logic PMALoadAccessFaultM,
|
output logic PMALoadAccessFaultM,
|
||||||
output logic PMAStoreAccessFaultM
|
output logic PMAStoreAccessFaultM
|
||||||
@ -51,24 +49,25 @@ module pmachecker (
|
|||||||
// logic BootTim, Tim, CLINT, GPIO, UART, PLIC;
|
// logic BootTim, Tim, CLINT, GPIO, UART, PLIC;
|
||||||
logic PMAAccessFault;
|
logic PMAAccessFault;
|
||||||
logic AccessRW, AccessRWX, AccessRX;
|
logic AccessRW, AccessRWX, AccessRX;
|
||||||
|
logic [5:0] SelRegions;
|
||||||
|
|
||||||
// Determine what type of access is being made
|
// Determine what type of access is being made
|
||||||
assign AccessRW = ReadAccessM | WriteAccessM;
|
assign AccessRW = MemReadM | MemWriteM;
|
||||||
assign AccessRWX = ReadAccessM | WriteAccessM | ExecuteAccessF;
|
assign AccessRWX = MemReadM | MemWriteM | InstrReadF;
|
||||||
assign AccessRX = ReadAccessM | ExecuteAccessF;
|
assign AccessRX = MemReadM | InstrReadF;
|
||||||
|
|
||||||
// Determine which region of physical memory (if any) is being accessed
|
// 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
|
// Only RAM memory regions are cacheable
|
||||||
assign Cacheable = HSELRegions[5] | HSELRegions[4];
|
assign Cacheable = SelRegions[5] | SelRegions[4];
|
||||||
assign Idempotent = HSELRegions[4];
|
assign Idempotent = SelRegions[4];
|
||||||
assign AtomicAllowed = HSELRegions[4];
|
assign AtomicAllowed = SelRegions[4];
|
||||||
|
|
||||||
// Detect access faults
|
// Detect access faults
|
||||||
assign PMAAccessFault = (~|HSELRegions) && AccessRWX;
|
assign PMAAccessFault = (~|SelRegions) & AccessRWX;
|
||||||
assign PMAInstrAccessFaultF = ExecuteAccessF && PMAAccessFault;
|
assign PMAInstrAccessFaultF = InstrReadF & PMAAccessFault;
|
||||||
assign PMALoadAccessFaultM = ReadAccessM && PMAAccessFault;
|
assign PMALoadAccessFaultM = MemReadM & PMAAccessFault;
|
||||||
assign PMAStoreAccessFaultM = WriteAccessM && PMAAccessFault;
|
assign PMAStoreAccessFaultM = MemWriteM & PMAAccessFault;
|
||||||
assign PMASquashBusAccess = PMAAccessFault;
|
assign PMASquashBusAccess = PMAAccessFault;
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -30,7 +30,8 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module pmpadrdec (
|
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 [1:0] AdrMode,
|
||||||
input logic [`XLEN-1:0] CurrentPMPAdr,
|
input logic [`XLEN-1:0] CurrentPMPAdr,
|
||||||
input logic AdrAtLeastPreviousPMP,
|
input logic AdrAtLeastPreviousPMP,
|
||||||
@ -45,15 +46,15 @@ module pmpadrdec (
|
|||||||
logic TORMatch, NAMatch;
|
logic TORMatch, NAMatch;
|
||||||
logic AdrBelowCurrentPMP;
|
logic AdrBelowCurrentPMP;
|
||||||
logic [`PA_BITS-1:0] CurrentAdrFull;
|
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
|
// ***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)
|
// Top-of-range (TOR)
|
||||||
// Append two implicit trailing 0's to PMPAdr value
|
// Append two implicit trailing 0's to PMPAdr value
|
||||||
assign CurrentAdrFull = {CurrentPMPAdr[`PA_BITS-3:0], 2'b00};
|
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 AdrAtLeastCurrentPMP = ~AdrBelowCurrentPMP;
|
||||||
assign TORMatch = AdrAtLeastPreviousPMP && AdrBelowCurrentPMP;
|
assign TORMatch = AdrAtLeastPreviousPMP && AdrBelowCurrentPMP;
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ module pmpadrdec (
|
|||||||
endgenerate
|
endgenerate
|
||||||
// verilator lint_on UNOPTFLAT
|
// verilator lint_on UNOPTFLAT
|
||||||
|
|
||||||
assign NAMatch = &((FakePhysAdr ~^ CurrentAdrFull) | Mask);
|
assign NAMatch = &((PhysicalAddress ~^ CurrentAdrFull) | Mask);
|
||||||
|
|
||||||
/* generate
|
/* generate
|
||||||
if (`XLEN == 32 || `XLEN == 64) begin // ***redo for various sizes
|
if (`XLEN == 32 || `XLEN == 64) begin // ***redo for various sizes
|
||||||
|
@ -30,8 +30,8 @@
|
|||||||
|
|
||||||
module pmpchecker (
|
module pmpchecker (
|
||||||
// input logic clk, reset, //*** it seems like clk, reset is also not needed here?
|
// input logic clk, reset, //*** it seems like clk, reset is also not needed here?
|
||||||
|
input logic [`PA_BITS-1:0] PhysicalAddress,
|
||||||
input logic [31:0] HADDR,
|
// input logic [31:0] HADDR,
|
||||||
|
|
||||||
input logic [1:0] PrivilegeModeW,
|
input logic [1:0] PrivilegeModeW,
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ module pmpchecker (
|
|||||||
// we don't have to pass around 16 whole registers.
|
// we don't have to pass around 16 whole registers.
|
||||||
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
|
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,
|
output logic PMPSquashBusAccess,
|
||||||
|
|
||||||
@ -84,17 +84,20 @@ module pmpchecker (
|
|||||||
assign {PMPCFG[7], PMPCFG[6], PMPCFG[5], PMPCFG[4],
|
assign {PMPCFG[7], PMPCFG[6], PMPCFG[5], PMPCFG[4],
|
||||||
PMPCFG[3], PMPCFG[2], PMPCFG[1], PMPCFG[0]} = PMPCFG01_REGW;
|
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]),
|
.CurrentPMPAdr(PMPADDR_ARRAY_REGW[0]),
|
||||||
.AdrAtLeastPreviousPMP(1'b1),
|
.AdrAtLeastPreviousPMP(1'b1),
|
||||||
.AdrAtLeastCurrentPMP(AboveRegion[0]),
|
.AdrAtLeastCurrentPMP(AboveRegion[0]),
|
||||||
.Match(Regions[0]));
|
.Match(Regions[0]));
|
||||||
|
|
||||||
assign ActiveRegion[0] = |PMPCFG[0][4:3];
|
assign ActiveRegion[0] = |PMPCFG[0][4:3];
|
||||||
|
|
||||||
generate // *** only for PMP_ENTRIES > 0
|
generate // *** only for PMP_ENTRIES > 0
|
||||||
genvar i;
|
genvar i;
|
||||||
for (i = 1; i < `PMP_ENTRIES; i++) begin
|
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]),
|
.CurrentPMPAdr(PMPADDR_ARRAY_REGW[i]),
|
||||||
.AdrAtLeastPreviousPMP(AboveRegion[i-1]),
|
.AdrAtLeastPreviousPMP(AboveRegion[i-1]),
|
||||||
.AdrAtLeastCurrentPMP(AboveRegion[i]),
|
.AdrAtLeastCurrentPMP(AboveRegion[i]),
|
||||||
@ -131,26 +134,26 @@ module pmpchecker (
|
|||||||
default: MatchedRegion = 0; // Should only occur if there is no match
|
default: MatchedRegion = 0; // Should only occur if there is no match
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
assign L_Bit = PMPCFG[MatchedRegion][7] && Match;
|
assign L_Bit = PMPCFG[MatchedRegion][7] & Match;
|
||||||
assign X_Bit = PMPCFG[MatchedRegion][2] && Match;
|
assign X_Bit = PMPCFG[MatchedRegion][2] & Match;
|
||||||
assign W_Bit = PMPCFG[MatchedRegion][1] && Match;
|
assign W_Bit = PMPCFG[MatchedRegion][1] & Match;
|
||||||
assign R_Bit = PMPCFG[MatchedRegion][0] && Match;
|
assign R_Bit = PMPCFG[MatchedRegion][0] & Match;
|
||||||
|
|
||||||
assign InvalidExecute = ExecuteAccessF && ~X_Bit;
|
assign InvalidExecute = InstrReadF & ~X_Bit;
|
||||||
assign InvalidWrite = WriteAccessM && ~W_Bit;
|
assign InvalidWrite = MemWriteM & ~W_Bit;
|
||||||
assign InvalidRead = ReadAccessM && ~R_Bit;
|
assign InvalidRead = MemReadM & ~R_Bit;
|
||||||
|
|
||||||
// *** don't cause faults when there are no PMPs
|
// *** don't cause faults when there are no PMPs
|
||||||
assign PMPInstrAccessFaultF = (PrivilegeModeW == `M_MODE) ?
|
assign PMPInstrAccessFaultF = (PrivilegeModeW == `M_MODE) ?
|
||||||
Match && L_Bit && InvalidExecute :
|
Match & L_Bit & InvalidExecute :
|
||||||
EnforcePMP && InvalidExecute;
|
EnforcePMP & InvalidExecute;
|
||||||
assign PMPStoreAccessFaultM = (PrivilegeModeW == `M_MODE) ?
|
assign PMPStoreAccessFaultM = (PrivilegeModeW == `M_MODE) ?
|
||||||
Match && L_Bit && InvalidWrite :
|
Match & L_Bit & InvalidWrite :
|
||||||
EnforcePMP && InvalidWrite;
|
EnforcePMP & InvalidWrite;
|
||||||
assign PMPLoadAccessFaultM = (PrivilegeModeW == `M_MODE) ?
|
assign PMPLoadAccessFaultM = (PrivilegeModeW == `M_MODE) ?
|
||||||
Match && L_Bit && InvalidRead :
|
Match & L_Bit & InvalidRead :
|
||||||
EnforcePMP && InvalidRead;
|
EnforcePMP & InvalidRead;
|
||||||
|
|
||||||
assign PMPSquashBusAccess = PMPInstrAccessFaultF || PMPLoadAccessFaultM || PMPStoreAccessFaultM;
|
assign PMPSquashBusAccess = PMPInstrAccessFaultF | PMPLoadAccessFaultM | PMPStoreAccessFaultM;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
Reference in New Issue
Block a user