forked from Github_Repos/cvw
thomas fixed it before I did
This commit is contained in:
commit
86946266cf
@ -13,12 +13,13 @@ if ($#ARGV == -1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# array to hold contents of memory file
|
# array to hold contents of memory file
|
||||||
my @memfilebytes = (0)*16384*4;
|
my $maxmemfilesize = 1000000;
|
||||||
|
my @memfilebytes = (0)*$maxmemfilesize*4;
|
||||||
my $maxaddress = 0;
|
my $maxaddress = 0;
|
||||||
|
|
||||||
STDOUT->autoflush(1);
|
STDOUT->autoflush(1);
|
||||||
# *** Ross Thompson I think there is a bug here needs to be +1
|
my $numfiles = $#ARGV+1;
|
||||||
print ("Processing $#ARGV memfiles: ");
|
print ("Processing $numfiles memfiles: ");
|
||||||
my $frac = $#ARGV/10;
|
my $frac = $#ARGV/10;
|
||||||
for(my $i=0; $i<=$#ARGV; $i++) {
|
for(my $i=0; $i<=$#ARGV; $i++) {
|
||||||
if ($i < 10 || $i % $frac == 0) { print ("$i ") };
|
if ($i < 10 || $i % $frac == 0) { print ("$i ") };
|
||||||
@ -43,7 +44,7 @@ for(my $i=0; $i<=$#ARGV; $i++) {
|
|||||||
my $address;
|
my $address;
|
||||||
|
|
||||||
# initialize to all zeros;
|
# initialize to all zeros;
|
||||||
for (my $i=0; $i < 65536*4; $i++) {
|
for (my $i=0; $i < $maxmemfilesize*4; $i++) {
|
||||||
$memfilebytes[$i] = "00";
|
$memfilebytes[$i] = "00";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +85,11 @@ for(my $i=0; $i<=$#ARGV; $i++) {
|
|||||||
open(MEMFILE, ">$memfile") || die("Can't write $memfile");
|
open(MEMFILE, ">$memfile") || die("Can't write $memfile");
|
||||||
for (my $i=0; $i<= $maxaddress; $i = $i + 4) {
|
for (my $i=0; $i<= $maxaddress; $i = $i + 4) {
|
||||||
for ($j=3; $j>=0; $j--) {
|
for ($j=3; $j>=0; $j--) {
|
||||||
print MEMFILE "$memfilebytes[$i+$j]";
|
if (defined($memfilebytes[$i+$j])) {
|
||||||
|
print MEMFILE "$memfilebytes[$i+$j]";
|
||||||
|
} else {
|
||||||
|
print MEMFILE "00";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
print MEMFILE "\n";
|
print MEMFILE "\n";
|
||||||
}
|
}
|
||||||
@ -93,7 +98,11 @@ for(my $i=0; $i<=$#ARGV; $i++) {
|
|||||||
open(MEMFILE, ">$memfile") || die("Can't write $memfile");
|
open(MEMFILE, ">$memfile") || die("Can't write $memfile");
|
||||||
for (my $i=0; $i<= $maxaddress; $i = $i + 8) {
|
for (my $i=0; $i<= $maxaddress; $i = $i + 8) {
|
||||||
for ($j=7; $j>=0; $j--) {
|
for ($j=7; $j>=0; $j--) {
|
||||||
print MEMFILE "$memfilebytes[$i+$j]";
|
if (defined($memfilebytes[$i+$j])) {
|
||||||
|
print MEMFILE "$memfilebytes[$i+$j]";
|
||||||
|
} else {
|
||||||
|
print MEMFILE "00";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
print MEMFILE "\n";
|
print MEMFILE "\n";
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
# The verilator lint tool is faster and better than Modelsim so it is best to run this first.
|
# The verilator lint tool is faster and better than Modelsim so it is best to run this first.
|
||||||
|
|
||||||
echo "rv64ic linting..."
|
echo "rv64ic linting..."
|
||||||
verilator --lint-only --top-module wallypipelinedsoc -Iconfig/rv64ic src/*/*.sv
|
verilator --lint-only "$@" --top-module wallypipelinedsoc -Iconfig/rv64ic src/*/*.sv
|
||||||
echo "rv32ic linting..."
|
echo "rv32ic linting..."
|
||||||
verilator --lint-only --top-module wallypipelinedsoc -Iconfig/rv32ic src/*/*.sv
|
verilator --lint-only "$@" --top-module wallypipelinedsoc -Iconfig/rv32ic src/*/*.sv
|
||||||
#verilator --lint-only --top-module wallypipelinedsoc -Iconfig/rv64ic src/*/*.sv src/*/div/*.sv
|
#verilator --lint-only --top-module wallypipelinedsoc -Iconfig/rv64ic src/*/*.sv src/*/div/*.sv
|
||||||
|
|
||||||
# --lint-only just runs lint rather than trying to compile and simulate
|
# --lint-only just runs lint rather than trying to compile and simulate
|
||||||
|
@ -8,8 +8,35 @@
|
|||||||
#
|
#
|
||||||
##################################
|
##################################
|
||||||
|
|
||||||
# edit this line to add more configurations
|
from collections import namedtuple
|
||||||
confignames = ["rv32ic", "rv64ic", "busybear"]
|
# name: the name of this test configuration/script
|
||||||
|
# cmd: the command to run to test (should include the logfile as {})
|
||||||
|
# grepstr: the string to grep through the log file for, success iff grep finds that string
|
||||||
|
Config = namedtuple("Config", ['name', 'cmd', 'grepstr'])
|
||||||
|
|
||||||
|
# edit this list to add more configurations
|
||||||
|
configs = [
|
||||||
|
Config(
|
||||||
|
name="busybear",
|
||||||
|
cmd="vsim -do wally-busybear-batch.do -c > {}",
|
||||||
|
grepstr="# loaded 800000 instructions"
|
||||||
|
),
|
||||||
|
Config(
|
||||||
|
name="buildroot",
|
||||||
|
cmd="vsim -do wally-buildroot-batch.do -c > {}",
|
||||||
|
grepstr="# loaded 100000 instructions"
|
||||||
|
),
|
||||||
|
Config(
|
||||||
|
name="rv32ic",
|
||||||
|
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do ../config/rv32ic rv32ic\n!",
|
||||||
|
grepstr="All tests ran without failures"
|
||||||
|
),
|
||||||
|
Config(
|
||||||
|
name="rv64ic",
|
||||||
|
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do ../config/rv64ic rv64ic\n!",
|
||||||
|
grepstr="All tests ran without failures"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
import multiprocessing, os
|
import multiprocessing, os
|
||||||
|
|
||||||
@ -21,35 +48,28 @@ def search_log_for_text(text, logfile):
|
|||||||
return os.system(grepcmd) == 0
|
return os.system(grepcmd) == 0
|
||||||
|
|
||||||
def test_config(config, print_res=True):
|
def test_config(config, print_res=True):
|
||||||
"""Run the given config, and return 0 if it suceeds and 1 if it fails"""
|
"""Run the given config, and return 0 if it suceeds and 1 if it fails"""
|
||||||
logname = "wally_"+config+".log"
|
logname = "wally_"+config.name+".log"
|
||||||
if config == "busybear":
|
cmd = config.cmd.format(logname)
|
||||||
# Handle busybear separately
|
|
||||||
cmd = "vsim -do wally-busybear-batch.do -c >" + logname
|
|
||||||
os.system(cmd)
|
|
||||||
# check for success. grep returns 0 if found, 1 if not found
|
|
||||||
passed = search_log_for_text("# loaded 800000 instructions", logname)
|
|
||||||
else:
|
|
||||||
# Any other configuration loads that name from the config folder and runs vsim
|
|
||||||
cmd = "vsim -c >" + logname +" <<!\ndo wally-pipelined-batch.do ../config/" + config + " " + config + "\n!\n"
|
|
||||||
print(cmd)
|
print(cmd)
|
||||||
os.system(cmd)
|
os.system(cmd)
|
||||||
# check for success. grep returns 0 if found, 1 if not found
|
# check for success. grep returns 0 if found, 1 if not found
|
||||||
passed = search_log_for_text("All tests ran without failures", logname)
|
passed = search_log_for_text(config.grepstr, logname)
|
||||||
if passed:
|
if passed:
|
||||||
if print_res:print(logname+": Success")
|
if print_res:print(logname+": Success")
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
if print_res:print(logname+": failures detected")
|
if print_res:print(logname+": failures detected")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
# Run the tests and count the failures
|
# Run the tests and count the failures
|
||||||
pool = multiprocessing.Pool(min(len(confignames), 12))
|
pool = multiprocessing.Pool(min(len(configs), 12))
|
||||||
fail = sum(pool.map(test_config, confignames))
|
fail = sum(pool.map(test_config, configs))
|
||||||
|
|
||||||
if (fail):
|
if (fail):
|
||||||
print ("Regression failed with " +str(fail)+ " failed configurations")
|
print("Regression failed with " +str(fail)+ " failed configurations")
|
||||||
exit(1)
|
print("Reminder: have you run `make allclean`?")
|
||||||
|
exit(1)
|
||||||
else:
|
else:
|
||||||
print ("SUCCESS! All tests ran without failures")
|
print("SUCCESS! All tests ran without failures")
|
||||||
exit(0)
|
exit(0)
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
package ahbliteState;
|
package ahbliteState;
|
||||||
typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, INSTRREADC, ATOMICREAD, ATOMICWRITE, MMUTRANSLATE, MMUIDLE} statetype;
|
typedef enum {IDLE, MEMREAD, MEMWRITE, INSTRREAD, INSTRREADC, ATOMICREAD, ATOMICWRITE, MMUTRANSLATE} statetype;
|
||||||
endpackage
|
endpackage
|
||||||
|
|
||||||
module ahblite (
|
module ahblite (
|
||||||
@ -51,10 +51,13 @@ module ahblite (
|
|||||||
input logic [`XLEN-1:0] WriteDataM,
|
input logic [`XLEN-1:0] WriteDataM,
|
||||||
input logic [1:0] MemSizeM,
|
input logic [1:0] MemSizeM,
|
||||||
// Signals from MMU
|
// Signals from MMU
|
||||||
|
input logic MMUStall,
|
||||||
input logic [`XLEN-1:0] MMUPAdr,
|
input logic [`XLEN-1:0] MMUPAdr,
|
||||||
input logic MMUTranslate, MMUTranslationComplete,
|
input logic MMUTranslate, MMUTranslationComplete,
|
||||||
output logic [`XLEN-1:0] MMUReadPTE,
|
output logic [`XLEN-1:0] MMUReadPTE,
|
||||||
output logic MMUReady,
|
output logic MMUReady,
|
||||||
|
// Signals from PMA checker
|
||||||
|
input logic SquashAHBAccess,
|
||||||
// Return from bus
|
// Return from bus
|
||||||
output logic [`XLEN-1:0] ReadDataW,
|
output logic [`XLEN-1:0] ReadDataW,
|
||||||
// AHB-Lite external signals
|
// AHB-Lite external signals
|
||||||
@ -102,6 +105,10 @@ module ahblite (
|
|||||||
|
|
||||||
flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextBusState, IDLE, BusState);
|
flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextBusState, IDLE, BusState);
|
||||||
|
|
||||||
|
// *** If the SquashAHBAccess signal is high, we need to set NextBusState to IDLE.
|
||||||
|
// We could either have this case statement set a signal ProposedNextBusState, which gets
|
||||||
|
// used for NextBusState when we are not squashing. Alternatively, we could add a bunch of
|
||||||
|
// conditional statments below
|
||||||
always_comb
|
always_comb
|
||||||
case (BusState)
|
case (BusState)
|
||||||
IDLE: if (MMUTranslate) NextBusState = MMUTRANSLATE;
|
IDLE: if (MMUTranslate) NextBusState = MMUTRANSLATE;
|
||||||
@ -136,11 +143,10 @@ module ahblite (
|
|||||||
// since translation might not be complete.
|
// since translation might not be complete.
|
||||||
assign #2 DataStall = ((NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
|
assign #2 DataStall = ((NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
|
||||||
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE) ||
|
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE) ||
|
||||||
(NextBusState == MMUTRANSLATE) || (MMUTranslate && ~MMUTranslationComplete));
|
MMUStall);
|
||||||
// *** Could get finer grained stalling if we distinguish between MMU
|
|
||||||
// instruction address translation and data address translation
|
|
||||||
assign #1 InstrStall = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) ||
|
assign #1 InstrStall = ((NextBusState == INSTRREAD) || (NextBusState == INSTRREADC) ||
|
||||||
(NextBusState == MMUTRANSLATE) || (MMUTranslate && ~MMUTranslationComplete));
|
MMUStall);
|
||||||
|
|
||||||
// Determine access type (important for determining whether to fault)
|
// Determine access type (important for determining whether to fault)
|
||||||
assign Atomic = ((NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE));
|
assign Atomic = ((NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE));
|
||||||
|
@ -60,6 +60,9 @@ module pagetablewalker (
|
|||||||
output logic MMUTranslate,
|
output logic MMUTranslate,
|
||||||
output logic MMUTranslationComplete,
|
output logic MMUTranslationComplete,
|
||||||
|
|
||||||
|
// Stall signal
|
||||||
|
output logic MMUStall,
|
||||||
|
|
||||||
// Faults
|
// Faults
|
||||||
output logic WalkerInstrPageFaultF,
|
output logic WalkerInstrPageFaultF,
|
||||||
output logic WalkerLoadPageFaultM,
|
output logic WalkerLoadPageFaultM,
|
||||||
@ -197,8 +200,12 @@ module pagetablewalker (
|
|||||||
WalkerInstrPageFaultF = '0;
|
WalkerInstrPageFaultF = '0;
|
||||||
WalkerLoadPageFaultM = '0;
|
WalkerLoadPageFaultM = '0;
|
||||||
WalkerStorePageFaultM = '0;
|
WalkerStorePageFaultM = '0;
|
||||||
|
MMUStall = '1;
|
||||||
|
|
||||||
case (NextWalkerState)
|
case (NextWalkerState)
|
||||||
|
IDLE: begin
|
||||||
|
MMUStall = '0;
|
||||||
|
end
|
||||||
LEVEL1: begin
|
LEVEL1: begin
|
||||||
TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00};
|
TranslationPAdr = {BasePageTablePPN, VPN1, 2'b00};
|
||||||
end
|
end
|
||||||
@ -220,6 +227,7 @@ module pagetablewalker (
|
|||||||
WalkerInstrPageFaultF = ~DTLBMissM;
|
WalkerInstrPageFaultF = ~DTLBMissM;
|
||||||
WalkerLoadPageFaultM = DTLBMissM && ~MemStore;
|
WalkerLoadPageFaultM = DTLBMissM && ~MemStore;
|
||||||
WalkerStorePageFaultM = DTLBMissM && MemStore;
|
WalkerStorePageFaultM = DTLBMissM && MemStore;
|
||||||
|
MMUStall = '0; // Drop the stall early to enter trap handling code
|
||||||
end
|
end
|
||||||
default: begin
|
default: begin
|
||||||
// nothing
|
// nothing
|
||||||
@ -302,8 +310,12 @@ module pagetablewalker (
|
|||||||
WalkerInstrPageFaultF = '0;
|
WalkerInstrPageFaultF = '0;
|
||||||
WalkerLoadPageFaultM = '0;
|
WalkerLoadPageFaultM = '0;
|
||||||
WalkerStorePageFaultM = '0;
|
WalkerStorePageFaultM = '0;
|
||||||
|
MMUStall = '1;
|
||||||
|
|
||||||
case (NextWalkerState)
|
case (NextWalkerState)
|
||||||
|
IDLE: begin
|
||||||
|
MMUStall = '0;
|
||||||
|
end
|
||||||
LEVEL2: begin
|
LEVEL2: begin
|
||||||
TranslationPAdr = {BasePageTablePPN, VPN2, 3'b000};
|
TranslationPAdr = {BasePageTablePPN, VPN2, 3'b000};
|
||||||
end
|
end
|
||||||
@ -329,6 +341,7 @@ module pagetablewalker (
|
|||||||
WalkerInstrPageFaultF = ~DTLBMissM;
|
WalkerInstrPageFaultF = ~DTLBMissM;
|
||||||
WalkerLoadPageFaultM = DTLBMissM && ~MemStore;
|
WalkerLoadPageFaultM = DTLBMissM && ~MemStore;
|
||||||
WalkerStorePageFaultM = DTLBMissM && MemStore;
|
WalkerStorePageFaultM = DTLBMissM && MemStore;
|
||||||
|
MMUStall = '0; // Drop the stall early to enter trap handling code
|
||||||
end
|
end
|
||||||
default: begin
|
default: begin
|
||||||
// nothing
|
// nothing
|
||||||
|
86
wally-pipelined/src/ebu/pmachecker.sv
Normal file
86
wally-pipelined/src/ebu/pmachecker.sv
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// pmachecker.sv
|
||||||
|
//
|
||||||
|
// Written: tfleming@hmc.edu & jtorrey@hmc.edu 20 April 2021
|
||||||
|
// Modified:
|
||||||
|
//
|
||||||
|
// Purpose: Examines all physical memory accesses and identifies attributes of
|
||||||
|
// the memory region accessed.
|
||||||
|
// Can report illegal accesses to the trap unit and cause a fault.
|
||||||
|
//
|
||||||
|
// A component of the Wally configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||||
|
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||||
|
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||||
|
// is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||||
|
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
module pmachecker (
|
||||||
|
input logic [31:0] HADDR,
|
||||||
|
input logic [2:0] HSIZE,
|
||||||
|
input logic HWRITE,
|
||||||
|
input logic [2:0] HBURST,
|
||||||
|
|
||||||
|
input logic Atomic, Execute, Write, Read,
|
||||||
|
|
||||||
|
// *** Add pipeline suffixes
|
||||||
|
output logic Cacheable, Idempotent, AtomicAllowed,
|
||||||
|
output logic SquashAHBAccess,
|
||||||
|
|
||||||
|
output logic [5:0] HSELRegions,
|
||||||
|
|
||||||
|
output logic InstrAccessFaultF,
|
||||||
|
output logic LoadAccessFaultM,
|
||||||
|
output logic StoreAccessFaultM
|
||||||
|
);
|
||||||
|
|
||||||
|
// Signals are high if the memory access is within the given region
|
||||||
|
logic HSELBootTim, HSELTim, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC;
|
||||||
|
|
||||||
|
logic PreHSELUART;
|
||||||
|
|
||||||
|
logic Empty;
|
||||||
|
|
||||||
|
// Determine which region of physical memory (if any) is being accessed
|
||||||
|
adrdec boottimdec(HADDR, `BOOTTIMBASE, `BOOTTIMRANGE, HSELBootTim);
|
||||||
|
adrdec timdec(HADDR, `TIMBASE, `TIMRANGE, HSELTim);
|
||||||
|
adrdec clintdec(HADDR, `CLINTBASE, `CLINTRANGE, HSELCLINT);
|
||||||
|
adrdec gpiodec(HADDR, `GPIOBASE, `GPIORANGE, HSELGPIO);
|
||||||
|
adrdec uartdec(HADDR, `UARTBASE, `UARTRANGE, PreHSELUART);
|
||||||
|
adrdec plicdec(HADDR, `PLICBASE, `PLICRANGE, HSELPLIC);
|
||||||
|
|
||||||
|
assign HSELUART = PreHSELUART && (HSIZE == 3'b000); // only byte writes to UART are supported
|
||||||
|
|
||||||
|
// Swizzle region bits
|
||||||
|
assign HSELRegions = {HSELBootTim, HSELTim, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC};
|
||||||
|
|
||||||
|
// Only RAM memory regions are cacheable
|
||||||
|
assign Cacheable = HSELBootTim | HSELTim;
|
||||||
|
|
||||||
|
// *** Temporarily assume only RAM regions are idempotent -- likely wrong
|
||||||
|
assign Idempotent = HSELBootTim | HSELTim;
|
||||||
|
|
||||||
|
// *** Temporarily assume only RAM regions allow full atomic operations -- likely wrong
|
||||||
|
assign AtomicAllowed = HSELBootTim | HSELTim;
|
||||||
|
|
||||||
|
assign Empty = ~|HSELRegions;
|
||||||
|
|
||||||
|
assign InstrAccessFaultF = Empty && Execute;
|
||||||
|
assign LoadAccessFaultM = Empty && Read;
|
||||||
|
assign StoreAccessFaultM = Empty && Write;
|
||||||
|
|
||||||
|
assign SquashAHBAccess = InstrAccessFaultF || LoadAccessFaultM || StoreAccessFaultM;
|
||||||
|
|
||||||
|
endmodule
|
@ -22,7 +22,10 @@ module booth(xExt, choose, add1, e, pp);
|
|||||||
3'b100 : pp = {negx, 1'b0}; // -2
|
3'b100 : pp = {negx, 1'b0}; // -2
|
||||||
3'b101 : pp = {1'b1, negx}; // -1
|
3'b101 : pp = {1'b1, negx}; // -1
|
||||||
3'b110 : pp = {1'b1, negx}; // -1
|
3'b110 : pp = {1'b1, negx}; // -1
|
||||||
3'b111 : pp = 55'h7fffffffffffff; // -0
|
// *** <Thomas Fleming> I changed this to fix a lint error. '1 should
|
||||||
|
// fill the signal with all ones.
|
||||||
|
// 3'b111 : pp = 55'hfffffffffffffff;
|
||||||
|
3'b111 : pp = '1; // -0
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
always_comb
|
always_comb
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
`include "wally-constants.vh"
|
`include "wally-constants.vh"
|
||||||
|
|
||||||
// *** use actual flop notation instead of initialbegin and alwaysff
|
|
||||||
module tlb_ram #(parameter ENTRY_BITS = 3) (
|
module tlb_ram #(parameter ENTRY_BITS = 3) (
|
||||||
input clk, reset,
|
input clk, reset,
|
||||||
input [ENTRY_BITS-1:0] VPNIndex, // Index to read from
|
input [ENTRY_BITS-1:0] VPNIndex, // Index to read from
|
||||||
@ -44,17 +43,22 @@ module tlb_ram #(parameter ENTRY_BITS = 3) (
|
|||||||
|
|
||||||
logic [`XLEN-1:0] ram [0:NENTRIES-1];
|
logic [`XLEN-1:0] ram [0:NENTRIES-1];
|
||||||
logic [`XLEN-1:0] PageTableEntry;
|
logic [`XLEN-1:0] PageTableEntry;
|
||||||
always @(posedge clk) begin
|
|
||||||
if (TLBWrite) ram[WriteIndex] <= PageTableEntryWrite;
|
logic [NENTRIES-1:0] RAMEntryWrite;
|
||||||
end
|
|
||||||
|
decoder #(ENTRY_BITS) tlb_ram_decoder(WriteIndex, RAMEntryWrite);
|
||||||
|
|
||||||
|
// Generate a flop for every entry in the RAM
|
||||||
|
generate
|
||||||
|
genvar i;
|
||||||
|
for (i = 0; i < NENTRIES; i++) begin: tlb_ram_flops
|
||||||
|
flopenr #(`XLEN) pte_flop(clk, reset, RAMEntryWrite[i] & TLBWrite,
|
||||||
|
PageTableEntryWrite, ram[i]);
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
assign PageTableEntry = ram[VPNIndex];
|
assign PageTableEntry = ram[VPNIndex];
|
||||||
assign PTEAccessBits = PageTableEntry[7:0];
|
assign PTEAccessBits = PageTableEntry[7:0];
|
||||||
assign PhysicalPageNumber = PageTableEntry[`PPN_BITS+9:10];
|
assign PhysicalPageNumber = PageTableEntry[`PPN_BITS+9:10];
|
||||||
|
|
||||||
initial begin
|
|
||||||
for (int i = 0; i < NENTRIES; i++)
|
|
||||||
ram[i] = `XLEN'b0;
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -23,6 +23,13 @@
|
|||||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
// *** <Thomas Fleming> I added these verilator controls to clean up the
|
||||||
|
// lint output. The linter warnings should be fixed, but now the output is at
|
||||||
|
// least readable.
|
||||||
|
/* verilator lint_off COMBDLY */
|
||||||
|
/* verilator lint_off IMPLICIT */
|
||||||
|
|
||||||
|
|
||||||
module div (Q, rem0, done, divBusy, div0, N, D, clk, reset, start);
|
module div (Q, rem0, done, divBusy, div0, N, D, clk, reset, start);
|
||||||
|
|
||||||
input logic [63:0] N, D;
|
input logic [63:0] N, D;
|
||||||
@ -1554,3 +1561,5 @@ module shifter_r32 (Z, A, Shift);
|
|||||||
|
|
||||||
endmodule // shifter_r32
|
endmodule // shifter_r32
|
||||||
|
|
||||||
|
/* verilator lint_on COMBDLY */
|
||||||
|
/* verilator lint_on IMPLICIT */
|
||||||
|
@ -107,8 +107,10 @@ module csrm #(parameter
|
|||||||
logic WritePMPCFG0M, WritePMPCFG2M;
|
logic WritePMPCFG0M, WritePMPCFG2M;
|
||||||
logic WritePMPADDRM [0:15];
|
logic WritePMPADDRM [0:15];
|
||||||
|
|
||||||
|
localparam MISA_26 = (`MISA) & 32'h03ffffff;
|
||||||
|
|
||||||
// MISA is hardwired. Spec says it could be written to disable features, but this is not supported by Wally
|
// MISA is hardwired. Spec says it could be written to disable features, but this is not supported by Wally
|
||||||
assign MISA_REGW = {(`XLEN == 32 ? 2'b01 : 2'b10), {(`XLEN-28){1'b0}}, {`MISA}[25:0]};
|
assign MISA_REGW = {(`XLEN == 32 ? 2'b01 : 2'b10), {(`XLEN-28){1'b0}}, MISA_26[25:0]};
|
||||||
|
|
||||||
// Write machine Mode CSRs
|
// Write machine Mode CSRs
|
||||||
assign WriteMSTATUSM = CSRMWriteM && (CSRAdrM == MSTATUS);
|
assign WriteMSTATUSM = CSRMWriteM && (CSRAdrM == MSTATUS);
|
||||||
|
@ -42,9 +42,9 @@ module privileged (
|
|||||||
input logic PrivilegedM,
|
input logic PrivilegedM,
|
||||||
input logic ITLBInstrPageFaultF, DTLBLoadPageFaultM, DTLBStorePageFaultM,
|
input logic ITLBInstrPageFaultF, DTLBLoadPageFaultM, DTLBStorePageFaultM,
|
||||||
input logic WalkerInstrPageFaultF, WalkerLoadPageFaultM, WalkerStorePageFaultM,
|
input logic WalkerInstrPageFaultF, WalkerLoadPageFaultM, WalkerStorePageFaultM,
|
||||||
input logic InstrMisalignedFaultM, InstrAccessFaultF, IllegalIEUInstrFaultD,
|
input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD,
|
||||||
input logic LoadMisalignedFaultM, LoadAccessFaultM,
|
input logic LoadMisalignedFaultM,
|
||||||
input logic StoreMisalignedFaultM, StoreAccessFaultM,
|
input logic StoreMisalignedFaultM,
|
||||||
input logic TimerIntM, ExtIntM, SwIntM,
|
input logic TimerIntM, ExtIntM, SwIntM,
|
||||||
input logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM,
|
input logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM,
|
||||||
input logic [4:0] SetFflagsM,
|
input logic [4:0] SetFflagsM,
|
||||||
@ -52,7 +52,16 @@ module privileged (
|
|||||||
output logic [`XLEN-1:0] SATP_REGW,
|
output logic [`XLEN-1:0] SATP_REGW,
|
||||||
output logic STATUS_MXR, STATUS_SUM,
|
output logic STATUS_MXR, STATUS_SUM,
|
||||||
output logic [2:0] FRM_REGW,
|
output logic [2:0] FRM_REGW,
|
||||||
input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM
|
input logic FlushD, FlushE, FlushM, StallD, StallW, StallE, StallM,
|
||||||
|
|
||||||
|
// PMA checker signals
|
||||||
|
input logic [31:0] HADDR,
|
||||||
|
input logic [2:0] HSIZE, HBURST,
|
||||||
|
input logic HWRITE,
|
||||||
|
input logic Atomic, Execute, Write, Read,
|
||||||
|
output logic Cacheable, Idempotent, AtomicAllowed,
|
||||||
|
output logic SquashAHBAccess,
|
||||||
|
output logic [5:0] HSELRegions
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [1:0] NextPrivilegeModeM;
|
logic [1:0] NextPrivilegeModeM;
|
||||||
@ -67,7 +76,8 @@ module privileged (
|
|||||||
logic IllegalIEUInstrFaultE, IllegalIEUInstrFaultM;
|
logic IllegalIEUInstrFaultE, IllegalIEUInstrFaultM;
|
||||||
logic LoadPageFaultM, StorePageFaultM;
|
logic LoadPageFaultM, StorePageFaultM;
|
||||||
logic InstrPageFaultF, InstrPageFaultD, InstrPageFaultE, InstrPageFaultM;
|
logic InstrPageFaultF, InstrPageFaultD, InstrPageFaultE, InstrPageFaultM;
|
||||||
logic InstrAccessFaultD, InstrAccessFaultE, InstrAccessFaultM;
|
logic InstrAccessFaultF, InstrAccessFaultD, InstrAccessFaultE, InstrAccessFaultM;
|
||||||
|
logic LoadAccessFaultM, StoreAccessFaultM;
|
||||||
logic IllegalInstrFaultM;
|
logic IllegalInstrFaultM;
|
||||||
|
|
||||||
logic BreakpointFaultM, EcallFaultM;
|
logic BreakpointFaultM, EcallFaultM;
|
||||||
@ -118,6 +128,12 @@ module privileged (
|
|||||||
|
|
||||||
csr csr(.*);
|
csr csr(.*);
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
// Check physical memory accesses
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
pmachecker pmachecker(.*);
|
||||||
|
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// Extract exceptions by name and handle them
|
// Extract exceptions by name and handle them
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
@ -37,6 +37,7 @@ module trap (
|
|||||||
input logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW,
|
input logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW,
|
||||||
input logic [11:0] MIP_REGW, MIE_REGW,
|
input logic [11:0] MIP_REGW, MIE_REGW,
|
||||||
input logic STATUS_MIE, STATUS_SIE,
|
input logic STATUS_MIE, STATUS_SIE,
|
||||||
|
input logic [`XLEN-1:0] PCM,
|
||||||
input logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM,
|
input logic [`XLEN-1:0] InstrMisalignedAdrM, MemAdrM,
|
||||||
input logic [31:0] InstrM,
|
input logic [31:0] InstrM,
|
||||||
output logic TrapM, MTrapM, STrapM, UTrapM, RetM,
|
output logic TrapM, MTrapM, STrapM, UTrapM, RetM,
|
||||||
@ -128,7 +129,7 @@ module trap (
|
|||||||
if (InstrMisalignedFaultM) NextFaultMtvalM = InstrMisalignedAdrM;
|
if (InstrMisalignedFaultM) NextFaultMtvalM = InstrMisalignedAdrM;
|
||||||
else if (LoadMisalignedFaultM) NextFaultMtvalM = MemAdrM;
|
else if (LoadMisalignedFaultM) NextFaultMtvalM = MemAdrM;
|
||||||
else if (StoreMisalignedFaultM) NextFaultMtvalM = MemAdrM;
|
else if (StoreMisalignedFaultM) NextFaultMtvalM = MemAdrM;
|
||||||
else if (InstrPageFaultM) NextFaultMtvalM = 0; // *** implement
|
else if (InstrPageFaultM) NextFaultMtvalM = PCM;
|
||||||
else if (LoadPageFaultM) NextFaultMtvalM = MemAdrM;
|
else if (LoadPageFaultM) NextFaultMtvalM = MemAdrM;
|
||||||
else if (StorePageFaultM) NextFaultMtvalM = MemAdrM;
|
else if (StorePageFaultM) NextFaultMtvalM = MemAdrM;
|
||||||
else if (IllegalInstrFaultM) NextFaultMtvalM = {{(`XLEN-32){1'b0}}, InstrM};
|
else if (IllegalInstrFaultM) NextFaultMtvalM = {{(`XLEN-32){1'b0}}, InstrM};
|
||||||
|
@ -47,8 +47,11 @@ module uncore (
|
|||||||
input logic [2:0] HADDRD,
|
input logic [2:0] HADDRD,
|
||||||
input logic [3:0] HSIZED,
|
input logic [3:0] HSIZED,
|
||||||
input logic HWRITED,
|
input logic HWRITED,
|
||||||
|
// PMA checker signals
|
||||||
|
input logic [5:0] HSELRegions,
|
||||||
// bus interface
|
// bus interface
|
||||||
output logic DataAccessFaultM,
|
// PMA checker now handles access faults. *** This can be deleted
|
||||||
|
// output logic DataAccessFaultM,
|
||||||
// peripheral pins
|
// peripheral pins
|
||||||
output logic TimerIntM, SwIntM, ExtIntM,
|
output logic TimerIntM, SwIntM, ExtIntM,
|
||||||
input logic [31:0] GPIOPinsIn,
|
input logic [31:0] GPIOPinsIn,
|
||||||
@ -68,8 +71,11 @@ module uncore (
|
|||||||
logic HSELBootTim, HSELBootTimD, HRESPBootTim, HREADYBootTim;
|
logic HSELBootTim, HSELBootTimD, HRESPBootTim, HREADYBootTim;
|
||||||
logic [1:0] MemRWboottim;
|
logic [1:0] MemRWboottim;
|
||||||
logic UARTIntr,GPIOIntr;
|
logic UARTIntr,GPIOIntr;
|
||||||
|
|
||||||
|
|
||||||
|
// unswizzle HSEL signals
|
||||||
|
assign {HSELBootTim, HSELTim, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC} = HSELRegions;
|
||||||
|
|
||||||
|
/* PMA checker now handles decoding addresses. *** This can be deleted.
|
||||||
// AHB Address decoder
|
// AHB Address decoder
|
||||||
adrdec timdec(HADDR, `TIMBASE, `TIMRANGE, HSELTim);
|
adrdec timdec(HADDR, `TIMBASE, `TIMRANGE, HSELTim);
|
||||||
adrdec boottimdec(HADDR, `BOOTTIMBASE, `BOOTTIMRANGE, HSELBootTim);
|
adrdec boottimdec(HADDR, `BOOTTIMBASE, `BOOTTIMRANGE, HSELBootTim);
|
||||||
@ -78,6 +84,7 @@ module uncore (
|
|||||||
adrdec gpiodec(HADDR, `GPIOBASE, `GPIORANGE, HSELGPIO);
|
adrdec gpiodec(HADDR, `GPIOBASE, `GPIORANGE, HSELGPIO);
|
||||||
adrdec uartdec(HADDR, `UARTBASE, `UARTRANGE, PreHSELUART);
|
adrdec uartdec(HADDR, `UARTBASE, `UARTRANGE, PreHSELUART);
|
||||||
assign HSELUART = PreHSELUART && (HSIZE == 3'b000); // only byte writes to UART are supported
|
assign HSELUART = PreHSELUART && (HSIZE == 3'b000); // only byte writes to UART are supported
|
||||||
|
*/
|
||||||
|
|
||||||
// subword accesses: converts HWDATAIN to HWDATA
|
// subword accesses: converts HWDATAIN to HWDATA
|
||||||
subwordwrite sww(.*);
|
subwordwrite sww(.*);
|
||||||
@ -115,9 +122,10 @@ module uncore (
|
|||||||
HSELBootTimD & HREADYBootTim |
|
HSELBootTimD & HREADYBootTim |
|
||||||
HSELUARTD & HREADYUART;
|
HSELUARTD & HREADYUART;
|
||||||
|
|
||||||
|
/* PMA checker now handles access faults. *** This can be deleted
|
||||||
// Faults
|
// Faults
|
||||||
assign DataAccessFaultM = ~(HSELTimD | HSELCLINTD | HSELPLICD | HSELGPIOD | HSELBootTimD | HSELUARTD);
|
assign DataAccessFaultM = ~(HSELTimD | HSELCLINTD | HSELPLICD | HSELGPIOD | HSELBootTimD | HSELUARTD);
|
||||||
|
*/
|
||||||
|
|
||||||
// Address Decoder Delay (figure 4-2 in spec)
|
// Address Decoder Delay (figure 4-2 in spec)
|
||||||
flopr #(1) hseltimreg(HCLK, ~HRESETn, HSELTim, HSELTimD);
|
flopr #(1) hseltimreg(HCLK, ~HRESETn, HSELTim, HSELTimD);
|
||||||
|
@ -48,6 +48,7 @@ module wallypipelinedhart (
|
|||||||
output logic [3:0] HPROT,
|
output logic [3:0] HPROT,
|
||||||
output logic [1:0] HTRANS,
|
output logic [1:0] HTRANS,
|
||||||
output logic HMASTLOCK,
|
output logic HMASTLOCK,
|
||||||
|
output logic [5:0] HSELRegions,
|
||||||
// Delayed signals for subword write
|
// Delayed signals for subword write
|
||||||
output logic [2:0] HADDRD,
|
output logic [2:0] HADDRD,
|
||||||
output logic [3:0] HSIZED,
|
output logic [3:0] HSIZED,
|
||||||
@ -110,9 +111,15 @@ module wallypipelinedhart (
|
|||||||
logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM;
|
logic [`XLEN-1:0] PageTableEntryF, PageTableEntryM;
|
||||||
logic [1:0] PageTypeF, PageTypeM;
|
logic [1:0] PageTypeF, PageTypeM;
|
||||||
|
|
||||||
|
// PMA checker signals
|
||||||
|
logic Atomic, Execute, Write, Read;
|
||||||
|
logic Cacheable, Idempotent, AtomicAllowed;
|
||||||
|
logic SquashAHBAccess;
|
||||||
|
|
||||||
// IMem stalls
|
// IMem stalls
|
||||||
logic ICacheStallF;
|
logic ICacheStallF;
|
||||||
logic [`XLEN-1:0] MMUPAdr, MMUReadPTE;
|
logic [`XLEN-1:0] MMUPAdr, MMUReadPTE;
|
||||||
|
logic MMUStall;
|
||||||
logic MMUTranslate, MMUTranslationComplete, MMUReady;
|
logic MMUTranslate, MMUTranslationComplete, MMUReady;
|
||||||
|
|
||||||
// bus interface to dmem
|
// bus interface to dmem
|
||||||
|
@ -60,6 +60,7 @@ module wallypipelinedsoc (
|
|||||||
// Uncore signals
|
// Uncore signals
|
||||||
logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore
|
logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore
|
||||||
logic HREADY, HRESP;
|
logic HREADY, HRESP;
|
||||||
|
logic [5:0] HSELRegions;
|
||||||
logic InstrAccessFaultF, DataAccessFaultM;
|
logic InstrAccessFaultF, DataAccessFaultM;
|
||||||
logic TimerIntM, SwIntM; // from CLINT
|
logic TimerIntM, SwIntM; // from CLINT
|
||||||
logic ExtIntM; // from PLIC
|
logic ExtIntM; // from PLIC
|
||||||
@ -72,8 +73,6 @@ module wallypipelinedsoc (
|
|||||||
// instantiate processor and memories
|
// instantiate processor and memories
|
||||||
wallypipelinedhart hart(.*);
|
wallypipelinedhart hart(.*);
|
||||||
|
|
||||||
// *** Temporary driving of access fault to low until PMA checker is complete
|
|
||||||
assign InstrAccessFaultF = '0;
|
|
||||||
// instructions now come from uncore memory. This line can be removed at any time.
|
// instructions now come from uncore memory. This line can be removed at any time.
|
||||||
// imem imem(.AdrF(PCF[`XLEN-1:1]), .*); // temporary until uncore memory is finished***
|
// imem imem(.AdrF(PCF[`XLEN-1:1]), .*); // temporary until uncore memory is finished***
|
||||||
uncore uncore(.HWDATAIN(HWDATA), .*);
|
uncore uncore(.HWDATAIN(HWDATA), .*);
|
||||||
|
@ -29,6 +29,76 @@ module testbench();
|
|||||||
// instantiate processor and memories
|
// instantiate processor and memories
|
||||||
wallypipelinedsoc dut(.*);
|
wallypipelinedsoc dut(.*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Walk the page table stored in dtim according to sv39 logic and translate a
|
||||||
|
* virtual address to a physical address.
|
||||||
|
*
|
||||||
|
* See section 4.3.2 of the RISC-V Privileged specification for a full
|
||||||
|
* explanation of the below algorithm.
|
||||||
|
*/
|
||||||
|
function logic [`XLEN-1:0] adrTranslator(
|
||||||
|
input logic [`XLEN-1:0] adrIn);
|
||||||
|
begin
|
||||||
|
logic SvMode, PTE_R, PTE_X;
|
||||||
|
logic [`XLEN-1:0] SATP, PTE;
|
||||||
|
logic [55:0] BaseAdr, PAdr;
|
||||||
|
logic [8:0] VPN [0:2];
|
||||||
|
logic [11:0] Offset;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Grab the SATP register from privileged unit
|
||||||
|
SATP = dut.hart.priv.csr.SATP_REGW;
|
||||||
|
|
||||||
|
// Split the virtual address into page number segments and offset
|
||||||
|
VPN[2] = adrIn[38:30];
|
||||||
|
VPN[1] = adrIn[29:21];
|
||||||
|
VPN[0] = adrIn[20:12];
|
||||||
|
Offset = adrIn[11:0];
|
||||||
|
|
||||||
|
// We do not support sv48; only sv39
|
||||||
|
SvMode = SATP[63];
|
||||||
|
|
||||||
|
// Only perform translation if translation is on and the processor is not
|
||||||
|
// in machine mode
|
||||||
|
if (SvMode && (dut.hart.priv.PrivilegeModeW != `M_MODE)) begin
|
||||||
|
BaseAdr = SATP[43:0] << 12;
|
||||||
|
|
||||||
|
for (i = 2; i >= 0; i--) begin
|
||||||
|
PAdr = BaseAdr + (VPN[i] << 3);
|
||||||
|
|
||||||
|
// dtim.RAM is 64-bit addressed. PAdr specifies a byte. We right shift
|
||||||
|
// by 3 (the PTE size) to get the requested 64-bit PTE.
|
||||||
|
PTE = dut.uncore.dtim.RAM[PAdr >> 3];
|
||||||
|
PTE_R = PTE[1];
|
||||||
|
PTE_X = PTE[3];
|
||||||
|
if (PTE_R || PTE_X) begin
|
||||||
|
// Leaf page found
|
||||||
|
break;
|
||||||
|
end else begin
|
||||||
|
// Go to next level of table
|
||||||
|
BaseAdr = PTE[53:10] << 12;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Determine which parts of the PTE page number to use based on the
|
||||||
|
// level of the page table we reached.
|
||||||
|
if (i == 2) begin
|
||||||
|
// Gigapage
|
||||||
|
assign adrTranslator = {8'b0, PTE[53:28], VPN[1], VPN[0], Offset};
|
||||||
|
end else if (i == 1) begin
|
||||||
|
// Megapage
|
||||||
|
assign adrTranslator = {8'b0, PTE[53:19], VPN[0], Offset};
|
||||||
|
end else begin
|
||||||
|
// Kilopage
|
||||||
|
assign adrTranslator = {8'b0, PTE[53:10], Offset};
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
// Direct translation if address translation is not on
|
||||||
|
assign adrTranslator = adrIn;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
// initialize test
|
// initialize test
|
||||||
initial
|
initial
|
||||||
@ -68,7 +138,7 @@ module testbench();
|
|||||||
// read CSR trace file
|
// read CSR trace file
|
||||||
integer data_file_csr, scan_file_csr;
|
integer data_file_csr, scan_file_csr;
|
||||||
initial begin
|
initial begin
|
||||||
data_file_csr = $fopen({`BUSYBEAR_TEST_VECTORS,"parsedCSRs.txt"}, "r");
|
data_file_csr = $fopen({`BUSYBEAR_TEST_VECTORS,"parsedCSRs2.txt"}, "r");
|
||||||
if (data_file_csr == 0) begin
|
if (data_file_csr == 0) begin
|
||||||
$display("file couldn't be opened");
|
$display("file couldn't be opened");
|
||||||
$stop;
|
$stop;
|
||||||
@ -189,7 +259,7 @@ module testbench();
|
|||||||
logic [63:0] readMask;
|
logic [63:0] readMask;
|
||||||
assign readMask = ((1 << (8*(1 << HSIZE))) - 1) << 8 * HADDR[2:0];
|
assign readMask = ((1 << (8*(1 << HSIZE))) - 1) << 8 * HADDR[2:0];
|
||||||
|
|
||||||
logic [`XLEN-1:0] readAdrExpected;
|
logic [`XLEN-1:0] readAdrExpected, readAdrTranslated;
|
||||||
|
|
||||||
import ahbliteState::*;
|
import ahbliteState::*;
|
||||||
always @(dut.HRDATA) begin
|
always @(dut.HRDATA) begin
|
||||||
@ -204,8 +274,9 @@ module testbench();
|
|||||||
end
|
end
|
||||||
scan_file_memR = $fscanf(data_file_memR, "%x\n", readAdrExpected);
|
scan_file_memR = $fscanf(data_file_memR, "%x\n", readAdrExpected);
|
||||||
scan_file_memR = $fscanf(data_file_memR, "%x\n", HRDATA);
|
scan_file_memR = $fscanf(data_file_memR, "%x\n", HRDATA);
|
||||||
if (~equal(HADDR,readAdrExpected,4)) begin
|
assign readAdrTranslated = adrTranslator(readAdrExpected);
|
||||||
$display("%0t ps, instr %0d: HADDR does not equal readAdrExpected: %x, %x", $time, instrs, HADDR, readAdrExpected);
|
if (~equal(HADDR,readAdrTranslated,4)) begin
|
||||||
|
$display("%0t ps, instr %0d: HADDR does not equal readAdrExpected: %x, %x", $time, instrs, HADDR, readAdrTranslated);
|
||||||
`ERROR
|
`ERROR
|
||||||
end
|
end
|
||||||
if ((readMask & HRDATA) !== (readMask & dut.HRDATA)) begin
|
if ((readMask & HRDATA) !== (readMask & dut.HRDATA)) begin
|
||||||
@ -227,7 +298,7 @@ module testbench();
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
logic [`XLEN-1:0] writeDataExpected, writeAdrExpected;
|
logic [`XLEN-1:0] writeDataExpected, writeAdrExpected, writeAdrTranslated;
|
||||||
|
|
||||||
// this might need to change
|
// this might need to change
|
||||||
//always @(HWDATA or HADDR or HSIZE or HWRITE) begin
|
//always @(HWDATA or HADDR or HSIZE or HWRITE) begin
|
||||||
@ -240,12 +311,14 @@ module testbench();
|
|||||||
end
|
end
|
||||||
scan_file_memW = $fscanf(data_file_memW, "%x\n", writeDataExpected);
|
scan_file_memW = $fscanf(data_file_memW, "%x\n", writeDataExpected);
|
||||||
scan_file_memW = $fscanf(data_file_memW, "%x\n", writeAdrExpected);
|
scan_file_memW = $fscanf(data_file_memW, "%x\n", writeAdrExpected);
|
||||||
|
assign writeAdrTranslated = adrTranslator(writeAdrExpected);
|
||||||
|
|
||||||
if (writeDataExpected != HWDATA) begin
|
if (writeDataExpected != HWDATA) begin
|
||||||
$display("%0t ps, instr %0d: HWDATA does not equal writeDataExpected: %x, %x", $time, instrs, HWDATA, writeDataExpected);
|
$display("%0t ps, instr %0d: HWDATA does not equal writeDataExpected: %x, %x", $time, instrs, HWDATA, writeDataExpected);
|
||||||
`ERROR
|
`ERROR
|
||||||
end
|
end
|
||||||
if (~equal(writeAdrExpected,HADDR,1)) begin
|
if (~equal(writeAdrTranslated,HADDR,1)) begin
|
||||||
$display("%0t ps, instr %0d: HADDR does not equal writeAdrExpected: %x, %x", $time, instrs, HADDR, writeAdrExpected);
|
$display("%0t ps, instr %0d: HADDR does not equal writeAdrExpected: %x, %x", $time, instrs, HADDR, writeAdrTranslated);
|
||||||
`ERROR
|
`ERROR
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -346,10 +419,6 @@ module testbench();
|
|||||||
//$stop;
|
//$stop;
|
||||||
generate
|
generate
|
||||||
if (`BUSYBEAR == 1) begin
|
if (`BUSYBEAR == 1) begin
|
||||||
initial begin
|
|
||||||
#34140421;
|
|
||||||
$stop;
|
|
||||||
end
|
|
||||||
initial begin //this is temporary until the bug can be fixed!!!
|
initial begin //this is temporary until the bug can be fixed!!!
|
||||||
#11130100;
|
#11130100;
|
||||||
force dut.hart.ieu.dp.regf.rf[5] = 64'h0000000080000004;
|
force dut.hart.ieu.dp.regf.rf[5] = 64'h0000000080000004;
|
||||||
|
@ -334,7 +334,8 @@ module testbench();
|
|||||||
"rv32i/WALLY-CSRRC", "4000",
|
"rv32i/WALLY-CSRRC", "4000",
|
||||||
"rv32i/WALLY-CSRRWI", "3000",
|
"rv32i/WALLY-CSRRWI", "3000",
|
||||||
"rv32i/WALLY-CSRRSI", "3000",
|
"rv32i/WALLY-CSRRSI", "3000",
|
||||||
"rv32i/WALLY-CSRRCI", "3000"
|
"rv32i/WALLY-CSRRCI", "3000",
|
||||||
|
"rv32i/WALLY-PIPELINE", "1a800"
|
||||||
};
|
};
|
||||||
|
|
||||||
string testsBP64[] = '{
|
string testsBP64[] = '{
|
||||||
@ -409,7 +410,7 @@ module testbench();
|
|||||||
// if (`F_SUPPORTED) tests = {tests64f, tests};
|
// if (`F_SUPPORTED) tests = {tests64f, tests};
|
||||||
// if (`D_SUPPORTED) tests = {tests64d, tests};
|
// if (`D_SUPPORTED) tests = {tests64d, tests};
|
||||||
if (`A_SUPPORTED) tests = {tests, tests64a};
|
if (`A_SUPPORTED) tests = {tests, tests64a};
|
||||||
if (`MEM_VIRTMEM) tests = {tests64mmu, tests};
|
// if (`MEM_VIRTMEM) tests = {tests64mmu, tests};
|
||||||
end
|
end
|
||||||
//tests = {tests64a, tests};
|
//tests = {tests64a, tests};
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user