Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main

This commit is contained in:
Ross Thompson 2021-06-23 09:34:42 -05:00
commit 349f6a9471
10 changed files with 87 additions and 76 deletions

View File

@ -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/*

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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];

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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),