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

This commit is contained in:
Ross Thompson 2022-01-18 17:19:59 -06:00
commit 2508b9d35a
15 changed files with 4562 additions and 4 deletions

6
.gitmodules vendored
View File

@ -11,3 +11,9 @@
[submodule "addins/riscv-tests"]
path = addins/riscv-tests
url = https://github.com/riscv-software-src/riscv-tests
[submodule "addins/riscv-dv"]
path = addins/riscv-dv
url = https://github.com/google/riscv-dv
[submodule "addins/embench-iot"]
path = addins/embench-iot
url = https://github.com/embench/embench-iot

1
addins/embench-iot Submodule

@ -0,0 +1 @@
Subproject commit 261a65e0a2d3e8d62d81b1d8fe7e309a096bc6a9

1
addins/riscv-dv Submodule

@ -0,0 +1 @@
Subproject commit 96c1ee6f371f2754c45b4831fcab95f6671689d9

170
bin/exe2memfile.pl Executable file
View File

@ -0,0 +1,170 @@
#!/usr/bin/perl -w
# exe2memfile.pl
# David_Harris@hmc.edu 26 November 2020
# Converts an executable file to a series of 32-bit hex instructions
# to read into a Verilog simulation with $readmemh
use File::stat;
use IO::Handle;
if ($#ARGV == -1) {
die("Usage: $0 executable_file");
}
# array to hold contents of memory file
my $maxmemfilesize = 1000000;
my @memfilebytes = (0)*$maxmemfilesize*4;
my $maxaddress = 0;
STDOUT->autoflush(1);
my $numfiles = $#ARGV+1;
if ($numfiles > 1) {
print ("Processing $numfiles memfiles: ");
}
my $frac = $#ARGV/10;
for(my $i=0; $i<=$#ARGV; $i++) {
if ($i > 0 && ($i < 10 || $i % $frac == 0)) { print ("$i ") };
my $fname = $ARGV[$i];
# print "fname = $fname";
my $ofile = $fname.".objdump";
my $memfile = $fname.".memfile";
my $needsprocessing = 0;
if (!-e $memfile) { $needsprocessing = 1; } # create memfile if it doesn't exist
else {
my $osb = stat($ofile) || die("Can't stat $ofile");
my $msb = stat($memfile) || die("Can't stat $memfile");
my $otime = $osb->mtime;
my $mtime = $msb->mtime;
if ($otime > $mtime) { $needsprocessing = 1; } # is memfile out of date?
}
if ($needsprocessing == 1) {
open(FILE, $ofile) || die("Can't read $ofile");
my $mode = 0; # parse for code
my $address;
# initialize to all zeros;
for (my $i=0; $i < $maxmemfilesize*4; $i++) {
$memfilebytes[$i] = "00";
}
while(<FILE>) {
if ($mode == 0) { # Parse code
# print("Examining $_\n");
if (/^\s*(\S\S\S\S\S\S\S\S):\s+(\S+)\s+/) {
$address = &fixadr($1);
my $instr = $2;
my $len = length($instr);
for (my $i=0; $i<$len/2; $i++) {
$memfilebytes[$address+$i] = substr($instr, $len-2-2*$i, 2);
}
# print ("address $address $instr\n");
}
if (/Disassembly of section .data:/) { $mode = 1;}
} elsif ($mode == 1) { # Parse data segment
# if (/^\s*(\S\S\S\S\S\S\S\S):\s+(.*)/) { # changed to \t 30 Oct 2021 dmh to fix parsing issue in d_fmadd_b17
if (/^\s*(\S\S\S\S\S\S\S\S):\s+(.*)/) {
$address = &fixadr($1);
# print "addresss $address maxaddress $maxaddress\n";
if ($address > $maxaddress) { $maxaddress = $address; }
#print "test $address $1 $2\n";
my $lineorig = $2;
my $line = $2;
# strip off leading 0x
$line =~ s/^0x//;
# merge chunks with spaces
$line =~ s/(\S)\s(\S)/$1$2/g;
my $linemerge = $line;
# strip off comments
$line =~ /^(\S*)/;
$payload = $1;
# if ($address >= 17520 && $address <= 17552) { # was 12304
# print "Address: $address\n orig: $lineorig \n merge: $linemerge \n line: $line \n payload: $payload\n";
# }
&emitData($address, $payload);
}
if (/Disassembly of section .riscv.attributes:/) { $mode = 2; }
}
}
close(FILE);
# print("maxaddress: $maxaddress\n");
$maxaddress += 32; # pad some zeros at the end
# print("maxaddress: $maxaddress\n");
# print to memory file
if ($fname =~ /rv32/) {
open(MEMFILE, ">$memfile") || die("Can't write $memfile");
for (my $i=0; $i<= $maxaddress; $i = $i + 4) {
for ($j=3; $j>=0; $j--) {
if (defined($memfilebytes[$i+$j])) {
print MEMFILE "$memfilebytes[$i+$j]";
} else {
print MEMFILE "00";
}
}
print MEMFILE "\n";
}
close(MEMFILE);
} else {
open(MEMFILE, ">$memfile") || die("Can't write $memfile");
for (my $i=0; $i<= $maxaddress; $i = $i + 8) {
for ($j=7; $j>=0; $j--) {
my $loc = $i+$j;
# if ($loc >= 17520 && $loc <= 17552) {
# print "loc: $loc val $memfilebytes[$loc]\n";
# }
if (defined($memfilebytes[$loc])) {
print MEMFILE "$memfilebytes[$loc]";
} else {
print MEMFILE "00";
}
}
print MEMFILE "\n";
}
close(MEMFILE);
}
}
}
print("\n");
sub emitData {
# print the data portion of the ELF into a memroy file, including 0s for empty stuff
# deal with endianness
my $address = shift;
my $payload = shift;
# if ($address > 17520 && $address < 17552) { # was 12304
# print("Emitting data. address = $address payload = $payload\n");
# }
my $len = length($payload);
if ($len <= 8) {
# print word or halfword
for(my $i=0; $i<$len/2; $i++) {
my $adr = $address+$i;
my $b = substr($payload, $len-2-2*$i, 2);
$memfilebytes[$adr] = $b;
# if ($address >= 17520 && $address <= 17552) {
# print(" Wrote $b to $adr\n");
# }
# print(" $adr $b\n");
}
} elsif ($len == 12) {
# weird case of three halfwords on line
&emitData($address, substr($payload, 0, 4));
&emitData($address+2, substr($payload, 4, 4));
&emitData($address+4, substr($payload, 8, 4));
} else {
&emitData($address, substr($payload, 0, 8));
&emitData($address+4, substr($payload, 8, $len-8));
}
}
sub fixadr {
# strip off leading 8 from address and convert to decimal
my $adr = shift;
if ($adr =~ s/^8/0/) { return hex($adr); }
else { die("address $adr lacks leading 8\n"); }
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,134 @@
//////////////////////////////////////////
// wally-config.vh
//
// Written: David_Harris@hmc.edu 4 January 2021
// Modified:
//
// Purpose: Specify which features are configured
// Macros to determine which modes are supported based on MISA
//
// 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 shared configuration
`include "wally-shared.vh"
`define FPGA 0
`define QEMU 0
`define BUILDROOT 0
`define BUSYBEAR 0
`define DESIGN_COMPILER 0
// RV32 or RV64: XLEN = 32 or 64
`define XLEN 32
// IEEE 754 compliance
`define IEEE754 0
// E
`define MISA (32'h00000010)
`define ZICSR_SUPPORTED 1
`define ZIFENCEI_SUPPORTED 0
`define COUNTERS 32
`define ZICOUNTERS_SUPPORTED 0
// Microarchitectural Features
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
`define MEM_DTIM 0
`define MEM_DCACHE 0
`define MEM_IROM 0
`define MEM_ICACHE 0
`define MEM_VIRTMEM 0
`define VECTORED_INTERRUPTS_SUPPORTED 1
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 0
`define DTLB_ENTRIES 0
// Cache configuration. Sizes should be a power of two
// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines
`define DCACHE_NUMWAYS 4
`define DCACHE_WAYSIZEINBYTES 4096
`define DCACHE_LINELENINBITS 256
`define DCACHE_REPLBITS 3
`define ICACHE_NUMWAYS 4
`define ICACHE_WAYSIZEINBYTES 4096
`define ICACHE_LINELENINBITS 256
// Integer Divider Configuration
// DIV_BITSPERCYCLE must be 1, 2, or 4
`define DIV_BITSPERCYCLE 4
// Legal number of PMP entries are 0, 16, or 64
`define PMP_ENTRIES 0
// Address space
`define RESET_VECTOR 32'h80000000
// Peripheral Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
`define BOOTROM_SUPPORTED 1'b1
`define BOOTROM_BASE 34'h00001000
`define BOOTROM_RANGE 34'h00000FFF
`define RAM_SUPPORTED 1'b1
`define RAM_BASE 34'h80000000
`define RAM_RANGE 34'h07FFFFFF
`define EXT_MEM_SUPPORTED 1'b0
`define EXT_MEM_BASE 34'h80000000
`define EXT_MEM_RANGE 34'h07FFFFFF
`define CLINT_SUPPORTED 1'b1
`define CLINT_BASE 34'h02000000
`define CLINT_RANGE 34'h0000FFFF
`define GPIO_SUPPORTED 1'b1
`define GPIO_BASE 34'h10012000
`define GPIO_RANGE 34'h000000FF
`define UART_SUPPORTED 1'b1
`define UART_BASE 34'h10000000
`define UART_RANGE 34'h00000007
`define PLIC_SUPPORTED 1'b1
`define PLIC_BASE 34'h0C000000
`define PLIC_RANGE 34'h03FFFFFF
`define SDC_SUPPORTED 1'b0
`define SDC_BASE 34'h00012100
`define SDC_RANGE 34'h0000001F
// Bus Interface width
`define AHBW 32
// Test modes
// Tie GPIO outputs back to inputs
`define GPIO_LOOPBACK_TEST 1
// Hardware configuration
`define UART_PRESCALE 1
// Interrupt configuration
`define PLIC_NUM_SRC 4
// comment out the following if >=32 sources
`define PLIC_NUM_SRC_LT_32
`define PLIC_GPIO_ID 3
`define PLIC_UART_ID 4
`define TWO_BIT_PRELOAD "../config/rv32ic/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/rv32ic/BTBPredictor.txt"
`define BPRED_ENABLED 1
`define BPTYPE "BPGSHARE" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE
`define TESTSBP 0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,134 @@
//////////////////////////////////////////
// wally-config.vh
//
// Written: David_Harris@hmc.edu 4 January 2021
// Modified:
//
// Purpose: Specify which features are configured
// Macros to determine which modes are supported based on MISA
//
// 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 shared configuration
`include "wally-shared.vh"
`define FPGA 0
`define QEMU 0
`define BUILDROOT 0
`define BUSYBEAR 0
`define DESIGN_COMPILER 0
// RV32 or RV64: XLEN = 32 or 64
`define XLEN 32
// IEEE 754 compliance
`define IEEE754 0
// E, M, C
`define MISA (32'h00001014)
`define ZICSR_SUPPORTED 1
`define ZIFENCEI_SUPPORTED 0
`define COUNTERS 32
`define ZICOUNTERS_SUPPORTED 0
// Microarchitectural Features
`define UARCH_PIPELINED 1
`define UARCH_SUPERSCALR 0
`define UARCH_SINGLECYCLE 0
`define MEM_DTIM 0
`define MEM_DCACHE 0
`define MEM_IROM 0
`define MEM_ICACHE 0
`define MEM_VIRTMEM 0
`define VECTORED_INTERRUPTS_SUPPORTED 1
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 0
`define DTLB_ENTRIES 0
// Cache configuration. Sizes should be a power of two
// typical configuration 4 ways, 4096 bytes per way, 256 bit or more lines
`define DCACHE_NUMWAYS 4
`define DCACHE_WAYSIZEINBYTES 4096
`define DCACHE_LINELENINBITS 256
`define DCACHE_REPLBITS 3
`define ICACHE_NUMWAYS 4
`define ICACHE_WAYSIZEINBYTES 4096
`define ICACHE_LINELENINBITS 256
// Integer Divider Configuration
// DIV_BITSPERCYCLE must be 1, 2, or 4
`define DIV_BITSPERCYCLE 4
// Legal number of PMP entries are 0, 16, or 64
`define PMP_ENTRIES 0
// Address space
`define RESET_VECTOR 32'h80000000
// Peripheral Addresses
// Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
`define BOOTROM_SUPPORTED 1'b1
`define BOOTROM_BASE 34'h00001000
`define BOOTROM_RANGE 34'h00000FFF
`define RAM_SUPPORTED 1'b1
`define RAM_BASE 34'h80000000
`define RAM_RANGE 34'h07FFFFFF
`define EXT_MEM_SUPPORTED 1'b0
`define EXT_MEM_BASE 34'h80000000
`define EXT_MEM_RANGE 34'h07FFFFFF
`define CLINT_SUPPORTED 1'b1
`define CLINT_BASE 34'h02000000
`define CLINT_RANGE 34'h0000FFFF
`define GPIO_SUPPORTED 1'b1
`define GPIO_BASE 34'h10012000
`define GPIO_RANGE 34'h000000FF
`define UART_SUPPORTED 1'b1
`define UART_BASE 34'h10000000
`define UART_RANGE 34'h00000007
`define PLIC_SUPPORTED 1'b1
`define PLIC_BASE 34'h0C000000
`define PLIC_RANGE 34'h03FFFFFF
`define SDC_SUPPORTED 1'b0
`define SDC_BASE 34'h00012100
`define SDC_RANGE 34'h0000001F
// Bus Interface width
`define AHBW 32
// Test modes
// Tie GPIO outputs back to inputs
`define GPIO_LOOPBACK_TEST 1
// Hardware configuration
`define UART_PRESCALE 1
// Interrupt configuration
`define PLIC_NUM_SRC 4
// comment out the following if >=32 sources
`define PLIC_NUM_SRC_LT_32
`define PLIC_GPIO_ID 3
`define PLIC_UART_ID 4
`define TWO_BIT_PRELOAD "../config/rv32ic/twoBitPredictor.txt"
`define BTB_PRELOAD "../config/rv32ic/BTBPredictor.txt"
`define BPRED_ENABLED 1
`define BPTYPE "BPGSHARE" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE
`define TESTSBP 0

View File

@ -31,7 +31,9 @@
`define A_SUPPORTED ((`MISA >> 0) % 2 == 1)
`define C_SUPPORTED ((`MISA >> 2) % 2 == 1)
`define D_SUPPORTED ((`MISA >> 3) % 2 == 1)
`define E_SUPPORTED ((`MISA >> 4) % 2 == 1)
`define F_SUPPORTED ((`MISA >> 5) % 2 == 1)
`define I_SUPPORTED ((`MISA >> 8) % 2 == 1)
`define M_SUPPORTED ((`MISA >> 12) % 2 == 1)
`define Q_SUPPORTED ((`MISA >> 16) % 2 == 1)
`define S_SUPPORTED ((`MISA >> 18) % 2 == 1)

