mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Preliminary work to make DTIM and Bus compatible. Not yet working because accesses to bus are causing illegal address faults on the bus.
This commit is contained in:
parent
60b673cafd
commit
f2517f8290
@ -82,7 +82,7 @@ for test in tests32gc:
|
|||||||
grepstr="All tests ran without failures")
|
grepstr="All tests ran without failures")
|
||||||
configs.append(tc)
|
configs.append(tc)
|
||||||
|
|
||||||
tests32ic = ["arch32i", "arch32c", "imperas32i", "imperas32c", "wally32priv", "wally32periph"]
|
tests32ic = ["arch32i", "arch32c", "imperas32i", "imperas32c", "wally32periph"]
|
||||||
for test in tests32ic:
|
for test in tests32ic:
|
||||||
tc = TestCase(
|
tc = TestCase(
|
||||||
name=test,
|
name=test,
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
vsim -do "do wally-pipelined.do rv32gc wally32periph"
|
vsim -do "do wally-pipelined.do rv32ic wally32periph"
|
||||||
|
|
||||||
|
@ -93,6 +93,7 @@ module ifu (
|
|||||||
logic CompressedF;
|
logic CompressedF;
|
||||||
logic [31:0] InstrRawD, InstrRawF;
|
logic [31:0] InstrRawD, InstrRawF;
|
||||||
logic [31:0] FinalInstrRawF;
|
logic [31:0] FinalInstrRawF;
|
||||||
|
logic [1:0] NonIROMMemRWM;
|
||||||
|
|
||||||
logic [31:0] InstrE;
|
logic [31:0] InstrE;
|
||||||
logic [`XLEN-1:0] PCD;
|
logic [`XLEN-1:0] PCD;
|
||||||
@ -113,6 +114,7 @@ module ifu (
|
|||||||
logic BusStall;
|
logic BusStall;
|
||||||
logic ICacheStallF, IFUCacheBusStallF;
|
logic ICacheStallF, IFUCacheBusStallF;
|
||||||
logic CPUBusy;
|
logic CPUBusy;
|
||||||
|
logic SelIROM;
|
||||||
(* mark_debug = "true" *) logic [31:0] PostSpillInstrRawF;
|
(* mark_debug = "true" *) logic [31:0] PostSpillInstrRawF;
|
||||||
// branch predictor signal
|
// branch predictor signal
|
||||||
logic [`XLEN-1:0] PCNext1F, PCNext2F, PCNext0F;
|
logic [`XLEN-1:0] PCNext1F, PCNext2F, PCNext0F;
|
||||||
@ -154,7 +156,7 @@ module ifu (
|
|||||||
|
|
||||||
mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1))
|
mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1))
|
||||||
immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
|
immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
|
||||||
.PrivilegeModeW, .DisableTranslation(1'b0),
|
.PrivilegeModeW, .DisableTranslation(1'b0), .SelTIM(SelIROM),
|
||||||
.VAdr(PCFExt),
|
.VAdr(PCFExt),
|
||||||
.Size(2'b10),
|
.Size(2'b10),
|
||||||
.PTE(PTE),
|
.PTE(PTE),
|
||||||
@ -184,9 +186,20 @@ module ifu (
|
|||||||
logic [`XLEN-1:0] AllInstrRawF;
|
logic [`XLEN-1:0] AllInstrRawF;
|
||||||
assign InstrRawF = AllInstrRawF[31:0];
|
assign InstrRawF = AllInstrRawF[31:0];
|
||||||
|
|
||||||
|
// The IROM uses untranslated addresses, so it is not compatible with virtual memory.
|
||||||
if (`IROM_SUPPORTED) begin : irom
|
if (`IROM_SUPPORTED) begin : irom
|
||||||
|
logic [`PA_BITS-1:0] IROMAdr;
|
||||||
|
logic IROMAccessRW;
|
||||||
|
/* verilator lint_off WIDTH */
|
||||||
|
assign IROMAdr = CPUBusy | reset ? PCFSpill : PCNextFSpill; // zero extend or contract to PA_BITS
|
||||||
|
/* verilator lint_on WIDTH */
|
||||||
|
|
||||||
|
adrdec iromdec(IROMAdr, `IROM_BASE, `IROM_RANGE, `IROM_SUPPORTED, 1'b1, 2'b10, 4'b1111, SelIROM);
|
||||||
|
assign NonIROMMemRWM = {~SelIROM, 1'b0};
|
||||||
irom irom(.clk, .reset, .Adr(CPUBusy | reset ? PCFSpill : PCNextFSpill), .ReadData(FinalInstrRawF));
|
irom irom(.clk, .reset, .Adr(CPUBusy | reset ? PCFSpill : PCNextFSpill), .ReadData(FinalInstrRawF));
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
assign SelIROM = 0; assign NonIROMMemRWM = 2'b10;
|
||||||
end
|
end
|
||||||
if (`BUS) begin : bus
|
if (`BUS) begin : bus
|
||||||
localparam integer WORDSPERLINE = `ICACHE ? `ICACHE_LINELENINBITS/`XLEN : 1;
|
localparam integer WORDSPERLINE = `ICACHE ? `ICACHE_LINELENINBITS/`XLEN : 1;
|
||||||
@ -210,7 +223,7 @@ module ifu (
|
|||||||
.CacheMiss(ICacheMiss), .CacheAccess(ICacheAccess),
|
.CacheMiss(ICacheMiss), .CacheAccess(ICacheAccess),
|
||||||
.ByteMask('0), .WordCount('0), .SelBusWord('0),
|
.ByteMask('0), .WordCount('0), .SelBusWord('0),
|
||||||
.FinalWriteData('0),
|
.FinalWriteData('0),
|
||||||
.RW(2'b10),
|
.RW(NonIROMMemRWM),
|
||||||
.Atomic('0), .FlushCache('0),
|
.Atomic('0), .FlushCache('0),
|
||||||
.NextAdr(PCNextFSpill[11:0]),
|
.NextAdr(PCNextFSpill[11:0]),
|
||||||
.PAdr(PCPF),
|
.PAdr(PCPF),
|
||||||
@ -225,7 +238,7 @@ module ifu (
|
|||||||
.CacheWriteLine(1'b0), .CacheBusAck(ICacheBusAck),
|
.CacheWriteLine(1'b0), .CacheBusAck(ICacheBusAck),
|
||||||
.FetchBuffer, .PAdr(PCPF),
|
.FetchBuffer, .PAdr(PCPF),
|
||||||
.SelUncachedAdr,
|
.SelUncachedAdr,
|
||||||
.IgnoreRequest(ITLBMissF), .RW(2'b10), .CPUBusy, .Cacheable(CacheableF),
|
.IgnoreRequest(ITLBMissF), .RW(NonIROMMemRWM), .CPUBusy, .Cacheable(CacheableF),
|
||||||
.BusStall, .BusCommitted());
|
.BusStall, .BusCommitted());
|
||||||
|
|
||||||
mux2 #(32) UnCachedDataMux(.d0(FinalInstrRawF), .d1(FetchBuffer[32-1:0]),
|
mux2 #(32) UnCachedDataMux(.d0(FinalInstrRawF), .d1(FetchBuffer[32-1:0]),
|
||||||
@ -235,7 +248,7 @@ module ifu (
|
|||||||
flopen #(`XLEN) fb(.clk, .en(IFUBusRead), .d(HRDATA), .q(AllInstrRawF[31:0]));
|
flopen #(`XLEN) fb(.clk, .en(IFUBusRead), .d(HRDATA), .q(AllInstrRawF[31:0]));
|
||||||
|
|
||||||
busfsm #(LOGBWPL) busfsm(
|
busfsm #(LOGBWPL) busfsm(
|
||||||
.clk, .reset, .IgnoreRequest(ITLBMissF), .RW(2'b10),
|
.clk, .reset, .IgnoreRequest(ITLBMissF), .RW(NonIROMMemRWM),
|
||||||
.BusAck(IFUBusAck), .BusInit(IFUBusInit), .CPUBusy,
|
.BusAck(IFUBusAck), .BusInit(IFUBusInit), .CPUBusy,
|
||||||
.BusStall, .BusWrite(), .BusRead(IFUBusRead),
|
.BusStall, .BusWrite(), .BusRead(IFUBusRead),
|
||||||
.HTRANS(IFUHTRANS), .BusCommitted());
|
.HTRANS(IFUHTRANS), .BusCommitted());
|
||||||
|
@ -94,8 +94,7 @@ module lsu (
|
|||||||
logic [`PA_BITS-1:0] LSUPAdrM;
|
logic [`PA_BITS-1:0] LSUPAdrM;
|
||||||
logic DTLBMissM;
|
logic DTLBMissM;
|
||||||
logic DTLBWriteM;
|
logic DTLBWriteM;
|
||||||
logic [1:0] LSURWM;
|
logic [1:0] NonDTIMMemRWM, PreLSURWM, LSURWM;
|
||||||
logic [1:0] PreLSURWM;
|
|
||||||
logic [2:0] LSUFunct3M;
|
logic [2:0] LSUFunct3M;
|
||||||
logic [6:0] LSUFunct7M;
|
logic [6:0] LSUFunct7M;
|
||||||
logic [1:0] LSUAtomicM;
|
logic [1:0] LSUAtomicM;
|
||||||
@ -125,7 +124,7 @@ module lsu (
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
if(`VIRTMEM_SUPPORTED) begin : VIRTMEM_SUPPORTED
|
if(`VIRTMEM_SUPPORTED) begin : VIRTMEM_SUPPORTED
|
||||||
lsuvirtmem lsuvirtmem(.clk, .reset, .StallW, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF,
|
lsuvirtmem lsuvirtmem(.clk, .reset, .StallW, .MemRWM(NonDTIMMemRWM), .AtomicM, .ITLBMissF, .ITLBWriteF,
|
||||||
.DTLBMissM, .DTLBWriteM, .InstrDAPageFaultF, .DataDAPageFaultM,
|
.DTLBMissM, .DTLBWriteM, .InstrDAPageFaultF, .DataDAPageFaultM,
|
||||||
.TrapM, .DCacheStallM, .SATP_REGW, .PCF,
|
.TrapM, .DCacheStallM, .SATP_REGW, .PCF,
|
||||||
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW,
|
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW,
|
||||||
@ -135,7 +134,7 @@ module lsu (
|
|||||||
.IgnoreRequestTLB);
|
.IgnoreRequestTLB);
|
||||||
end else begin
|
end else begin
|
||||||
assign {InterlockStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF, IgnoreRequestTLB} = '0;
|
assign {InterlockStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF, IgnoreRequestTLB} = '0;
|
||||||
assign CPUBusy = StallW; assign PreLSURWM = MemRWM;
|
assign CPUBusy = StallW; assign PreLSURWM = NonDTIMMemRWM;
|
||||||
assign LSUAdrE = IEUAdrE[11:0];
|
assign LSUAdrE = IEUAdrE[11:0];
|
||||||
assign PreLSUPAdrM = IEUAdrExtM;
|
assign PreLSUPAdrM = IEUAdrExtM;
|
||||||
assign LSUFunct3M = Funct3M; assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM;
|
assign LSUFunct3M = Funct3M; assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM;
|
||||||
@ -156,7 +155,7 @@ module lsu (
|
|||||||
assign DisableTranslation = SelHPTW | FlushDCacheM;
|
assign DisableTranslation = SelHPTW | FlushDCacheM;
|
||||||
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
|
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
|
||||||
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
|
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
|
||||||
.PrivilegeModeW, .DisableTranslation,
|
.PrivilegeModeW, .DisableTranslation, .SelTIM(SelDTIM),
|
||||||
.VAdr(PreLSUPAdrM),
|
.VAdr(PreLSUPAdrM),
|
||||||
.Size(LSUFunct3M[1:0]),
|
.Size(LSUFunct3M[1:0]),
|
||||||
.PTE,
|
.PTE,
|
||||||
@ -196,21 +195,24 @@ module lsu (
|
|||||||
if (`DTIM_SUPPORTED) begin : dtim
|
if (`DTIM_SUPPORTED) begin : dtim
|
||||||
logic [`PA_BITS-1:0] DTIMAdr;
|
logic [`PA_BITS-1:0] DTIMAdr;
|
||||||
logic DTIMAccessRW;
|
logic DTIMAccessRW;
|
||||||
|
logic MemStage;
|
||||||
|
|
||||||
// The DTIM uses untranslated addresses, so it is not compatible with virtual memory.
|
// The DTIM uses untranslated addresses, so it is not compatible with virtual memory.
|
||||||
// Don't perform size checking on DTIM
|
// Don't perform size checking on DTIM
|
||||||
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
||||||
assign DTIMAdr = CPUBusy | MemRWM[0] | reset ? IEUAdrM : IEUAdrE; // zero extend or contract to PA_BITS
|
assign MemStage = CPUBusy | MemRWM[0] | reset; // 1 = M stage; 0 = E stage
|
||||||
|
assign DTIMAdr = MemStage ? IEUAdrM : IEUAdrE; // zero extend or contract to PA_BITS
|
||||||
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
||||||
assign DTIMAccessRW = |MemRWM;
|
assign DTIMAccessRW = |MemRWM;
|
||||||
adrdec dtimdec(DTIMAdr, `DTIM_BASE, `DTIM_RANGE, `DTIM_SUPPORTED, DTIMAccessRW, 2'b10, 4'b1111, SelDTIM);
|
adrdec dtimdec(DTIMAdr, `DTIM_BASE, `DTIM_RANGE, `DTIM_SUPPORTED, DTIMAccessRW | ~MemStage, 2'b10, 4'b1111, SelDTIM);
|
||||||
|
assign NonDTIMMemRWM = MemRWM & ~{2{SelDTIM}}; // disable access to bus-based memory map when DTIM is selected
|
||||||
|
|
||||||
dtim dtim(.clk, .reset, .MemRWM,
|
dtim dtim(.clk, .reset, .MemRWM,
|
||||||
.Adr(DTIMAdr),
|
.Adr(DTIMAdr),
|
||||||
.TrapM, .WriteDataM(LSUWriteDataM),
|
.TrapM, .WriteDataM(LSUWriteDataM),
|
||||||
.ReadDataWordM(ReadDataWordM[`XLEN-1:0]), .ByteMaskM(ByteMaskM[`XLEN/8-1:0]));
|
.ReadDataWordM(ReadDataWordM[`XLEN-1:0]), .ByteMaskM(ByteMaskM[`XLEN/8-1:0]));
|
||||||
end else begin
|
end else begin
|
||||||
assign SelDTIM = 0;
|
assign SelDTIM = 0; assign NonDTIMMemRWM = MemRWM;
|
||||||
end
|
end
|
||||||
if (`BUS) begin : bus
|
if (`BUS) begin : bus
|
||||||
localparam integer WORDSPERLINE = `DCACHE ? `DCACHE_LINELENINBITS/`XLEN : 1;
|
localparam integer WORDSPERLINE = `DCACHE ? `DCACHE_LINELENINBITS/`XLEN : 1;
|
||||||
|
@ -35,24 +35,21 @@ module adrdecs (
|
|||||||
input logic [`PA_BITS-1:0] PhysicalAddress,
|
input logic [`PA_BITS-1:0] PhysicalAddress,
|
||||||
input logic AccessRW, AccessRX, AccessRWX,
|
input logic AccessRW, AccessRX, AccessRWX,
|
||||||
input logic [1:0] Size,
|
input logic [1:0] Size,
|
||||||
output logic [10:0] SelRegions
|
output logic [8:0] SelRegions
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam logic [3:0] SUPPORTED_SIZE = (`LLEN == 32 ? 4'b0111 : 4'b1111);
|
localparam logic [3:0] SUPPORTED_SIZE = (`LLEN == 32 ? 4'b0111 : 4'b1111);
|
||||||
// Determine which region of physical memory (if any) is being accessed
|
// Determine which region of physical memory (if any) is being accessed
|
||||||
adrdec ddr4dec(PhysicalAddress, `EXT_MEM_BASE, `EXT_MEM_RANGE, `EXT_MEM_SUPPORTED, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[9]);
|
adrdec ddr4dec(PhysicalAddress, `EXT_MEM_BASE, `EXT_MEM_RANGE, `EXT_MEM_SUPPORTED, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[7]);
|
||||||
adrdec bootromdec(PhysicalAddress, `BOOTROM_BASE, `BOOTROM_RANGE, `BOOTROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[8]);
|
adrdec bootromdec(PhysicalAddress, `BOOTROM_BASE, `BOOTROM_RANGE, `BOOTROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[6]);
|
||||||
adrdec uncoreramdec(PhysicalAddress, `UNCORE_RAM_BASE, `UNCORE_RAM_RANGE, `UNCORE_RAM_SUPPORTED, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[7]);
|
adrdec uncoreramdec(PhysicalAddress, `UNCORE_RAM_BASE, `UNCORE_RAM_RANGE, `UNCORE_RAM_SUPPORTED, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[5]);
|
||||||
adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[6]);
|
adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[4]);
|
||||||
adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[5]);
|
adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[3]);
|
||||||
adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[4]);
|
adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[2]);
|
||||||
adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[3]);
|
adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[1]);
|
||||||
adrdec sdcdec(PhysicalAddress, `SDC_BASE, `SDC_RANGE, `SDC_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE & 4'b1100, SelRegions[2]);
|
adrdec sdcdec(PhysicalAddress, `SDC_BASE, `SDC_RANGE, `SDC_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE & 4'b1100, SelRegions[0]);
|
||||||
|
|
||||||
adrdec iromdec(PhysicalAddress, `IROM_BASE, `IROM_RANGE, `IROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[1]);
|
assign SelRegions[8] = ~|(SelRegions[7:0]); // none of the regions are selected
|
||||||
adrdec dtimdec(PhysicalAddress, `DTIM_BASE, `DTIM_RANGE, `DTIM_SUPPORTED, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[0]);
|
|
||||||
|
|
||||||
assign SelRegions[10] = ~|(SelRegions[9:0]); // none of the regions are selected
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
|
|||||||
// x1 - TLB is accessed for a write
|
// x1 - TLB is accessed for a write
|
||||||
// 11 - TLB is accessed for both read and write
|
// 11 - TLB is accessed for both read and write
|
||||||
input logic DisableTranslation,
|
input logic DisableTranslation,
|
||||||
|
input logic SelTIM, // access to DTIM or IROM; ignore other access checking
|
||||||
|
|
||||||
// VAdr is the virtual/physical address from IEU or physical address from HPTW.
|
// VAdr is the virtual/physical address from IEU or physical address from HPTW.
|
||||||
// PhysicalAddress is selected to be PAdr when no translation or the translated VAdr (TLBPAdr)
|
// PhysicalAddress is selected to be PAdr when no translation or the translated VAdr (TLBPAdr)
|
||||||
@ -125,7 +126,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
|
|||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
|
||||||
pmachecker pmachecker(.PhysicalAddress, .Size,
|
pmachecker pmachecker(.PhysicalAddress, .Size,
|
||||||
.AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM,
|
.AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .SelTIM,
|
||||||
.Cacheable, .Idempotent, .AtomicAllowed,
|
.Cacheable, .Idempotent, .AtomicAllowed,
|
||||||
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
|
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ 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 AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // *** atomicaccessM is unused but might want to stay in for future use.
|
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // *** atomicaccessM is unused but might want to stay in for future use.
|
||||||
|
input logic SelTIM,
|
||||||
output logic Cacheable, Idempotent, AtomicAllowed,
|
output logic Cacheable, Idempotent, AtomicAllowed,
|
||||||
output logic PMAInstrAccessFaultF,
|
output logic PMAInstrAccessFaultF,
|
||||||
output logic PMALoadAccessFaultM,
|
output logic PMALoadAccessFaultM,
|
||||||
@ -46,7 +47,7 @@ module pmachecker (
|
|||||||
|
|
||||||
logic PMAAccessFault;
|
logic PMAAccessFault;
|
||||||
logic AccessRW, AccessRWX, AccessRX;
|
logic AccessRW, AccessRWX, AccessRX;
|
||||||
logic [10:0] SelRegions;
|
logic [8:0] SelRegions;
|
||||||
|
|
||||||
// Determine what type of access is being made
|
// Determine what type of access is being made
|
||||||
assign AccessRW = ReadAccessM | WriteAccessM;
|
assign AccessRW = ReadAccessM | WriteAccessM;
|
||||||
@ -57,12 +58,12 @@ module pmachecker (
|
|||||||
adrdecs adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWX, Size, SelRegions);
|
adrdecs adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWX, Size, SelRegions);
|
||||||
|
|
||||||
// Only non-core RAM/ROM memory regions are cacheable
|
// Only non-core RAM/ROM memory regions are cacheable
|
||||||
assign Cacheable = SelRegions[9] | SelRegions[8] | SelRegions[7];
|
assign Cacheable = SelRegions[7] | SelRegions[6] | SelRegions[5];
|
||||||
assign Idempotent = SelRegions[9] | SelRegions[7];
|
assign Idempotent = SelRegions[7] | SelRegions[5];
|
||||||
assign AtomicAllowed = SelRegions[9] | SelRegions[7];
|
assign AtomicAllowed = SelRegions[7] | SelRegions[5];
|
||||||
|
|
||||||
// Detect access faults
|
// Detect access faults
|
||||||
assign PMAAccessFault = SelRegions[10] & AccessRWX;
|
assign PMAAccessFault = (SelRegions[8] & ~SelTIM) & AccessRWX;
|
||||||
assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault;
|
assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault;
|
||||||
assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault;
|
assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault;
|
||||||
assign PMAStoreAmoAccessFaultM = WriteAccessM & PMAAccessFault;
|
assign PMAStoreAmoAccessFaultM = WriteAccessM & PMAAccessFault;
|
||||||
|
@ -67,7 +67,7 @@ module uncore (
|
|||||||
|
|
||||||
logic [`XLEN-1:0] HREADRam, HREADSDC;
|
logic [`XLEN-1:0] HREADRam, HREADSDC;
|
||||||
|
|
||||||
logic [10:0] HSELRegions;
|
logic [8:0] HSELRegions;
|
||||||
logic HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
|
logic HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
|
||||||
logic HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
|
logic HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
|
||||||
logic HRESPRam, HRESPSDC;
|
logic HRESPRam, HRESPSDC;
|
||||||
@ -93,7 +93,7 @@ module uncore (
|
|||||||
adrdecs adrdecs(HADDR, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions);
|
adrdecs adrdecs(HADDR, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions);
|
||||||
|
|
||||||
// unswizzle HSEL signals
|
// unswizzle HSEL signals
|
||||||
assign {HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[9:2];
|
assign {HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[7:0];
|
||||||
|
|
||||||
// AHB -> APB bridge
|
// AHB -> APB bridge
|
||||||
ahbapbbridge #(4) ahbapbbridge
|
ahbapbbridge #(4) ahbapbbridge
|
||||||
@ -197,7 +197,7 @@ module uncore (
|
|||||||
HSELNoneD; // don't lock up the bus if no region is being accessed
|
HSELNoneD; // don't lock up the bus if no region is being accessed
|
||||||
|
|
||||||
// Address Decoder Delay (figure 4-2 in spec)
|
// Address Decoder Delay (figure 4-2 in spec)
|
||||||
flopr #(9) hseldelayreg(HCLK, ~HRESETn, HSELRegions[10:2], {HSELNoneD, HSELEXTD, HSELBootRomD, HSELRamD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD});
|
flopr #(9) hseldelayreg(HCLK, ~HRESETn, HSELRegions, {HSELNoneD, HSELEXTD, HSELBootRomD, HSELRamD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD});
|
||||||
flopr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HSELBRIDGE, HSELBRIDGED);
|
flopr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HSELBRIDGE, HSELBRIDGED);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user