diff --git a/wally-pipelined/regression/wave-dos/peripheral-waves.do b/wally-pipelined/regression/wave-dos/peripheral-waves.do index 5c9f38703..1304b40c6 100644 --- a/wally-pipelined/regression/wave-dos/peripheral-waves.do +++ b/wally-pipelined/regression/wave-dos/peripheral-waves.do @@ -65,17 +65,17 @@ add wave -hex /testbench/dut/hart/priv/csr/genblk1/csrm/MEPC_REGW add wave -divider # peripherals -add wave -hex /testbench/dut/uncore/plic/* -add wave -hex /testbench/dut/uncore/plic/intPriority -add wave -hex /testbench/dut/uncore/plic/pendingArray -add wave -divider -add wave -hex /testbench/dut/uncore/uart/u/* -add wave -divider -add wave -hex /testbench/dut/uncore/gpio/* -add wave -divider -add wave -hex /testbench/dut/hart/ebu/* -add wave -divider -add wave -divider +#add wave -hex /testbench/dut/uncore/plic/* +#add wave -hex /testbench/dut/uncore/plic/intPriority +#add wave -hex /testbench/dut/uncore/plic/pendingArray +#add wave -divider +#add wave -hex /testbench/dut/uncore/uart/u/* +#add wave -divider +#add wave -hex /testbench/dut/uncore/gpio/* +#add wave -divider +#add wave -hex /testbench/dut/hart/ebu/* +#add wave -divider +#add wave -divider # everything else add wave -hex -r /testbench/* diff --git a/wally-pipelined/src/dmem/dcache.sv b/wally-pipelined/src/lsu/dcache.sv similarity index 100% rename from wally-pipelined/src/dmem/dcache.sv rename to wally-pipelined/src/lsu/dcache.sv diff --git a/wally-pipelined/src/dmem/dmem.sv b/wally-pipelined/src/lsu/lsu.sv similarity index 99% rename from wally-pipelined/src/dmem/dmem.sv rename to wally-pipelined/src/lsu/lsu.sv index 7f19bc78f..ffa79adfe 100644 --- a/wally-pipelined/src/dmem/dmem.sv +++ b/wally-pipelined/src/lsu/lsu.sv @@ -1,10 +1,10 @@ /////////////////////////////////////////// -// dmem.sv +// lsu.sv // // Written: David_Harris@hmc.edu 9 January 2021 // Modified: // -// Purpose: Data memory +// Purpose: Load/Store Unit // Top level of the memory-stage hart logic // Contains data cache, DTLB, subword read/write datapath, interface to external bus // @@ -28,7 +28,7 @@ `include "wally-config.vh" // *** Ross Thompson amo misalignment check? -module dmem ( +module lsu ( input logic clk, reset, input logic StallM, FlushM, StallW, FlushW, //output logic DataStall, diff --git a/wally-pipelined/src/mmu/adrdec.sv b/wally-pipelined/src/mmu/adrdec.sv index 7e4423ec1..e2c63731b 100644 --- a/wally-pipelined/src/mmu/adrdec.sv +++ b/wally-pipelined/src/mmu/adrdec.sv @@ -28,17 +28,25 @@ 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 ); - logic [31:0] match; + logic Match; + logic SizeValid; // 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 = (HADDR ~^ Base) | Range; - assign HSEL = &match; + // determine if legal size of access is being made (byte, halfword, word, doubleword) + assign SizeValid = SizeMask[Size[1:0]]; + + assign HSEL = Match && Supported && AccessValid && SizeValid; endmodule diff --git a/wally-pipelined/src/mmu/pmaadrdec.sv b/wally-pipelined/src/mmu/adrdecs.sv similarity index 54% rename from wally-pipelined/src/mmu/pmaadrdec.sv rename to wally-pipelined/src/mmu/adrdecs.sv index c48cdc665..17f78d515 100644 --- a/wally-pipelined/src/mmu/pmaadrdec.sv +++ b/wally-pipelined/src/mmu/adrdecs.sv @@ -1,10 +1,10 @@ /////////////////////////////////////////// -// pmaadrdec.sv +// adrdecs.sv // -// Written: David_Harris@hmc.edu 29 January 2021 +// Written: David_Harris@hmc.edu 22 June 2021 // Modified: // -// Purpose: Address decoder +// Purpose: All the address decoders for peripherals // // A component of the Wally configurable RISC-V project. // @@ -25,28 +25,20 @@ `include "wally-config.vh" -module pmaadrdec ( - 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 +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 ); - logic Match; - logic SizeValid; - - // 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); - - // determine if legal size of access is being made (byte, halfword, word, doubleword) - assign SizeValid = SizeMask[Size[1:0]]; - - assign HSEL = Match && Supported && AccessValid && SizeValid; - + // 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]); endmodule diff --git a/wally-pipelined/src/mmu/pmachecker.sv b/wally-pipelined/src/mmu/pmachecker.sv index d771839e8..1d8cc3ee3 100644 --- a/wally-pipelined/src/mmu/pmachecker.sv +++ b/wally-pipelined/src/mmu/pmachecker.sv @@ -58,13 +58,7 @@ module pmachecker ( assign AccessRX = ReadAccessM | ExecuteAccessF; // Determine which region of physical memory (if any) is being accessed - // *** linux tests fail early when Access is anything other than 1b1 - pmaadrdec boottimdec(HADDR, `BOOTTIM_BASE, `BOOTTIM_RANGE, `BOOTTIM_SUPPORTED, 1'b1/*AccessRX*/, HSIZE, 4'b1111, HSELRegions[5]); - pmaadrdec timdec(HADDR, `TIM_BASE, `TIM_RANGE, `TIM_SUPPORTED, 1'b1/*AccessRWX*/, HSIZE, 4'b1111, HSELRegions[4]); - pmaadrdec clintdec(HADDR, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, HSIZE, 4'b1111, HSELRegions[3]); - pmaadrdec gpiodec(HADDR, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, HSIZE, 4'b0100, HSELRegions[2]); - pmaadrdec uartdec(HADDR, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, HSIZE, 4'b0001, HSELRegions[1]); - pmaadrdec plicdec(HADDR, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, HSIZE, 4'b0100, HSELRegions[0]); + adrdecs adrdecs(HADDR, AccessRW, AccessRX, AccessRWX, HSIZE, HSELRegions); // Only RAM memory regions are cacheable assign Cacheable = HSELRegions[5] | HSELRegions[4]; diff --git a/wally-pipelined/src/mmu/pmpadrdec.sv b/wally-pipelined/src/mmu/pmpadrdec.sv index f9e86cdc7..87f5d8f1e 100644 --- a/wally-pipelined/src/mmu/pmpadrdec.sv +++ b/wally-pipelined/src/mmu/pmpadrdec.sv @@ -30,11 +30,8 @@ `include "wally-config.vh" module pmpadrdec ( - input logic [31:0] HADDR, - + input logic [31:0] HADDR, // *** replace with PAdr input logic [1:0] AdrMode, - - // input logic [`XLEN-1:0] PreviousPMPAdr, input logic [`XLEN-1:0] CurrentPMPAdr, input logic AdrAtLeastPreviousPMP, output logic AdrAtLeastCurrentPMP, @@ -45,35 +42,48 @@ module pmpadrdec ( localparam NA4 = 2'b10; localparam NAPOT = 2'b11; - logic TORMatch, NA4Match, NAPOTMatch; - + logic TORMatch, NAMatch; logic AdrBelowCurrentPMP; + logic [`PA_BITS-1:0] CurrentAdrFull; + logic [`PA_BITS-1:0] FakePhysAdr; - logic [31:0] CurrentAdrFull; - // logic [31:0] PreviousAdrFull; - - logic [33:0] Range; - - //assign PreviousAdrFull = {PreviousPMPAdr[29:0], 2'b00}; - assign CurrentAdrFull = {CurrentPMPAdr[29:0], 2'b00}; - + // ***replace this when the true physical address from MMU is available + assign FakePhysAdr = {{(`PA_BITS-32){1'b0}}, HADDR}; + // Top-of-range (TOR) - // *** Check if this synthesizes - // if not, literally do comparison (HADDR - PreviousAdrFull == 0) - assign AdrBelowCurrentPMP = HADDR < CurrentAdrFull; + // 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 AdrAtLeastCurrentPMP = ~AdrBelowCurrentPMP; assign TORMatch = AdrAtLeastPreviousPMP && AdrBelowCurrentPMP; - // Naturally aligned four-byte region - adrdec na4dec(HADDR, CurrentAdrFull, (2**2)-1, NA4Match); + // Naturally aligned regions + // *** should be able to optimize away bottom 2 bits + // verilator lint_off UNOPTFLAT + logic [`PA_BITS-1:0] Mask; + genvar i; + + // create a mask of which bits to ignore generate - if (`XLEN == 32 || `XLEN == 64) begin + assign Mask[1:0] = 2'b11; + assign Mask[2] = (AdrMode == NAPOT); // mask has 0s in upper bis for NA4 region + for (i=3; i < `PA_BITS; i=i+1) + assign Mask[i] = Mask[i-1] & CurrentPMPAdr[i-3]; // NAPOT mask: 1's indicate bits to ignore + endgenerate + // verilator lint_on UNOPTFLAT + + assign NAMatch = &((FakePhysAdr ~^ CurrentAdrFull) | Mask); + + /* generate + if (`XLEN == 32 || `XLEN == 64) begin // ***redo for various sizes // priority encoder to translate address to range // *** We'd like to replace this with a better priority encoder // *** We should not be truncating 64 bit physical addresses to 32 bits... + // *** there is an easy combinatinoal way to do this with a cascade of AND gates O(32) rather than O(32^2) dh always_comb - casez (CurrentPMPAdr[31:0]) + if (AdrMode == NA4) Range = (2**2) - 1; + else casez (CurrentPMPAdr[31:0]) // NAPOT regions 32'b???????????????????????????????0: Range = (2**3) - 1; 32'b??????????????????????????????01: Range = (2**4) - 1; 32'b?????????????????????????????011: Range = (2**5) - 1; @@ -112,15 +122,15 @@ module pmpadrdec ( end else begin assign Range = '0; end - endgenerate + endgenerate // *** Range should not be truncated... but our physical address space is // currently only 32 bits wide. - adrdec napotdec(HADDR, CurrentAdrFull, Range[31:0], NAPOTMatch); + // with a bit of combining of range selection, this could be shared with NA4Match *** + assign NAMatch = &((HADDR ~^ CurrentAdrFull) | Range[31:0]);*/ assign Match = (AdrMode == TOR) ? TORMatch : - (AdrMode == NA4) ? NA4Match : - (AdrMode == NAPOT) ? NAPOTMatch : + (AdrMode == NA4 || AdrMode == NAPOT) ? NAMatch : 0; endmodule diff --git a/wally-pipelined/src/mmu/pmpchecker.sv b/wally-pipelined/src/mmu/pmpchecker.sv index 8b33ccf3a..f88d56fa0 100644 --- a/wally-pipelined/src/mmu/pmpchecker.sv +++ b/wally-pipelined/src/mmu/pmpchecker.sv @@ -76,6 +76,8 @@ module pmpchecker ( logic L_Bit, X_Bit, W_Bit, R_Bit; logic InvalidExecute, InvalidWrite, InvalidRead; + // *** extend to optionally 64 configurations + assign {PMPCFG[15], PMPCFG[14], PMPCFG[13], PMPCFG[12], PMPCFG[11], PMPCFG[10], PMPCFG[9], PMPCFG[8]} = PMPCFG23_REGW; @@ -107,6 +109,7 @@ module pmpchecker ( // Only enforce PMP checking for S and U modes when at least one PMP is active assign EnforcePMP = |ActiveRegion; + // *** extend to up to 64, fold bit extraction to avoid need for binary encoding of region always_comb casez (Regions) 16'b???????????????1: MatchedRegion = 0; @@ -137,6 +140,7 @@ module pmpchecker ( assign InvalidWrite = WriteAccessM && ~W_Bit; assign InvalidRead = ReadAccessM && ~R_Bit; + // *** don't cause faults when there are no PMPs assign PMPInstrAccessFaultF = (PrivilegeModeW == `M_MODE) ? Match && L_Bit && InvalidExecute : EnforcePMP && InvalidExecute; diff --git a/wally-pipelined/src/uncore/uncore.sv b/wally-pipelined/src/uncore/uncore.sv index a100d76f9..cb0a8c2ac 100644 --- a/wally-pipelined/src/uncore/uncore.sv +++ b/wally-pipelined/src/uncore/uncore.sv @@ -47,8 +47,6 @@ module uncore ( input logic [2:0] HADDRD, input logic [3:0] HSIZED, input logic HWRITED, - // PMA checker signals - input logic [5:0] HSELRegions, // bus interface // PMA checker now handles access faults. *** This can be deleted // output logic DataAccessFaultM, @@ -64,6 +62,7 @@ module uncore ( logic [`XLEN-1:0] HWDATA; logic [`XLEN-1:0] HREADTim, HREADCLINT, HREADPLIC, HREADGPIO, HREADUART; + logic [5:0] HSELRegions; logic HSELTim, HSELCLINT, HSELPLIC, HSELGPIO, PreHSELUART, HSELUART; logic HSELTimD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD; logic HRESPTim, HRESPCLINT, HRESPPLIC, HRESPGPIO, HRESPUART; @@ -73,6 +72,10 @@ module uncore ( logic [1:0] MemRWboottim; logic UARTIntr,GPIOIntr; + // Determine which region of physical memory (if any) is being accessed + // Use a trimmed down portion of the PMA checker - only the address decoders + adrdecs adrdecs(HADDR, 1'b1, 1'b1, 1'b1, HSIZE, HSELRegions); + // unswizzle HSEL signals assign {HSELBootTim, HSELTim, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC} = HSELRegions; diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index bb35d4831..8e71f4452 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -161,7 +161,7 @@ module wallypipelinedhart ( mux2 #(`XLEN) OutputInput2mux(WriteDataM, FWriteDataM, FMemRWM[0], WriteDatatmpM); - dmem dmem(.MemRWM(MemRWM|FMemRWM), .WriteDataM(WriteDatatmpM),.*); // data cache unit + lsu lsu(.MemRWM(MemRWM|FMemRWM), .WriteDataM(WriteDatatmpM),.*); // data cache unit ahblite ebu( //.InstrReadF(1'b0),