View File

@ -7,6 +7,14 @@ make clean:
make clean -C ../../tests/wally-riscv-arch-test
make all:
# *** Build old tests/imperas-riscv-tests for now;
# Delete this part when the privileged tests transition over to tests/wally-riscv-arch-test
# Also delete exe2memfile at that point
make -C ../../tests/imperas-riscv-tests
make -C ../../tests/imperas-riscv-tests XLEN=64
cd ../../tests/imperas-riscv-tests; exe2memfile.pl work/*/*.elf
# Build riscv-arch-test 64 and 32-bit versions
make -C ../../addins/riscv-arch-test
make -C ../../addins/riscv-arch-test XLEN=32

View File

@ -106,6 +106,7 @@ module controller(
logic unused;
logic BranchFlagE;
logic IEURegWriteE;
logic IllegalERegAdrD;
// Extract fields
assign OpD = InstrD[6:0];
@ -164,7 +165,9 @@ module controller(
// unswizzle control bits
// squash control signals if coming from an illegal compressed instruction
assign IllegalBaseInstrFaultD = ControlsD[0];
// On RV32E, can't write to upper 16 registers. Checking reads to upper 16 is more costly so disregard them.
assign IllegalERegAdrD = `E_SUPPORTED & RegWriteD & InstrD[11];
assign IllegalBaseInstrFaultD = ControlsD[0] | IllegalERegAdrD;
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, W64D, CSRReadD,
PrivilegedD, FenceD, MDUD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD;

View File

@ -37,7 +37,9 @@ module regfile (
input logic [`XLEN-1:0] wd3,
output logic [`XLEN-1:0] rd1, rd2);
logic [`XLEN-1:0] rf[31:1];
localparam NUMREGS = `E_SUPPORTED ? 16 : 32; // only 16 registers in E mode
logic [`XLEN-1:0] rf[NUMREGS-1:1];
integer i;
// three ported register file
@ -49,7 +51,7 @@ module regfile (
// reset is intended for simulation only, not synthesis
always_ff @(negedge clk) // or posedge reset)
if (reset) for(i=1; i<32; i++) rf[i] <= 0;
if (reset) for(i=1; i<NUMREGS; i++) rf[i] <= 0;
else if (we3) rf[a3] <= wd3;
assign #2 rd1 = (a1 != 0) ? rf[a1] : 0;

View File

@ -333,6 +333,7 @@ module riscvassertions;
assert (`S_SUPPORTED | `MEM_VIRTMEM == 0) else $error("Virtual memory requires S mode support");
assert (`DIV_BITSPERCYCLE == 1 | `DIV_BITSPERCYCLE==2 | `DIV_BITSPERCYCLE==4) else $error("Illegal number of divider bits/cycle: DIV_BITSPERCYCLE must be 1, 2, or 4");
assert (`F_SUPPORTED | ~`D_SUPPORTED) else $error("Can't support double (D) without supporting float (F)");
assert (`I_SUPPORTED ^ `E_SUPPORTED) else $error("Exactly one of I and E must be supported");
assert (`XLEN == 64 | ~`D_SUPPORTED) else $error("Wally does not yet support D extensions on RV32");
assert (`DCACHE_WAYSIZEINBYTES <= 4096 | `MEM_DCACHE == 0 | `MEM_VIRTMEM == 0) else $error("DCACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
assert (`DCACHE_LINELENINBITS >= 128 | `MEM_DCACHE == 0) else $error("DCACHE_LINELENINBITS must be at least 128 when caches are enabled");