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,
|
||||
|
||||
// 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);
|
||||
|
@ -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
|
||||
|
@ -26,13 +26,13 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module adrdec (
|
||||
input logic [31:0] HADDR,
|
||||
input logic [31:0] Base, Range,
|
||||
input logic [`PA_BITS-1:0] PhysicalAddress,
|
||||
input logic [`PA_BITS-1:0] Base, Range,
|
||||
input logic Supported,
|
||||
input logic AccessValid,
|
||||
input logic [2:0] Size,
|
||||
input logic [1:0] Size,
|
||||
input logic [3:0] SizeMask,
|
||||
output logic HSEL
|
||||
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
|
||||
|
||||
|
@ -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 [`PA_BITS-1:0] PhysicalAddress,
|
||||
input logic AccessRW, AccessRX, AccessRWX,
|
||||
input logic [2:0] HSIZE,
|
||||
output logic [5:0] HSELRegions
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
||||
);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user