forked from Github_Repos/cvw
Added E extension, and downloaded riscv-dv and embench-iot to addins
This commit is contained in:
parent
b63e53bbdb
commit
55b4423329
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -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
1
addins/embench-iot
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 261a65e0a2d3e8d62d81b1d8fe7e309a096bc6a9
|
1
addins/riscv-dv
Submodule
1
addins/riscv-dv
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 96c1ee6f371f2754c45b4831fcab95f6671689d9
|
170
bin/exe2memfile.pl
Executable file
170
bin/exe2memfile.pl
Executable 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"); }
|
||||
}
|
@ -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
|
||||
@ -25,7 +33,7 @@ make all:
|
||||
# make -C ../../addins/imperas-riscv-tests
|
||||
# make -C ../../addins/imperas-riscv-tests XLEN=64
|
||||
# cd ../../addins/imperas-riscv-tests; elf2hex.sh
|
||||
|
||||
|
||||
# Link Linux test vectors (fix this later***)
|
||||
#cd ../../tests/linux-testgen/linux-testvectors/;./tvLinker.sh
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user