From 55b442332923949cc27bdd61ef752d7f296e70a2 Mon Sep 17 00:00:00 2001 From: David Harris Date: Mon, 17 Jan 2022 14:42:59 +0000 Subject: [PATCH] Added E extension, and downloaded riscv-dv and embench-iot to addins --- .gitmodules | 6 ++ addins/embench-iot | 1 + addins/riscv-dv | 1 + bin/exe2memfile.pl | 170 ++++++++++++++++++++++++++++++++ pipelined/regression/Makefile | 10 +- pipelined/src/ieu/controller.sv | 5 +- pipelined/src/ieu/regfile.sv | 6 +- 7 files changed, 195 insertions(+), 4 deletions(-) create mode 160000 addins/embench-iot create mode 160000 addins/riscv-dv create mode 100755 bin/exe2memfile.pl diff --git a/.gitmodules b/.gitmodules index bd2adf26..8eca4d01 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/addins/embench-iot b/addins/embench-iot new file mode 160000 index 00000000..261a65e0 --- /dev/null +++ b/addins/embench-iot @@ -0,0 +1 @@ +Subproject commit 261a65e0a2d3e8d62d81b1d8fe7e309a096bc6a9 diff --git a/addins/riscv-dv b/addins/riscv-dv new file mode 160000 index 00000000..96c1ee6f --- /dev/null +++ b/addins/riscv-dv @@ -0,0 +1 @@ +Subproject commit 96c1ee6f371f2754c45b4831fcab95f6671689d9 diff --git a/bin/exe2memfile.pl b/bin/exe2memfile.pl new file mode 100755 index 00000000..70e51167 --- /dev/null +++ b/bin/exe2memfile.pl @@ -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() { + 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"); } +} \ No newline at end of file diff --git a/pipelined/regression/Makefile b/pipelined/regression/Makefile index f4207429..56bd60c9 100644 --- a/pipelined/regression/Makefile +++ b/pipelined/regression/Makefile @@ -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 diff --git a/pipelined/src/ieu/controller.sv b/pipelined/src/ieu/controller.sv index 9916287f..99bf3a64 100644 --- a/pipelined/src/ieu/controller.sv +++ b/pipelined/src/ieu/controller.sv @@ -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; diff --git a/pipelined/src/ieu/regfile.sv b/pipelined/src/ieu/regfile.sv index 9ab7c8f7..9b161096 100644 --- a/pipelined/src/ieu/regfile.sv +++ b/pipelined/src/ieu/regfile.sv @@ -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