diff --git a/pipelined/regression/regression-wally b/pipelined/regression/regression-wally index 4761fa6c4..20519bbb8 100755 --- a/pipelined/regression/regression-wally +++ b/pipelined/regression/regression-wally @@ -82,7 +82,7 @@ for test in tests32gc: grepstr="All tests ran without failures") configs.append(tc) -tests32ic = ["arch32i", "arch32c", "imperas32i", "imperas32c", "wally32priv", "wally32periph"] +tests32ic = ["arch32i", "arch32c", "imperas32i", "imperas32c", "wally32periph"] for test in tests32ic: tc = TestCase( name=test, diff --git a/pipelined/regression/sim-wally b/pipelined/regression/sim-wally index 6163ab8b1..583396fd7 100755 --- a/pipelined/regression/sim-wally +++ b/pipelined/regression/sim-wally @@ -1,2 +1,2 @@ -vsim -do "do wally-pipelined.do rv32gc wally32periph" +vsim -do "do wally-pipelined.do rv32ic wally32periph" diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index 0d67601cc..61fbde018 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -93,6 +93,7 @@ module ifu ( logic CompressedF; logic [31:0] InstrRawD, InstrRawF; logic [31:0] FinalInstrRawF; + logic [1:0] NonIROMMemRWM; logic [31:0] InstrE; logic [`XLEN-1:0] PCD; @@ -113,6 +114,7 @@ module ifu ( logic BusStall; logic ICacheStallF, IFUCacheBusStallF; logic CPUBusy; + logic SelIROM; (* mark_debug = "true" *) logic [31:0] PostSpillInstrRawF; // branch predictor signal logic [`XLEN-1:0] PCNext1F, PCNext2F, PCNext0F; @@ -154,7 +156,7 @@ module ifu ( mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1)) 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), .Size(2'b10), .PTE(PTE), @@ -184,10 +186,21 @@ module ifu ( logic [`XLEN-1:0] AllInstrRawF; assign InstrRawF = AllInstrRawF[31:0]; + // The IROM uses untranslated addresses, so it is not compatible with virtual memory. 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)); - end + end else begin + assign SelIROM = 0; assign NonIROMMemRWM = 2'b10; + end if (`BUS) begin : bus localparam integer WORDSPERLINE = `ICACHE ? `ICACHE_LINELENINBITS/`XLEN : 1; localparam integer LOGBWPL = `ICACHE ? $clog2(WORDSPERLINE) : 1; @@ -210,7 +223,7 @@ module ifu ( .CacheMiss(ICacheMiss), .CacheAccess(ICacheAccess), .ByteMask('0), .WordCount('0), .SelBusWord('0), .FinalWriteData('0), - .RW(2'b10), + .RW(NonIROMMemRWM), .Atomic('0), .FlushCache('0), .NextAdr(PCNextFSpill[11:0]), .PAdr(PCPF), @@ -225,7 +238,7 @@ module ifu ( .CacheWriteLine(1'b0), .CacheBusAck(ICacheBusAck), .FetchBuffer, .PAdr(PCPF), .SelUncachedAdr, - .IgnoreRequest(ITLBMissF), .RW(2'b10), .CPUBusy, .Cacheable(CacheableF), + .IgnoreRequest(ITLBMissF), .RW(NonIROMMemRWM), .CPUBusy, .Cacheable(CacheableF), .BusStall, .BusCommitted()); 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])); busfsm #(LOGBWPL) busfsm( - .clk, .reset, .IgnoreRequest(ITLBMissF), .RW(2'b10), + .clk, .reset, .IgnoreRequest(ITLBMissF), .RW(NonIROMMemRWM), .BusAck(IFUBusAck), .BusInit(IFUBusInit), .CPUBusy, .BusStall, .BusWrite(), .BusRead(IFUBusRead), .HTRANS(IFUHTRANS), .BusCommitted()); diff --git a/pipelined/src/lsu/lsu.sv b/pipelined/src/lsu/lsu.sv index 57d34d9da..50f680581 100644 --- a/pipelined/src/lsu/lsu.sv +++ b/pipelined/src/lsu/lsu.sv @@ -94,8 +94,7 @@ module lsu ( logic [`PA_BITS-1:0] LSUPAdrM; logic DTLBMissM; logic DTLBWriteM; - logic [1:0] LSURWM; - logic [1:0] PreLSURWM; + logic [1:0] NonDTIMMemRWM, PreLSURWM, LSURWM; logic [2:0] LSUFunct3M; logic [6:0] LSUFunct7M; logic [1:0] LSUAtomicM; @@ -125,7 +124,7 @@ module lsu ( ///////////////////////////////////////////////////////////////////////////////////////////// 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, .TrapM, .DCacheStallM, .SATP_REGW, .PCF, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW, @@ -135,7 +134,7 @@ module lsu ( .IgnoreRequestTLB); end else begin 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 PreLSUPAdrM = IEUAdrExtM; assign LSUFunct3M = Funct3M; assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM; @@ -156,7 +155,7 @@ module lsu ( assign DisableTranslation = SelHPTW | FlushDCacheM; mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0)) dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, - .PrivilegeModeW, .DisableTranslation, + .PrivilegeModeW, .DisableTranslation, .SelTIM(SelDTIM), .VAdr(PreLSUPAdrM), .Size(LSUFunct3M[1:0]), .PTE, @@ -196,21 +195,24 @@ module lsu ( if (`DTIM_SUPPORTED) begin : dtim logic [`PA_BITS-1:0] DTIMAdr; logic DTIMAccessRW; + logic MemStage; // The DTIM uses untranslated addresses, so it is not compatible with virtual memory. // Don't perform size checking on DTIM /* 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 */ 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, .Adr(DTIMAdr), .TrapM, .WriteDataM(LSUWriteDataM), .ReadDataWordM(ReadDataWordM[`XLEN-1:0]), .ByteMaskM(ByteMaskM[`XLEN/8-1:0])); end else begin - assign SelDTIM = 0; + assign SelDTIM = 0; assign NonDTIMMemRWM = MemRWM; end if (`BUS) begin : bus localparam integer WORDSPERLINE = `DCACHE ? `DCACHE_LINELENINBITS/`XLEN : 1; diff --git a/pipelined/src/mmu/adrdecs.sv b/pipelined/src/mmu/adrdecs.sv index 9fd462fc7..59acbd13d 100644 --- a/pipelined/src/mmu/adrdecs.sv +++ b/pipelined/src/mmu/adrdecs.sv @@ -35,24 +35,21 @@ module adrdecs ( input logic [`PA_BITS-1:0] PhysicalAddress, input logic AccessRW, AccessRX, AccessRWX, 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); // 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 bootromdec(PhysicalAddress, `BOOTROM_BASE, `BOOTROM_RANGE, `BOOTROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[8]); - adrdec uncoreramdec(PhysicalAddress, `UNCORE_RAM_BASE, `UNCORE_RAM_RANGE, `UNCORE_RAM_SUPPORTED, AccessRWX, Size, SUPPORTED_SIZE, SelRegions[7]); - adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[6]); - adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[5]); - adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[4]); - adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[3]); - adrdec sdcdec(PhysicalAddress, `SDC_BASE, `SDC_RANGE, `SDC_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE & 4'b1100, SelRegions[2]); + 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[6]); + 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[4]); + 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[2]); + 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[0]); - adrdec iromdec(PhysicalAddress, `IROM_BASE, `IROM_RANGE, `IROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[1]); - 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 + assign SelRegions[8] = ~|(SelRegions[7:0]); // none of the regions are selected endmodule diff --git a/pipelined/src/mmu/mmu.sv b/pipelined/src/mmu/mmu.sv index dbf23e98e..389057df7 100644 --- a/pipelined/src/mmu/mmu.sv +++ b/pipelined/src/mmu/mmu.sv @@ -48,6 +48,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries // x1 - TLB is accessed for a write // 11 - TLB is accessed for both read and write 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. // 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, - .AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, + .AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .SelTIM, .Cacheable, .Idempotent, .AtomicAllowed, .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM); diff --git a/pipelined/src/mmu/pmachecker.sv b/pipelined/src/mmu/pmachecker.sv index c11b8bcdb..0d299bbd2 100644 --- a/pipelined/src/mmu/pmachecker.sv +++ b/pipelined/src/mmu/pmachecker.sv @@ -38,6 +38,7 @@ module pmachecker ( input logic [`PA_BITS-1:0] PhysicalAddress, 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 SelTIM, output logic Cacheable, Idempotent, AtomicAllowed, output logic PMAInstrAccessFaultF, output logic PMALoadAccessFaultM, @@ -46,7 +47,7 @@ module pmachecker ( logic PMAAccessFault; logic AccessRW, AccessRWX, AccessRX; - logic [10:0] SelRegions; + logic [8:0] SelRegions; // Determine what type of access is being made assign AccessRW = ReadAccessM | WriteAccessM; @@ -57,12 +58,12 @@ module pmachecker ( adrdecs adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWX, Size, SelRegions); // Only non-core RAM/ROM memory regions are cacheable - assign Cacheable = SelRegions[9] | SelRegions[8] | SelRegions[7]; - assign Idempotent = SelRegions[9] | SelRegions[7]; - assign AtomicAllowed = SelRegions[9] | SelRegions[7]; + assign Cacheable = SelRegions[7] | SelRegions[6] | SelRegions[5]; + assign Idempotent = SelRegions[7] | SelRegions[5]; + assign AtomicAllowed = SelRegions[7] | SelRegions[5]; // Detect access faults - assign PMAAccessFault = SelRegions[10] & AccessRWX; + assign PMAAccessFault = (SelRegions[8] & ~SelTIM) & AccessRWX; assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault; assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault; assign PMAStoreAmoAccessFaultM = WriteAccessM & PMAAccessFault; diff --git a/pipelined/src/uncore/uncore.sv b/pipelined/src/uncore/uncore.sv index 1eec29f82..ecb2fe130 100644 --- a/pipelined/src/uncore/uncore.sv +++ b/pipelined/src/uncore/uncore.sv @@ -67,7 +67,7 @@ module uncore ( logic [`XLEN-1:0] HREADRam, HREADSDC; - logic [10:0] HSELRegions; + logic [8:0] HSELRegions; logic HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC; logic HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD; logic HRESPRam, HRESPSDC; @@ -93,7 +93,7 @@ module uncore ( adrdecs adrdecs(HADDR, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions); // 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 ahbapbbridge #(4) ahbapbbridge @@ -197,7 +197,7 @@ module uncore ( HSELNoneD; // don't lock up the bus if no region is being accessed // 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); endmodule