mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main
This commit is contained in:
commit
349f6a9471
@ -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/*
|
||||
|
@ -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,
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user