Version 1.9.
This commit is contained in:
parent
bcb5b33726
commit
ec254f5491
18
README.md
18
README.md
|
@ -1,6 +1,6 @@
|
|||
# EH1 SweRV RISC-V Core<sup>TM</sup> 1.8 from Western Digital
|
||||
# EH1 RISC-V SweRV Core<sup>TM</sup> 1.9 from Western Digital
|
||||
|
||||
This repository contains the SweRV EH1 Core<sup>TM</sup> design RTL
|
||||
This repository contains the EH1 SweRV Core<sup>TM</sup> design RTL
|
||||
|
||||
## License
|
||||
|
||||
|
@ -16,7 +16,7 @@ Files under the [tools](tools/) directory may be available under a different lic
|
|||
│ ├── dec # Decode, Registers and Exceptions
|
||||
│ ├── dmi # DMI block
|
||||
│ ├── exu # EXU (ALU/MUL/DIV)
|
||||
│ ├── ifu # Fetch & Branch Prediction
|
||||
│ ├── ifu # Fetch & Branch Predictor
|
||||
│ ├── include
|
||||
│ ├── lib
|
||||
│ └── lsu # Load/Store
|
||||
|
@ -28,7 +28,7 @@ Files under the [tools](tools/) directory may be available under a different lic
|
|||
|
||||
## Dependencies
|
||||
|
||||
- Verilator **(4.030 or later)** must be installed on the system if running with verilator
|
||||
- Verilator **(4.102 or later)** must be installed on the system if running with verilator
|
||||
- If adding/removing instructions, espresso must be installed (used by *tools/coredecode*)
|
||||
- RISCV tool chain (based on gcc version 7.3 or higher) must be
|
||||
installed so that it can be used to prepare RISCV binaries to run.
|
||||
|
@ -61,7 +61,7 @@ the `-target=name` option to swerv.config.
|
|||
|
||||
This script derives the following consistent set of include files :
|
||||
|
||||
$RV_ROOT/configs/snapshots/default
|
||||
snapshots/default
|
||||
├── common_defines.vh # `defines for testbench or design
|
||||
├── defines.h # #defines for C/assembly headers
|
||||
├── pd_defines.vh # `defines for physical design
|
||||
|
@ -87,13 +87,10 @@ Example for csh or its derivatives:
|
|||
*(Name your snapshot to distinguish it from the default. Without an explicit name, it will update/override the __default__ snapshot)*
|
||||
For example if `mybuild` is the name for the snapshot:
|
||||
|
||||
set BUILD_PATH environment variable:
|
||||
|
||||
`setenv BUILD_PATH snapshots/mybuild`
|
||||
|
||||
`$RV_ROOT/configs/swerv.config [configuration options..] -snapshot=mybuild`
|
||||
|
||||
Snapshots are placed in `$BUILD_PATH` directory
|
||||
Snapshots are placed in ./snapshots directory
|
||||
|
||||
**Building an FPGA speed optimized model:**
|
||||
Use ``-fpga_optimize=1`` option to ``swerv.config`` to build a model that removes clock gating logic from flop model so that the FPGA builds can run at higher speeds. **This is now the default option for
|
||||
|
@ -191,10 +188,13 @@ The `$RV_ROOT/testbench/asm` directory contains following tests ready to simula
|
|||
```
|
||||
hello_world - default test to run, prints Hello World message to screen and console.log
|
||||
hello_world_dccm - the same as above, but takes the string from preloaded DCCM.
|
||||
hello_world_iccm - the same as above, but CPU copies the code from external memory to ICCM via AXI LSU to DMA bridge
|
||||
and then jumps there. The test runs only on CPU configurations with ICCM and AXI bus.
|
||||
cmark - coremark benchmark running with code and data in external memories
|
||||
cmark_dccm - the same as above, running data and stack from DCCM (faster)
|
||||
cmark_iccm - the same as above, but with code preloaded to iccm - runs only on CPU with ICCM
|
||||
use CONF_PARAMS=-set=iccm_enable argument to `make` to build CPU with ICCM
|
||||
dhry - dhrystone benchmark - example of multi source files program
|
||||
```
|
||||
|
||||
The `$RV_ROOT/testbench/hex` directory contains precompiled hex files of the tests, ready for simulation in case RISCV SW tools are not installed.
|
||||
|
|
|
@ -243,6 +243,9 @@ my $pdfile = "$build_path/pd_defines.vh";
|
|||
# Whisper config file path
|
||||
my $whisperfile = "$build_path/whisper.json";
|
||||
|
||||
# Default linker file
|
||||
my $linkerfile = "$build_path/link.ld";
|
||||
|
||||
# Perl defines file path
|
||||
my $perlfile = "$build_path/perl_configs.pl";
|
||||
|
||||
|
@ -368,8 +371,8 @@ our @triggers = (#{{{
|
|||
},
|
||||
{
|
||||
"reset" => ["0x23e00000", "0x00000000", "0x00000000"],
|
||||
"mask" => ["0x081818c7", "0xffffffff", "0x00000000"],
|
||||
"poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"]
|
||||
"mask" => ["0x081810c7", "0xffffffff", "0x00000000"],
|
||||
"poke_mask" => ["0x081810c7", "0xffffffff", "0x00000000"]
|
||||
},
|
||||
{
|
||||
"reset" => ["0x23e00000", "0x00000000", "0x00000000"],
|
||||
|
@ -378,8 +381,8 @@ our @triggers = (#{{{
|
|||
},
|
||||
{
|
||||
"reset" => ["0x23e00000", "0x00000000", "0x00000000"],
|
||||
"mask" => ["0x081818c7", "0xffffffff", "0x00000000"],
|
||||
"poke_mask" => ["0x081818c7", "0xffffffff", "0x00000000"]
|
||||
"mask" => ["0x081810c7", "0xffffffff", "0x00000000"],
|
||||
"poke_mask" => ["0x081810c7", "0xffffffff", "0x00000000"]
|
||||
},
|
||||
);#}}}
|
||||
|
||||
|
@ -417,7 +420,7 @@ our %csr = (#{{{
|
|||
"exists" => "true",
|
||||
},
|
||||
"mimpid" => {
|
||||
"reset" => "0x5",
|
||||
"reset" => "0x6",
|
||||
"mask" => "0x0",
|
||||
"exists" => "true",
|
||||
},
|
||||
|
@ -621,7 +624,7 @@ our %csr = (#{{{
|
|||
"mfdc" => {
|
||||
"number" => "0x7f9",
|
||||
"reset" => "0x00070000",
|
||||
"mask" => "0x000707ff",
|
||||
"mask" => "0x000727ff",
|
||||
"exists" => "true",
|
||||
},
|
||||
"dmst" => {
|
||||
|
@ -1153,57 +1156,6 @@ if($config{bht}{bht_size}==2048){
|
|||
$config{bht}{bht_addr_hi} = 5;
|
||||
$config{bht}{bht_array_depth}= 4;
|
||||
}
|
||||
#if($config{bht}{bht_size}==2048){
|
||||
# $config{bht}{bht_ghr_size}= 8;
|
||||
# $config{bht}{bht_ghr_range}= "7:0";
|
||||
# $config{bht}{bht_ghr_pad}= "fghr[7:4],3'b0";
|
||||
# $config{bht}{bht_ghr_pad2}= "fghr[7:3],2'b0";
|
||||
# $config{bht}{bht_array_depth}= 256;
|
||||
# $config{bht}{bht_addr_hi}= 11;
|
||||
#} elsif($config{bht}{bht_size}==1024){
|
||||
# $config{bht}{bht_ghr_size}= 7;
|
||||
# $config{bht}{bht_ghr_range}= "6:0";
|
||||
# $config{bht}{bht_ghr_pad}= "fghr[6:4],3'b0";
|
||||
# $config{bht}{bht_ghr_pad2}= "fghr[6:3],2'b0";
|
||||
# $config{bht}{bht_array_depth}= 128;
|
||||
# $config{bht}{bht_addr_hi}= 10;
|
||||
#} elsif($config{bht}{bht_size}==512){
|
||||
# $config{bht}{bht_ghr_size}= 6;
|
||||
# $config{bht}{bht_ghr_range}= "5:0";
|
||||
# $config{bht}{bht_ghr_pad}= "fghr[5:4],3'b0";
|
||||
# $config{bht}{bht_ghr_pad2}= "fghr[5:3],2'b0";
|
||||
# $config{bht}{bht_array_depth}= 64;
|
||||
# $config{bht}{bht_addr_hi}= 9;
|
||||
#} elsif($config{bht}{bht_size}==256){
|
||||
# $config{bht}{bht_ghr_size}= 5;
|
||||
# $config{bht}{bht_ghr_range}= "4:0";
|
||||
# $config{bht}{bht_ghr_pad}= "fghr[4],3'b0";
|
||||
# $config{bht}{bht_ghr_pad2}= "fghr[4:3],2'b0";
|
||||
# $config{bht}{bht_addr_hi} = 8;
|
||||
# $config{bht}{bht_array_depth}= 32;
|
||||
#} elsif($config{bht}{bht_size}==128){
|
||||
# $config{bht}{bht_ghr_size}= 5;
|
||||
# $config{bht}{bht_ghr_range}= "4:0";
|
||||
# $config{bht}{bht_ghr_pad}= "fghr[4],3'b0";
|
||||
# $config{bht}{bht_ghr_pad2}= "fghr[4:3],2'b0";
|
||||
# $config{bht}{bht_addr_hi} = 7;
|
||||
# $config{bht}{bht_array_depth}= 16;
|
||||
#} elsif($config{bht}{bht_size}==64){
|
||||
# $config{bht}{bht_ghr_size}= 4;
|
||||
# $config{bht}{bht_ghr_range}= "3:0";
|
||||
# $config{bht}{bht_ghr_pad}= "3'b0 ";
|
||||
# $config{bht}{bht_ghr_pad2}= "fghr[4],2'b0";
|
||||
# $config{bht}{bht_addr_hi} = 6;
|
||||
# $config{bht}{bht_array_depth}= 8;
|
||||
#} elsif($config{bht}{bht_size}==32){
|
||||
# $config{bht}{bht_ghr_size}= 3;
|
||||
# $config{bht}{bht_ghr_range}= "2:0";
|
||||
# $config{bht}{bht_ghr_pad}= "2'b0 ";
|
||||
# $config{bht}{bht_ghr_pad2}= "2'b0";
|
||||
# $config{bht}{bht_addr_hi} = 5;
|
||||
# $config{bht}{bht_array_depth}= 4;
|
||||
# $config{bht}{bht_ghr_size_2} = 1;
|
||||
#}
|
||||
|
||||
$config{bht}{bht_hash_string} = &ghrhash($config{btb}{btb_index1_hi}, $config{bht}{bht_ghr_size}-1);
|
||||
|
||||
|
@ -1603,6 +1555,8 @@ print FILE Data::Dumper->Dump([\%config], [ qw(*config) ]);
|
|||
print FILE "1;\n";
|
||||
close FILE;
|
||||
|
||||
# Default linker script
|
||||
gen_default_linker_script();
|
||||
# Done ##################################################################
|
||||
#
|
||||
exit(0);
|
||||
|
@ -1960,7 +1914,7 @@ sub dump_whisper_config{#{{{
|
|||
$jh{memmap}{inst} = [@inst_mem_prot] if @inst_mem_prot;
|
||||
$jh{memmap}{data} = [@data_mem_prot] if @data_mem_prot;
|
||||
$config{memmap}{consoleio} = $config{memmap}{serialio} if exists $config{memmap}{serialio};
|
||||
foreach my $tag (qw (size page_size serialio consoleio)) {
|
||||
foreach my $tag (qw ( size page_size serialio consoleio)) {
|
||||
$jh{memmap}{$tag} = $config{memmap}{$tag} if exists $config{memmap}{$tag};
|
||||
}
|
||||
|
||||
|
@ -2048,3 +2002,56 @@ sub log2 {
|
|||
my ($n) = @_;
|
||||
return log($n)/log(2);
|
||||
}
|
||||
|
||||
sub gen_default_linker_script {#{{{
|
||||
|
||||
open (FILE, ">$linkerfile") || die "Cannot open $linkerfile for writing $!";
|
||||
print "$self: Writing $linkerfile\n";
|
||||
print FILE "/*\n";
|
||||
print_header();
|
||||
|
||||
my $io = "0xd0580000";
|
||||
$io = $config{memmap}{serialio} if exists $config{memmap}{serialio};
|
||||
|
||||
my $iccm = ""; my $iccm_ctl = "";
|
||||
if (exists $config{iccm} and $config{iccm}{iccm_enable}) {
|
||||
my $sa = $config{iccm}{iccm_sadr}; my $ea = $config{iccm}{iccm_eadr};
|
||||
$iccm = " . = $sa ;";
|
||||
$iccm_ctl = " . = 0xfffffff0; .iccm.ctl . : { LONG($sa); LONG($ea) }" ;
|
||||
}
|
||||
|
||||
my $sa = $config{memmap}{external_data}; my $dccm_ctl = "";
|
||||
if (exists $config{dccm} and $config{dccm}{dccm_enable}) {
|
||||
$sa = $config{dccm}{dccm_sadr};
|
||||
$dccm_ctl = " . = 0xfffffff8; .data.ctl : { LONG($sa); LONG(STACK) }" ;
|
||||
}
|
||||
my $data_loc = " . = $sa ;";
|
||||
|
||||
print FILE <<EOF;
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH( "riscv" )
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = $config{reset_vec};
|
||||
.text.init . : { *(.text.init) }
|
||||
$iccm
|
||||
.text . : { *(.text) }
|
||||
_end = .;
|
||||
. = $io;
|
||||
.data.io . : { *(.data.io) }
|
||||
$data_loc
|
||||
.data : ALIGN(0x800) { *(.*data) *(.rodata*)}
|
||||
.bss : {BSS_START = .; *(.*bss)}
|
||||
BSS_END = .;
|
||||
STACK = ALIGN(16) + 0x1000;
|
||||
$iccm_ctl
|
||||
$dccm_ctl
|
||||
}
|
||||
|
||||
EOF
|
||||
close FILE;
|
||||
} #}}}
|
||||
|
||||
|
|
|
@ -1,42 +1,34 @@
|
|||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env python
|
||||
from fusesoc.capi2.generator import Generator
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
if sys.version[0] == '2':
|
||||
devnull = open(os.devnull, 'w')
|
||||
else:
|
||||
from subprocess import DEVNULL as devnull
|
||||
|
||||
class SwervConfigGenerator(Generator):
|
||||
def run(self):
|
||||
build_path="swerv_config"
|
||||
script_root = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '..'))
|
||||
files = [
|
||||
{os.path.join(build_path, "common_defines.vh") : {
|
||||
{"configs/snapshots/default/common_defines.vh" : {
|
||||
"copyto" : "config/common_defines.vh",
|
||||
"file_type" : "systemVerilogSource"}},
|
||||
{os.path.join(build_path, "pic_ctrl_verilator_unroll.sv") : {
|
||||
{"configs/snapshots/default/pic_ctrl_verilator_unroll.sv" : {
|
||||
"copyto" : "config/pic_ctrl_verilator_unroll.sv",
|
||||
"is_include_file" : True,
|
||||
"file_type" : "systemVerilogSource"}},
|
||||
{os.path.join(build_path, "pic_map_auto.h") : {
|
||||
{"configs/snapshots/default/pic_map_auto.h" : {
|
||||
"copyto" : "config/pic_map_auto.h",
|
||||
"is_include_file" : True,
|
||||
"file_type" : "systemVerilogSource"}}]
|
||||
|
||||
tmp_dir = os.path.join(tempfile.mkdtemp(), 'core')
|
||||
shutil.copytree(script_root, tmp_dir)
|
||||
shutil.copytree(self.files_root, tmp_dir)
|
||||
|
||||
cwd = tmp_dir
|
||||
|
||||
env = os.environ.copy()
|
||||
env['RV_ROOT'] = tmp_dir
|
||||
env['BUILD_PATH'] = build_path
|
||||
args = ['configs/swerv.config'] + self.config.get('args', [])
|
||||
rc = subprocess.call(args, cwd=cwd, env=env, stdout=devnull)
|
||||
rc = subprocess.call(args, cwd=cwd, env=env)
|
||||
if rc:
|
||||
exit(1)
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ module dbg (
|
|||
// general inputs
|
||||
input logic clk,
|
||||
input logic free_clk,
|
||||
input logic rst_l,
|
||||
input logic rst_l, // This includes both top rst and dbg rst
|
||||
input logic dbg_rst_l,
|
||||
input logic clk_override,
|
||||
input logic scan_mode
|
||||
|
@ -165,13 +165,12 @@ module dbg (
|
|||
logic dmstatus_dmerr_wren;
|
||||
logic dmstatus_resumeack_wren;
|
||||
logic dmstatus_resumeack_din;
|
||||
logic dmstatus_havereset_wren;
|
||||
logic dmstatus_havereset_rst;
|
||||
logic dmstatus_haveresetn_wren;
|
||||
logic dmstatus_resumeack;
|
||||
logic dmstatus_unavail;
|
||||
logic dmstatus_running;
|
||||
logic dmstatus_halted;
|
||||
logic dmstatus_havereset;
|
||||
logic dmstatus_havereset, dmstatus_haveresetn;
|
||||
|
||||
// dmcontrol
|
||||
logic resumereq;
|
||||
|
@ -297,7 +296,7 @@ module dbg (
|
|||
|
||||
// Reset logic
|
||||
assign dbg_dm_rst_l = dbg_rst_l & (dmcontrol_reg[0] | scan_mode);
|
||||
assign dbg_core_rst_l = ~dmcontrol_reg[1];
|
||||
assign dbg_core_rst_l = ~dmcontrol_reg[1] | scan_mode;
|
||||
|
||||
// system bus register
|
||||
// sbcs[31:29], sbcs - [22]:sbbusyerror, [21]: sbbusy, [20]:sbreadonaddr, [19:17]:sbaccess, [16]:sbautoincrement, [15]:sbreadondata, [14:12]:sberror, sbsize=32, 128=0, 64/32/16/8 are legal
|
||||
|
@ -308,7 +307,7 @@ module dbg (
|
|||
assign sbcs_reg[4:0] = 5'b01111;
|
||||
assign sbcs_wren = (dmi_reg_addr == 7'h38) & dmi_reg_en & dmi_reg_wr_en & (sb_state == SBIDLE); // & (sbcs_reg[14:12] == 3'b000);
|
||||
assign sbcs_sbbusyerror_wren = (sbcs_wren & dmi_reg_wdata[22]) |
|
||||
((sb_state != SBIDLE) & dmi_reg_en & ((dmi_reg_addr == 7'h39) | (dmi_reg_addr == 7'h3c) | (dmi_reg_addr == 7'h3d)));
|
||||
(sbcs_reg[21] & dmi_reg_en & ((dmi_reg_wr_en & (dmi_reg_addr == 7'h39)) | (dmi_reg_addr == 7'h3c) | (dmi_reg_addr == 7'h3d)));
|
||||
assign sbcs_sbbusyerror_din = ~(sbcs_wren & dmi_reg_wdata[22]); // Clear when writing one
|
||||
|
||||
rvdffs #(1) sbcs_sbbusyerror_reg (.din(sbcs_sbbusyerror_din), .dout(sbcs_reg[22]), .en(sbcs_sbbusyerror_wren), .rst_l(dbg_dm_rst_l), .clk(sb_free_clk));
|
||||
|
@ -387,15 +386,15 @@ module dbg (
|
|||
assign dmstatus_resumeack_wren = ((dbg_state == RESUMING) & dec_tlu_resume_ack) | (dmstatus_resumeack & resumereq & dmstatus_halted);
|
||||
assign dmstatus_resumeack_din = (dbg_state == RESUMING) & dec_tlu_resume_ack;
|
||||
|
||||
assign dmstatus_havereset_wren = (dmi_reg_addr == 7'h10) & dmi_reg_wdata[1] & dmi_reg_en & dmi_reg_wr_en;
|
||||
assign dmstatus_havereset_rst = (dmi_reg_addr == 7'h10) & dmi_reg_wdata[28] & dmi_reg_en & dmi_reg_wr_en;
|
||||
assign dmstatus_haveresetn_wren = (dmi_reg_addr == 7'h10) & dmi_reg_wdata[28] & dmi_reg_en & dmi_reg_wr_en & dmcontrol_reg[0]; // clear the havereset
|
||||
assign dmstatus_havereset = ~dmstatus_haveresetn;
|
||||
|
||||
assign dmstatus_unavail = dmcontrol_reg[1] | ~rst_l;
|
||||
assign dmstatus_running = ~(dmstatus_unavail | dmstatus_halted);
|
||||
|
||||
rvdffs #(1) dmstatus_resumeack_reg (.din(dmstatus_resumeack_din), .dout(dmstatus_resumeack), .en(dmstatus_resumeack_wren), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
|
||||
rvdff #(1) dmstatus_halted_reg (.din(dec_tlu_dbg_halted & ~dec_tlu_mpc_halted_only), .dout(dmstatus_halted), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
|
||||
rvdffsc #(1) dmstatus_havereset_reg (.din(1'b1), .dout(dmstatus_havereset), .en(dmstatus_havereset_wren), .clear(dmstatus_havereset_rst), .rst_l(dbg_dm_rst_l), .clk(dbg_free_clk));
|
||||
rvdffs #(1) dmstatus_haveresetn_reg (.din(1'b1), .dout(dmstatus_haveresetn), .en(dmstatus_haveresetn_wren), .rst_l(rst_l), .clk(dbg_free_clk));
|
||||
|
||||
// haltsum0 register
|
||||
assign haltsum0_reg[31:1] = '0;
|
||||
|
@ -631,7 +630,7 @@ module dbg (
|
|||
case (sb_state)
|
||||
SBIDLE: begin
|
||||
sb_nxtstate = sbdata0wr_access ? WAIT_WR : WAIT_RD;
|
||||
sb_state_en = (sbdata0wr_access | sbreadondata_access | sbreadonaddr_access) & ~(|sbcs_reg[14:12]);
|
||||
sb_state_en = (sbdata0wr_access | sbreadondata_access | sbreadonaddr_access) & ~(|sbcs_reg[14:12]) & ~sbcs_reg[22];
|
||||
sbcs_sbbusy_wren = sb_state_en; // set the single read bit if it is a singlread command
|
||||
sbcs_sbbusy_din = 1'b1;
|
||||
sbcs_sberror_wren = sbcs_wren & (|dmi_reg_wdata[14:12]); // write to clear the error bits
|
||||
|
|
|
@ -206,7 +206,7 @@ csr[ csr_mfdc ] = { csr_mfdc presync postsync }
|
|||
csr[ csr_dcsr ] = { csr_dcsr }
|
||||
csr[ csr_dpc ] = { csr_dpc }
|
||||
csr[ csr_mtsel ] = { csr_mtsel }
|
||||
csr[ csr_mtdata1 ] = { csr_mtdata1 postsync }
|
||||
csr[ csr_mtdata1 ] = { csr_mtdata1 presync postsync }
|
||||
csr[ csr_mtdata2 ] = { csr_mtdata2 postsync }
|
||||
csr[ csr_mhpmc3 ] = { csr_mhpmc3 presync }
|
||||
csr[ csr_mhpmc4 ] = { csr_mhpmc4 presync }
|
||||
|
|
|
@ -157,6 +157,8 @@ module dec
|
|||
|
||||
input logic iccm_dma_sb_error, // ICCM DMA single bit error
|
||||
|
||||
input logic dma_mem_dccm_req,
|
||||
|
||||
input logic exu_i0_flush_final, // slot0 flush
|
||||
input logic exu_i1_flush_final, // slot1 flush
|
||||
|
||||
|
@ -378,6 +380,7 @@ module dec
|
|||
output logic dec_tlu_sideeffect_posted_disable, // disable posted writes to side-effect address
|
||||
output logic dec_tlu_core_ecc_disable, // disable core ECC
|
||||
output logic dec_tlu_sec_alu_disable, // disable secondary ALU
|
||||
output logic dec_tlu_dccm_nonblock_dma_disable, // disable dma nonblock
|
||||
output logic dec_tlu_non_blocking_disable, // disable non blocking loads
|
||||
output logic dec_tlu_fast_div_disable, // disable fast divider
|
||||
output logic dec_tlu_bpred_disable, // disable branch prediction
|
||||
|
|
|
@ -70,6 +70,7 @@ module dec_tlu_ctl
|
|||
input logic lsu_pmu_bus_error, // D side bus error
|
||||
input logic lsu_pmu_bus_busy, // D side bus busy
|
||||
|
||||
input logic dma_mem_dccm_req,
|
||||
|
||||
input logic iccm_dma_sb_error, // I side dma single bit error
|
||||
|
||||
|
@ -232,6 +233,7 @@ module dec_tlu_ctl
|
|||
output logic dec_tlu_dual_issue_disable, // disable dual issue
|
||||
output logic dec_tlu_core_ecc_disable, // disable core ECC
|
||||
output logic dec_tlu_sec_alu_disable, // disable secondary ALU
|
||||
output logic dec_tlu_dccm_nonblock_dma_disable, // disable dma nonblock
|
||||
output logic dec_tlu_non_blocking_disable, // disable non blocking loads
|
||||
output logic dec_tlu_fast_div_disable, // disable fast divider
|
||||
output logic dec_tlu_bpred_disable, // disable branch prediction
|
||||
|
@ -256,7 +258,8 @@ module dec_tlu_ctl
|
|||
logic dec_csr_wen_wb_mod, clk_override, e4e5_int_clk, nmi_lsu_load_type, nmi_lsu_store_type, nmi_int_detected_f, nmi_lsu_load_type_f,
|
||||
nmi_lsu_store_type_f, allow_dbg_halt_csr_write, dbg_cmd_done_ns, i_cpu_run_req_d1_raw, debug_mode_status, lsu_single_ecc_error_wb,
|
||||
i0_mp_e4, i1_mp_e4, sel_npc_e4, sel_npc_wb, ce_int, mtval_capture_lsu_wb, wr_mdeau_wb, micect_cout_nc, miccmect_cout_nc,
|
||||
mdccmect_cout_nc, nmi_in_debug_mode, dpc_capture_npc, dpc_capture_pc, tdata_load, tdata_opcode, tdata_action, perfcnt_halted;
|
||||
mdccmect_cout_nc, nmi_in_debug_mode, dpc_capture_npc, dpc_capture_pc, tdata_load, tdata_opcode, tdata_action, perfcnt_halted, tdata_chain,
|
||||
tdata_kill_write;
|
||||
|
||||
|
||||
logic reset_delayed, reset_detect, reset_detected;
|
||||
|
@ -359,7 +362,7 @@ module dec_tlu_ctl
|
|||
logic [2:0] trigger_chain;
|
||||
logic i0_trigger_hit_e4, i0_trigger_hit_raw_e4, i0_trigger_action_e4,
|
||||
trigger_hit_e4, trigger_hit_wb, i0_trigger_hit_wb,
|
||||
mepc_trigger_hit_sel_pc_e4,
|
||||
mepc_trigger_hit_sel_pc_e4, i0_trigger_set_hit_e4, i1_trigger_set_hit_e4,
|
||||
mepc_trigger_hit_sel_pc_wb;
|
||||
logic i1_trigger_hit_e4, i1_trigger_hit_raw_e4, i1_trigger_action_e4;
|
||||
logic [3:0] update_hit_bit_e4, update_hit_bit_wb, i0_iside_trigger_has_pri_e4, i1_iside_trigger_has_pri_e4,
|
||||
|
@ -370,7 +373,7 @@ module dec_tlu_ctl
|
|||
logic wr_mcgc_wb, wr_mfdc_wb;
|
||||
logic [8:0] mcgc;
|
||||
logic [18:0] mfdc;
|
||||
logic [13:0] mfdc_int, mfdc_ns;
|
||||
logic [14:0] mfdc_int, mfdc_ns;
|
||||
logic i_cpu_halt_req_sync_qual, i_cpu_run_req_sync_qual, pmu_fw_halt_req_ns, pmu_fw_halt_req_f, int_timer_stalled,
|
||||
fw_halt_req, enter_pmu_fw_halt_req, pmu_fw_tlu_halted, pmu_fw_tlu_halted_f, internal_pmu_fw_halt_mode,
|
||||
internal_pmu_fw_halt_mode_f, int_timer0_int_hold, int_timer1_int_hold, int_timer0_int_hold_f, int_timer1_int_hold_f;
|
||||
|
@ -409,9 +412,11 @@ module dec_tlu_ctl
|
|||
rvoclkhdr lsu_e3_e4_cgc ( .en(lsu_error_pkt_dc3.exc_valid | lsu_error_pkt_dc4.exc_valid | lsu_error_pkt_dc3.single_ecc_error | lsu_error_pkt_dc4.single_ecc_error | clk_override), .l1clk(lsu_e3_e4_clk), .* );
|
||||
rvoclkhdr lsu_e4_e5_cgc ( .en(lsu_error_pkt_dc4.exc_valid | lsu_exc_valid_wb | clk_override), .l1clk(lsu_e4_e5_clk), .* );
|
||||
|
||||
logic freeze_rfpc_e4, rfpc_postsync_in, rfpc_postsync, dma_mem_dccm_req_f;
|
||||
|
||||
logic e4e5_clk, e4_valid, e5_valid, e4e5_valid, internal_dbg_halt_mode_f, internal_dbg_halt_mode_f2, internal_dbg_halt_mode_f3;
|
||||
assign e4_valid = dec_tlu_i0_valid_e4 | dec_tlu_i1_valid_e4;
|
||||
assign e4e5_valid = e4_valid | e5_valid;
|
||||
assign e4e5_valid = e4_valid | e5_valid | freeze_rfpc_e4;
|
||||
rvoclkhdr e4e5_cgc ( .en(e4e5_valid | clk_override), .l1clk(e4e5_clk), .* );
|
||||
rvoclkhdr e4e5_int_cgc ( .en(e4e5_valid | internal_dbg_halt_mode_f | i_cpu_run_req_d1 | interrupt_valid | interrupt_valid_wb | reset_delayed | pause_expired_e4 | pause_expired_wb | clk_override), .l1clk(e4e5_int_clk), .* );
|
||||
|
||||
|
@ -496,7 +501,7 @@ module dec_tlu_ctl
|
|||
|
||||
// acks back to interface
|
||||
assign mpc_debug_halt_ack_ns = mpc_halt_state_f & internal_dbg_halt_mode_f & mpc_debug_halt_req_sync & core_empty;
|
||||
assign mpc_debug_run_ack_ns = (mpc_debug_run_req_sync & ~dbg_halt_state_ns & ~mpc_debug_halt_req_sync) | (mpc_debug_run_ack_f & mpc_debug_run_req_sync) ;
|
||||
assign mpc_debug_run_ack_ns = (mpc_debug_run_req_sync & ~internal_dbg_halt_mode & ~mpc_debug_halt_req_sync) | (mpc_debug_run_ack_f & mpc_debug_run_req_sync) ;
|
||||
|
||||
// Pins
|
||||
assign mpc_debug_halt_ack = mpc_debug_halt_ack_f;
|
||||
|
@ -580,7 +585,7 @@ module dec_tlu_ctl
|
|||
assign pause_expired_e4 = ~dec_pause_state & dec_pause_state_f & ~(ext_int_ready | ce_int_ready | timer_int_ready | int_timer0_int_hold_f | int_timer1_int_hold_f | nmi_int_detected) & ~interrupt_valid_wb & ~debug_halt_req_f & ~pmu_fw_halt_req_f & ~halt_taken_f;
|
||||
|
||||
// stall dma fifo if a fence is pending, decode is waiting for lsu to idle before decoding the fence inst.
|
||||
assign dec_tlu_stall_dma = dec_fence_pending;
|
||||
assign dec_tlu_stall_dma = dec_fence_pending & dec_tlu_dccm_nonblock_dma_disable; // Stall the DMA for fences when chicken bit is set;
|
||||
assign dec_tlu_flush_leak_one_wb = dec_tlu_flush_lower_wb & dcsr[`DCSR_STEP] & (dec_tlu_resume_ack | dcsr_single_step_running);
|
||||
assign dec_tlu_flush_err_wb = dec_tlu_flush_lower_wb & (ic_perr_wb | iccm_sbecc_wb);
|
||||
|
||||
|
@ -661,13 +666,18 @@ module dec_tlu_ctl
|
|||
// Actions include breakpoint, or dmode. Dmode is only possible if the DMODE bit is set.
|
||||
// Otherwise, take a breakpoint.
|
||||
assign trigger_action[3:0] = {mtdata1_t3[`MTDATA1_ACTION] & mtdata1_t3[`MTDATA1_DMODE],
|
||||
mtdata1_t2[`MTDATA1_ACTION] & mtdata1_t2[`MTDATA1_DMODE],
|
||||
mtdata1_t2[`MTDATA1_ACTION] & mtdata1_t2[`MTDATA1_DMODE] & ~mtdata1_t2[`MTDATA1_CHAIN],
|
||||
mtdata1_t1[`MTDATA1_ACTION] & mtdata1_t1[`MTDATA1_DMODE],
|
||||
mtdata1_t0[`MTDATA1_ACTION] & mtdata1_t0[`MTDATA1_DMODE]};
|
||||
mtdata1_t0[`MTDATA1_ACTION] & mtdata1_t0[`MTDATA1_DMODE] & ~mtdata1_t0[`MTDATA1_CHAIN]};
|
||||
|
||||
// this is needed to set the HIT bit in the triggers
|
||||
assign update_hit_bit_e4[3:0] = ({4{i0_trigger_hit_e4 }} & i0_trigger_chain_masked_e4[3:0]) |
|
||||
({4{i1_trigger_hit_e4 & ~i0_trigger_hit_e4}} & i1_trigger_chain_masked_e4[3:0]);
|
||||
assign i0_trigger_set_hit_e4 = |i0_trigger_e4[3:0] & ~(dec_tlu_flush_lower_wb | dec_tlu_dbg_halted | rfpc_i0_e4);
|
||||
assign i1_trigger_set_hit_e4 = |i1_trigger_e4[3:0] & ~(dec_tlu_flush_lower_wb | dec_tlu_dbg_halted |
|
||||
~tlu_i0_commit_cmt | exu_i0_br_mp_e4 | dec_tlu_dbg_halted |
|
||||
lsu_freeze_pulse_e4 | lsu_i0_rfnpc_dc4 | rfpc_i1_e4);
|
||||
|
||||
assign update_hit_bit_e4[3:0] = ({4{i0_trigger_set_hit_e4}} & {i0_trigger_chain_masked_e4[3], i0_trigger_e4[2], i0_trigger_chain_masked_e4[1], i0_trigger_e4[0]} ) |
|
||||
({4{i1_trigger_set_hit_e4}} & {i1_trigger_chain_masked_e4[3], i1_trigger_e4[2], i1_trigger_chain_masked_e4[1], i1_trigger_e4[0]} );
|
||||
|
||||
// action, 1 means dmode. Simultaneous triggers with at least 1 set for dmode force entire action to dmode.
|
||||
assign i0_trigger_action_e4 = |(i0_trigger_chain_masked_e4[3:0] & trigger_action[3:0]);
|
||||
|
@ -730,7 +740,7 @@ module dec_tlu_ctl
|
|||
|
||||
assign cpu_halt_ack = i_cpu_halt_req_d1 & pmu_fw_tlu_halted_f;
|
||||
assign cpu_halt_status = (pmu_fw_tlu_halted_f & ~i_cpu_run_req_d1) | (o_cpu_halt_status & ~i_cpu_run_req_d1 & ~internal_dbg_halt_mode_f);
|
||||
assign cpu_run_ack = (o_cpu_halt_status & i_cpu_run_req_sync_qual) | (o_cpu_run_ack & i_cpu_run_req_sync_qual);
|
||||
assign cpu_run_ack = (o_cpu_halt_status & i_cpu_run_req_d1_raw) | (o_cpu_run_ack & i_cpu_run_req_sync);
|
||||
assign debug_mode_status = internal_dbg_halt_mode_f;
|
||||
assign o_debug_mode_status = debug_mode_status;// & ~mpc_debug_run_ack_f;
|
||||
|
||||
|
@ -813,10 +823,21 @@ module dec_tlu_ctl
|
|||
assign tlu_i0_kill_writeb_e4 = rfpc_i0_e4 | lsu_i0_exc_dc4 | inst_acc_e4 | (illegal_e4 & dec_tlu_dbg_halted) | i0_trigger_hit_e4 ;
|
||||
assign tlu_i1_kill_writeb_e4 = rfpc_i0_e4 | rfpc_i1_e4 | lsu_exc_valid_e4 | exu_i0_br_mp_e4 | inst_acc_e4 | (illegal_e4 & dec_tlu_dbg_halted) | trigger_hit_e4 | lsu_i0_rfnpc_dc4;
|
||||
|
||||
// Auto postsync loads that freeze when DMA requests are stalled, if not disabled with MFDC[13].
|
||||
assign freeze_rfpc_e4 = (lsu_block_interrupts_e4 | (dma_mem_dccm_req_f & lsu_freeze_e4)) & ~dec_tlu_flush_lower_wb & mfdc[13];
|
||||
assign rfpc_postsync_in = (freeze_rfpc_e4 | rfpc_postsync) & ~tlu_i0_commit_cmt;
|
||||
assign dec_tlu_dccm_nonblock_dma_disable = ~mfdc[13];
|
||||
|
||||
rvdff #(2) freezerfpc_ff (.*, .clk(free_clk),
|
||||
.din({rfpc_postsync_in, dma_mem_dccm_req}),
|
||||
.dout({rfpc_postsync, dma_mem_dccm_req_f}));
|
||||
|
||||
|
||||
// refetch PC, microarch flush
|
||||
// ic errors only in pipe0
|
||||
assign rfpc_i0_e4 = dec_tlu_i0_valid_e4 & ~tlu_flush_lower_wb & (exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4 | lsu_i0_rfpc_dc4) & ~i0_trigger_hit_e4;
|
||||
assign rfpc_i1_e4 = dec_tlu_i1_valid_e4 & ~tlu_flush_lower_wb & ~i0_exception_valid_e4 & ~exu_i0_br_mp_e4 & ~lsu_i0_exc_dc4 & ~lsu_i0_rfnpc_dc4 &
|
||||
assign rfpc_i0_e4 = freeze_rfpc_e4 | (
|
||||
dec_tlu_i0_valid_e4 & ~tlu_flush_lower_wb & (exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4 | lsu_i0_rfpc_dc4) & ~i0_trigger_hit_e4);
|
||||
assign rfpc_i1_e4 = dec_tlu_i1_valid_e4 & ~tlu_flush_lower_wb & ~i0_exception_valid_e4 & ~exu_i0_br_mp_e4 & ~lsu_i0_exc_dc4 & ~lsu_i0_rfnpc_dc4 &
|
||||
~(exu_i0_br_error_e4 | exu_i0_br_start_error_e4 | ic_perr_e4 | iccm_sbecc_e4 | lsu_i0_rfpc_dc4) &
|
||||
(exu_i1_br_error_e4 | exu_i1_br_start_error_e4 | lsu_i1_rfpc_dc4) &
|
||||
~trigger_hit_e4;
|
||||
|
@ -1355,13 +1376,15 @@ module dec_tlu_ctl
|
|||
// MFDC (RW) Feature Disable Control
|
||||
// [31:19] : Reserved, reads 0x0
|
||||
// [18:16] : DMA QoS Prty
|
||||
// [15:11] : Reserved, reads 0x0
|
||||
// [15:14] : Reserved, reads 0x0
|
||||
// [13] : Disable blocking DMA
|
||||
// [12:11] : Reserved, reads 0x0
|
||||
// [10] : Disable dual issue
|
||||
// [9] : Disable pic multiple ints
|
||||
// [8] : Disable core ecc
|
||||
// [7] : Disable secondary alu?s
|
||||
// [6] : Disable multiple outstanding sideeffect accesses to bus
|
||||
// [5] : Disable non-blocking loads/divides
|
||||
// [5] : Disable non-blocking divides
|
||||
// [4] : Disable fast divide
|
||||
// [3] : Disable branch prediction and return stack
|
||||
// [2] : Disable write buffer coalescing
|
||||
|
@ -1372,15 +1395,15 @@ module dec_tlu_ctl
|
|||
|
||||
assign wr_mfdc_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MFDC);
|
||||
|
||||
rvdffe #(14) mfdc_ff (.*, .en(wr_mfdc_wb), .din(mfdc_ns[13:0]), .dout(mfdc_int[13:0]));
|
||||
rvdffe #(15) mfdc_ff (.*, .en(wr_mfdc_wb), .din(mfdc_ns[14:0]), .dout(mfdc_int[14:0]));
|
||||
|
||||
`ifdef RV_BUILD_AXI4
|
||||
// flip poweron value of bit 6 for AXI build
|
||||
assign mfdc_ns[13:0] = {~dec_csr_wrdata_wb[18:16],dec_csr_wrdata_wb[10:7], ~dec_csr_wrdata_wb[6], dec_csr_wrdata_wb[5:0]};
|
||||
assign mfdc[18:0] = {~mfdc_int[13:11], 5'b0, mfdc_int[10:7], ~mfdc_int[6], mfdc_int[5:0]};
|
||||
assign mfdc_ns[14:0] = {~dec_csr_wrdata_wb[18:16],dec_csr_wrdata_wb[13], dec_csr_wrdata_wb[10:7], ~dec_csr_wrdata_wb[6], dec_csr_wrdata_wb[5:0]};
|
||||
assign mfdc[18:0] = {~mfdc_int[14:12], 2'b0, mfdc_int[11], 2'b0, mfdc_int[10:7], ~mfdc_int[6], mfdc_int[5:0]};
|
||||
`else
|
||||
assign mfdc_ns[13:0] = {~dec_csr_wrdata_wb[18:16],dec_csr_wrdata_wb[10:0]};
|
||||
assign mfdc[18:0] = {~mfdc_int[13:11], 5'b0, mfdc_int[10:0]};
|
||||
assign mfdc_ns[14:0] = {~dec_csr_wrdata_wb[18:16],dec_csr_wrdata_wb[13],dec_csr_wrdata_wb[10:0]};
|
||||
assign mfdc[18:0] = {~mfdc_int[14:12], 2'b0, mfdc_int[11], 2'b0, mfdc_int[10:0]};
|
||||
`endif
|
||||
|
||||
assign dec_tlu_dma_qos_prty[2:0] = mfdc[18:16];
|
||||
|
@ -1451,7 +1474,7 @@ module dec_tlu_ctl
|
|||
// only capture error bus if the MDSEAC reg is not locked
|
||||
assign mdseac_locked_ns = mdseac_en | (mdseac_locked_f & ~wr_mdeau_wb);
|
||||
|
||||
assign mdseac_en = (lsu_imprecise_error_store_any | lsu_imprecise_error_load_any) & ~mdseac_locked_f;
|
||||
assign mdseac_en = (lsu_imprecise_error_store_any | lsu_imprecise_error_load_any) & ~nmi_int_detected_f & ~mdseac_locked_f;
|
||||
|
||||
rvdffe #(32) mdseac_ff (.*, .en(mdseac_en), .din(lsu_imprecise_error_addr_any[31:0]), .dout(mdseac[31:0]));
|
||||
|
||||
|
@ -1783,10 +1806,19 @@ module dec_tlu_ctl
|
|||
// don't allow clearing DMODE and action=1
|
||||
assign tdata_action = (dec_csr_wrdata_wb[27] & dbg_tlu_halted_f) & dec_csr_wrdata_wb[12];
|
||||
|
||||
// Chain bit has conditions: WARL for triggers without chains. Force to zero if dmode is 0 but next trigger dmode is 1.
|
||||
assign tdata_chain = mtsel[0] ? 1'b0 : // triggers 1 and 3 chain bit is always zero
|
||||
mtsel[1] ? dec_csr_wrdata_wb[11] & ~(mtdata1_t3[`MTDATA1_DMODE] & ~dec_csr_wrdata_wb[27]) : // trigger 2
|
||||
dec_csr_wrdata_wb[11] & ~(mtdata1_t1[`MTDATA1_DMODE] & ~dec_csr_wrdata_wb[27]); // trigger 0
|
||||
|
||||
// Kill mtdata1 write if dmode=1 but prior trigger has dmode=0/chain=1. Only applies to T1 and T3
|
||||
assign tdata_kill_write = mtsel[1] ? dec_csr_wrdata_wb[27] & (~mtdata1_t2[`MTDATA1_DMODE] & mtdata1_t2[`MTDATA1_CHAIN]) : // trigger 3
|
||||
dec_csr_wrdata_wb[27] & (~mtdata1_t0[`MTDATA1_DMODE] & mtdata1_t0[`MTDATA1_CHAIN]) ; // trigger 1
|
||||
|
||||
assign tdata_wrdata_wb[9:0] = {dec_csr_wrdata_wb[27] & dbg_tlu_halted_f,
|
||||
dec_csr_wrdata_wb[20:19],
|
||||
tdata_action,
|
||||
dec_csr_wrdata_wb[11],
|
||||
tdata_chain,
|
||||
dec_csr_wrdata_wb[7:6],
|
||||
tdata_opcode,
|
||||
dec_csr_wrdata_wb[1],
|
||||
|
@ -1797,7 +1829,7 @@ module dec_tlu_ctl
|
|||
assign mtdata1_t0_ns[9:0] = wr_mtdata1_t0_wb ? tdata_wrdata_wb[9:0] :
|
||||
{mtdata1_t0[9], update_hit_bit_wb[0] | mtdata1_t0[8], mtdata1_t0[7:0]};
|
||||
|
||||
assign wr_mtdata1_t1_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTDATA1) & (mtsel[1:0] == 2'b01) & (~mtdata1_t1[`MTDATA1_DMODE] | dbg_tlu_halted_f);
|
||||
assign wr_mtdata1_t1_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTDATA1) & (mtsel[1:0] == 2'b01) & (~mtdata1_t1[`MTDATA1_DMODE] | dbg_tlu_halted_f) & ~tdata_kill_write;
|
||||
assign mtdata1_t1_ns[9:0] = wr_mtdata1_t1_wb ? tdata_wrdata_wb[9:0] :
|
||||
{mtdata1_t1[9], update_hit_bit_wb[1] | mtdata1_t1[8], mtdata1_t1[7:0]};
|
||||
|
||||
|
@ -1805,7 +1837,7 @@ module dec_tlu_ctl
|
|||
assign mtdata1_t2_ns[9:0] = wr_mtdata1_t2_wb ? tdata_wrdata_wb[9:0] :
|
||||
{mtdata1_t2[9], update_hit_bit_wb[2] | mtdata1_t2[8], mtdata1_t2[7:0]};
|
||||
|
||||
assign wr_mtdata1_t3_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTDATA1) & (mtsel[1:0] == 2'b11) & (~mtdata1_t3[`MTDATA1_DMODE] | dbg_tlu_halted_f);
|
||||
assign wr_mtdata1_t3_wb = dec_csr_wen_wb_mod & (dec_csr_wraddr_wb[11:0] == `MTDATA1) & (mtsel[1:0] == 2'b11) & (~mtdata1_t3[`MTDATA1_DMODE] | dbg_tlu_halted_f) & ~tdata_kill_write;
|
||||
assign mtdata1_t3_ns[9:0] = wr_mtdata1_t3_wb ? tdata_wrdata_wb[9:0] :
|
||||
{mtdata1_t3[9], update_hit_bit_wb[3] | mtdata1_t3[8], mtdata1_t3[7:0]};
|
||||
|
||||
|
@ -2438,12 +2470,13 @@ assign presync = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
|
|||
&dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]) | (
|
||||
!dec_csr_rdaddr_d[6]&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]
|
||||
&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]) | (
|
||||
dec_csr_rdaddr_d[10]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
|
||||
&dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[4]
|
||||
&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[1]&!dec_csr_rdaddr_d[0]) | (
|
||||
dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
|
||||
&dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]) | (dec_csr_rdaddr_d[11]
|
||||
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&dec_csr_rdaddr_d[1]
|
||||
&!dec_csr_rdaddr_d[0]) | (dec_csr_rdaddr_d[7]&!dec_csr_rdaddr_d[5]
|
||||
&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]&!dec_csr_rdaddr_d[2]
|
||||
&dec_csr_rdaddr_d[1]);
|
||||
&dec_csr_rdaddr_d[2]&!dec_csr_rdaddr_d[1]) | (dec_csr_rdaddr_d[7]
|
||||
&!dec_csr_rdaddr_d[5]&!dec_csr_rdaddr_d[4]&!dec_csr_rdaddr_d[3]
|
||||
&!dec_csr_rdaddr_d[2]&dec_csr_rdaddr_d[1]);
|
||||
|
||||
assign postsync = (dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d[4]&dec_csr_rdaddr_d[3]
|
||||
&dec_csr_rdaddr_d[0]) | (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[5]
|
||||
|
@ -2542,7 +2575,7 @@ assign legal_csr = (!dec_csr_rdaddr_d[11]&!dec_csr_rdaddr_d[10]&dec_csr_rdaddr_d
|
|||
|
||||
|
||||
assign dec_tlu_presync_d = presync & dec_csr_any_unq_d & ~dec_csr_wen_unq_d;
|
||||
assign dec_tlu_postsync_d = postsync & dec_csr_any_unq_d;
|
||||
assign dec_tlu_postsync_d = (postsync & dec_csr_any_unq_d) | rfpc_postsync;
|
||||
assign valid_csr = ( legal_csr & (~(csr_dcsr | csr_dpc | csr_dmst | csr_dicawics | csr_dicad0 | csr_dicad1 | csr_dicago) | dbg_tlu_halted_f));
|
||||
|
||||
assign dec_csr_legal_d = ( dec_csr_any_unq_d &
|
||||
|
@ -2553,7 +2586,7 @@ assign dec_csr_legal_d = ( dec_csr_any_unq_d &
|
|||
assign dec_csr_rddata_d[31:0] = ( ({32{csr_misa}} & 32'h40001104) |
|
||||
({32{csr_mvendorid}} & 32'h00000045) |
|
||||
({32{csr_marchid}} & 32'h0000000b) |
|
||||
({32{csr_mimpid}} & 32'h5) |
|
||||
({32{csr_mimpid}} & 32'h6) |
|
||||
({32{csr_mstatus}} & {19'b0, 2'b11, 3'b0, mstatus[1], 3'b0, mstatus[0], 3'b0}) |
|
||||
({32{csr_mtvec}} & {mtvec[30:1], 1'b0, mtvec[0]}) |
|
||||
({32{csr_mip}} & {1'b0, mip[5:3], 16'b0, mip[2], 3'b0, mip[1], 3'b0, mip[0], 3'b0}) |
|
||||
|
|
|
@ -105,6 +105,8 @@ module dma_ctrl (
|
|||
input logic dec_tlu_stall_dma, // stall dma accesses, tlu is attempting to enter halt/debug mode
|
||||
input logic [2:0] dec_tlu_dma_qos_prty, // DMA QoS priority coming from MFDC [18:15]
|
||||
|
||||
output logic dma_mem_dccm_req, // Used by TLU to do rfpc in case of freeze
|
||||
|
||||
input logic scan_mode
|
||||
);
|
||||
|
||||
|
@ -236,8 +238,8 @@ module dma_ctrl (
|
|||
//------------------------LOGIC STARTS HERE---------------------------------
|
||||
|
||||
// FIFO inputs
|
||||
assign fifo_addr_in[31:0] = dbg_cmd_valid ? dbg_cmd_addr[31:0] : axi_mstr_addr[31:0];
|
||||
assign fifo_sz_in[2:0] = dbg_cmd_valid ? {1'b0,dbg_cmd_size[1:0]} : axi_mstr_size[2:0];
|
||||
assign fifo_addr_in[31:0] = dbg_cmd_valid ? dbg_cmd_addr[31:0] : (axi_mstr_write & (axi_mstr_wstrb[7:0] == 8'hf0)) ? {axi_mstr_addr[31:3],1'b1,axi_mstr_addr[1:0]} : axi_mstr_addr[31:0];
|
||||
assign fifo_sz_in[2:0] = dbg_cmd_valid ? {1'b0,dbg_cmd_size[1:0]} : (axi_mstr_write & ((axi_mstr_wstrb[7:0] == 8'h0f) | (axi_mstr_wstrb[7:0] == 8'hf0))) ? 3'h2 : axi_mstr_size[2:0];
|
||||
assign fifo_write_in = dbg_cmd_valid ? dbg_cmd_write : axi_mstr_write;
|
||||
assign fifo_posted_write_in = axi_mstr_valid & axi_mstr_posted_write;
|
||||
assign fifo_dbg_in = dbg_cmd_valid;
|
||||
|
@ -315,11 +317,13 @@ module dma_ctrl (
|
|||
// Error logic
|
||||
assign dma_address_error = axi_mstr_valid & (~(dma_addr_in_dccm | dma_addr_in_iccm)); // request not for ICCM or DCCM
|
||||
assign dma_alignment_error = axi_mstr_valid & ~dma_address_error &
|
||||
(((axi_mstr_size[2:0] == 3'h1) & (axi_mstr_addr[0] | (axi_mstr_write & (axi_mstr_wstrb[axi_mstr_addr[2:0]+:2] != 2'b11)))) | // HW size but unaligned
|
||||
((axi_mstr_size[2:0] == 3'h2) & ((|axi_mstr_addr[1:0]) | (axi_mstr_write & (axi_mstr_wstrb[axi_mstr_addr[2:0]+:4] != 4'hf)))) | // W size but unaligned
|
||||
((axi_mstr_size[2:0] == 3'h3) & ((|axi_mstr_addr[2:0]) | (axi_mstr_write & (axi_mstr_wstrb[7:0] != 8'hff)))) | // DW size but unaligned
|
||||
(dma_addr_in_iccm & ~((axi_mstr_size[1:0] == 2'b10) | (axi_mstr_size[1:0] == 2'b11))) | // ICCM access not word size
|
||||
(dma_addr_in_dccm & axi_mstr_write & ~((axi_mstr_size[1:0] == 2'b10) | (axi_mstr_size[1:0] == 2'b11)))); // DCCM write not word size
|
||||
(((axi_mstr_size[2:0] == 3'h1) & axi_mstr_addr[0]) | // HW size but unaligned
|
||||
((axi_mstr_size[2:0] == 3'h2) & (|axi_mstr_addr[1:0])) | // W size but unaligned
|
||||
((axi_mstr_size[2:0] == 3'h3) & (|axi_mstr_addr[2:0])) | // DW size but unaligned
|
||||
(dma_addr_in_iccm & ~((axi_mstr_size[1:0] == 2'b10) | (axi_mstr_size[1:0] == 2'b11))) | // ICCM access not word size
|
||||
(dma_addr_in_dccm & axi_mstr_write & ~((axi_mstr_size[1:0] == 2'b10) | (axi_mstr_size[1:0] == 2'b11))) | // DCCM write not word size
|
||||
(axi_mstr_write & (axi_mstr_size[2:0] == 3'h2) & (axi_mstr_wstrb[axi_mstr_addr[2:0]+:4] != 4'hf)) | // Write byte enables not aligned for word store
|
||||
(axi_mstr_write & (axi_mstr_size[2:0] == 3'h3) & ~((axi_mstr_wstrb[7:0] == 8'h0f) | (axi_mstr_wstrb[7:0] == 8'hf0) | (axi_mstr_wstrb[7:0] == 8'hff)))); // Write byte enables not aligned for dword store
|
||||
|
||||
//Dbg outputs
|
||||
assign dma_dbg_ready = fifo_empty & dbg_dma_bubble;
|
||||
|
@ -357,12 +361,13 @@ module dma_ctrl (
|
|||
rvdffs #(3) nack_count_dff(.din(dma_nack_count_d[2:0]), .dout(dma_nack_count[2:0]), .en(dma_mem_req), .clk(dma_free_clk), .*);
|
||||
|
||||
// Core outputs
|
||||
assign dma_mem_req = fifo_valid[RdPtr] & ~fifo_rpend[RdPtr] & ~fifo_done[RdPtr] & ~(|fifo_error[RdPtr]) & (~fifo_write[RdPtr] | fifo_data_valid[RdPtr]);
|
||||
assign dma_mem_req = fifo_valid[RdPtr] & ~fifo_rpend[RdPtr] & ~fifo_done[RdPtr] & ~(|fifo_error[RdPtr]) & (~fifo_write[RdPtr] | fifo_data_valid[RdPtr]);
|
||||
assign dma_mem_dccm_req = dma_mem_req & fifo_dccm_valid[RdPtr]; // Only used by TLU for rfpc
|
||||
assign dma_dccm_req = dma_mem_req & fifo_dccm_valid[RdPtr] & dccm_ready;
|
||||
assign dma_iccm_req = dma_mem_req & fifo_iccm_valid[RdPtr] & iccm_ready;
|
||||
assign dma_mem_addr[31:0] = fifo_addr[RdPtr];
|
||||
assign dma_mem_sz[2:0] = fifo_sz[RdPtr];
|
||||
assign dma_mem_write = fifo_write[RdPtr];
|
||||
assign dma_mem_addr[31:0] = fifo_addr[RdPtr];
|
||||
assign dma_mem_sz[2:0] = fifo_sz[RdPtr];
|
||||
assign dma_mem_write = fifo_write[RdPtr];
|
||||
assign dma_mem_wdata[63:0] = fifo_data[RdPtr];
|
||||
|
||||
// Address check dccm
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
//-------------------------------------------------------------------------------------
|
||||
|
||||
module dmi_wrapper(
|
||||
|
||||
// JTAG signals
|
||||
input trst_n, // JTAG reset
|
||||
input tck, // JTAG clock
|
||||
|
|
|
@ -41,7 +41,7 @@ module lsu
|
|||
input logic dec_tlu_cancel_e4, // cancel the bus load in dc4 and reset the freeze
|
||||
|
||||
// chicken signals
|
||||
input logic dec_tlu_non_blocking_disable, // disable the non block
|
||||
input logic dec_tlu_dccm_nonblock_dma_disable, // disable dma nonblock
|
||||
input logic dec_tlu_wb_coalescing_disable, // disable the write buffer coalesce
|
||||
input logic dec_tlu_ld_miss_byp_wb_disable, // disable the miss bypass in the write buffer
|
||||
input logic dec_tlu_sideeffect_posted_disable, // disable posted writes to sideeffect addr to the bus
|
||||
|
|
|
@ -158,7 +158,7 @@ module lsu_addrcheck
|
|||
// 3. DCCM -> PIC offset cross when DCCM/PIC in same region (PIC access are always word aligned so no cross possible from PIC->DCCM)
|
||||
// 4. Ld/St access to picm are not word aligned
|
||||
// 5. Address not in protected space or dccm/pic region
|
||||
if (DCCM_REGION == PIC_REGION) begin
|
||||
if (DCCM_ENABLE & (DCCM_REGION == PIC_REGION)) begin
|
||||
assign access_fault_dc1 = ((start_addr_in_dccm_region_dc1 & ~(start_addr_in_dccm_dc1 | start_addr_in_pic_dc1)) |
|
||||
(end_addr_in_dccm_region_dc1 & ~(end_addr_in_dccm_dc1 | end_addr_in_pic_dc1)) |
|
||||
(start_addr_in_dccm_dc1 & end_addr_in_pic_dc1) |
|
||||
|
|
|
@ -42,7 +42,7 @@ module lsu_bus_buffer
|
|||
input logic clk,
|
||||
input logic rst_l,
|
||||
input logic scan_mode,
|
||||
input logic dec_tlu_non_blocking_disable, // disable non block
|
||||
input logic dec_tlu_dccm_nonblock_dma_disable, // disable dma nonblock
|
||||
input logic dec_tlu_wb_coalescing_disable, // disable write buffer coalescing
|
||||
input logic dec_tlu_ld_miss_byp_wb_disable, // disable ld miss bypass of the write buffer
|
||||
input logic dec_tlu_sideeffect_posted_disable, // disable posted writes to sideeffect addr to the bus
|
||||
|
@ -752,7 +752,7 @@ module lsu_bus_buffer
|
|||
|
||||
// Freeze logic
|
||||
assign FreezePtrEn = lsu_busreq_dc3 & lsu_pkt_dc3.load & ld_freeze_dc3;
|
||||
assign ld_freeze_en = (is_sideeffects_dc2 | dec_nonblock_load_freeze_dc2 | dec_tlu_non_blocking_disable) & lsu_busreq_dc2 & lsu_pkt_dc2.load & ~lsu_freeze_dc3 & ~flush_dc2_up & ~ld_full_hit_dc2;
|
||||
assign ld_freeze_en = (dec_nonblock_load_freeze_dc2 | (dec_tlu_dccm_nonblock_dma_disable & is_sideeffects_dc2)) & lsu_busreq_dc2 & lsu_pkt_dc2.load & ~lsu_freeze_dc3 & ~flush_dc2_up & ~ld_full_hit_dc2;
|
||||
always_comb begin
|
||||
ld_freeze_rst = flush_dc3 | (dec_tlu_cancel_e4 & ld_freeze_dc3);
|
||||
for (int i=0; i<DEPTH; i++) begin
|
||||
|
@ -766,7 +766,7 @@ module lsu_bus_buffer
|
|||
assign ld_bus_error_addr_dc3[31:0] = buf_addr[FreezePtr][31:0];
|
||||
|
||||
// Non blocking ports
|
||||
assign lsu_nonblock_load_valid_dc3 = lsu_busreq_dc3 & lsu_pkt_dc3.valid & lsu_pkt_dc3.load & ~flush_dc3 & ~dec_nonblock_load_freeze_dc3 & ~lsu_freeze_dc3 & ~dec_tlu_non_blocking_disable;
|
||||
assign lsu_nonblock_load_valid_dc3 = lsu_busreq_dc3 & lsu_pkt_dc3.valid & lsu_pkt_dc3.load & ~flush_dc3 & ~dec_nonblock_load_freeze_dc3 & ~lsu_freeze_dc3;
|
||||
assign lsu_nonblock_load_tag_dc3[DEPTH_LOG2-1:0] = WrPtr0_dc3[DEPTH_LOG2-1:0];
|
||||
assign lsu_nonblock_load_inv_dc5 = lsu_nonblock_load_valid_dc5 & ~lsu_commit_dc5;
|
||||
assign lsu_nonblock_load_inv_tag_dc5[DEPTH_LOG2-1:0] = WrPtr0_dc5[DEPTH_LOG2-1:0]; // dc5 tag needs to be accurate even if there is no invalidate
|
||||
|
@ -781,10 +781,10 @@ module lsu_bus_buffer
|
|||
lsu_nonblock_load_data_hi[31:0] = '0;
|
||||
for (int i=0; i<DEPTH; i++) begin
|
||||
// Use buf_rst[i] instead of buf_state_en[i] for timing
|
||||
lsu_nonblock_load_data_valid_hi |= lsu_bus_clk_en_q & (buf_state[i] == DONE) & buf_rst[i] & ~dec_tlu_non_blocking_disable & buf_nb[i] & ~buf_error[i] & (buf_dual[i] & buf_dualhi[i]);
|
||||
lsu_nonblock_load_data_valid_lo |= lsu_bus_clk_en_q & (buf_state[i] == DONE) & buf_rst[i] & ~dec_tlu_non_blocking_disable & buf_nb[i] & ~buf_error[i] & (~buf_dual[i] | ~buf_dualhi[i]);
|
||||
lsu_nonblock_load_data_error_hi |= lsu_bus_clk_en_q & (buf_state[i] == DONE) & buf_rst[i] & ~dec_tlu_non_blocking_disable & buf_error[i] & buf_nb[i] & (buf_dual[i] & buf_dualhi[i]);
|
||||
lsu_nonblock_load_data_error_lo |= lsu_bus_clk_en_q & (buf_state[i] == DONE) & buf_rst[i] & ~dec_tlu_non_blocking_disable & buf_error[i] & buf_nb[i] & (~buf_dual[i] | ~buf_dualhi[i]);
|
||||
lsu_nonblock_load_data_valid_hi |= lsu_bus_clk_en_q & (buf_state[i] == DONE) & buf_rst[i] & buf_nb[i] & ~buf_error[i] & (buf_dual[i] & buf_dualhi[i]);
|
||||
lsu_nonblock_load_data_valid_lo |= lsu_bus_clk_en_q & (buf_state[i] == DONE) & buf_rst[i] & buf_nb[i] & ~buf_error[i] & (~buf_dual[i] | ~buf_dualhi[i]);
|
||||
lsu_nonblock_load_data_error_hi |= lsu_bus_clk_en_q & (buf_state[i] == DONE) & buf_rst[i] & buf_error[i] & buf_nb[i] & (buf_dual[i] & buf_dualhi[i]);
|
||||
lsu_nonblock_load_data_error_lo |= lsu_bus_clk_en_q & (buf_state[i] == DONE) & buf_rst[i] & buf_error[i] & buf_nb[i] & (~buf_dual[i] | ~buf_dualhi[i]);
|
||||
lsu_nonblock_load_data_tag[DEPTH_LOG2-1:0] |= DEPTH_LOG2'(i) & {DEPTH_LOG2{((buf_state[i] == DONE) & buf_nb[i] & buf_rst[i] & (~buf_dual[i] | ~buf_dualhi[i]))}};
|
||||
lsu_nonblock_load_data_lo[31:0] |= buf_data[i][31:0] & {32{((buf_state[i] == DONE) & buf_nb[i] & buf_rst[i] & (~buf_dual[i] | ~buf_dualhi[i]))}};
|
||||
lsu_nonblock_load_data_hi[31:0] |= buf_data[i][31:0] & {32{((buf_state[i] == DONE) & buf_nb[i] & buf_rst[i] & (buf_dual[i] & buf_dualhi[i]))}};
|
||||
|
|
|
@ -28,7 +28,7 @@ module lsu_bus_intf
|
|||
input logic clk,
|
||||
input logic rst_l,
|
||||
input logic scan_mode,
|
||||
input logic dec_tlu_non_blocking_disable, // disable non block
|
||||
input logic dec_tlu_dccm_nonblock_dma_disable, // disable dma nonblock
|
||||
input logic dec_tlu_wb_coalescing_disable, // disable write buffer coalescing
|
||||
input logic dec_tlu_ld_miss_byp_wb_disable, // disable ld miss bypass of the write buffer
|
||||
input logic dec_tlu_sideeffect_posted_disable, // disable posted writes to sideeffect addr to the bus
|
||||
|
|
|
@ -811,6 +811,8 @@ module swerv
|
|||
logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] exu_i0_br_index_e4;
|
||||
logic [`RV_BTB_ADDR_HI:`RV_BTB_ADDR_LO] exu_i1_br_index_e4;
|
||||
|
||||
logic dma_mem_dccm_req;
|
||||
|
||||
logic dma_dccm_req;
|
||||
logic dma_iccm_req;
|
||||
logic [31:0] dma_mem_addr;
|
||||
|
@ -865,6 +867,7 @@ module swerv
|
|||
|
||||
// feature disable from mfdc
|
||||
logic dec_tlu_sec_alu_disable;
|
||||
logic dec_tlu_dccm_nonblock_dma_disable; // disable dma nonblock
|
||||
logic dec_tlu_non_blocking_disable;
|
||||
logic dec_tlu_fast_div_disable;
|
||||
logic dec_tlu_bpred_disable;
|
||||
|
@ -970,6 +973,7 @@ module swerv
|
|||
assign core_dbg_rddata[31:0] = dma_dbg_cmd_done ? dma_dbg_rddata[31:0] : dec_dbg_rddata[31:0];
|
||||
|
||||
dbg dbg (
|
||||
.rst_l(core_rst_l),
|
||||
.clk_override(dec_tlu_misc_clk_override),
|
||||
.*
|
||||
);
|
||||
|
@ -1034,6 +1038,7 @@ module swerv
|
|||
|
||||
// AXI4 -> AHB Gasket for LSU
|
||||
axi4_to_ahb #(.TAG(LSU_BUS_TAG)) lsu_axi4_to_ahb (
|
||||
.rst_l(core_rst_l),
|
||||
.clk_override(dec_tlu_bus_clk_override),
|
||||
.bus_clk_en(lsu_bus_clk_en),
|
||||
|
||||
|
@ -1089,6 +1094,7 @@ module swerv
|
|||
|
||||
// AXI4 -> AHB Gasket for System Bus
|
||||
axi4_to_ahb #(.TAG(SB_BUS_TAG)) sb_axi4_to_ahb (
|
||||
.rst_l(dbg_rst_l),
|
||||
.clk_override(dec_tlu_bus_clk_override),
|
||||
.bus_clk_en(dbg_bus_clk_en),
|
||||
|
||||
|
@ -1144,6 +1150,7 @@ module swerv
|
|||
|
||||
axi4_to_ahb #(.TAG(IFU_BUS_TAG)) ifu_axi4_to_ahb (
|
||||
.clk(clk),
|
||||
.rst_l(core_rst_l),
|
||||
.clk_override(dec_tlu_bus_clk_override),
|
||||
.bus_clk_en(ifu_bus_clk_en),
|
||||
|
||||
|
@ -1199,6 +1206,7 @@ module swerv
|
|||
|
||||
//AHB -> AXI4 Gasket for DMA
|
||||
ahb_to_axi4 #(.TAG(DMA_BUS_TAG)) dma_ahb_to_axi4 (
|
||||
.rst_l(core_rst_l),
|
||||
.clk_override(dec_tlu_bus_clk_override),
|
||||
.bus_clk_en(dma_bus_clk_en),
|
||||
|
||||
|
|
|
@ -401,6 +401,7 @@ module swerv_wrapper
|
|||
logic [31:0] dmi_reg_rdata;
|
||||
logic dmi_hard_reset;
|
||||
|
||||
|
||||
// Instantiate the swerv core
|
||||
swerv swerv (
|
||||
.*
|
||||
|
@ -414,7 +415,6 @@ module swerv_wrapper
|
|||
|
||||
// Instantiate the JTAG/DMI
|
||||
dmi_wrapper dmi_wrapper (
|
||||
|
||||
// JTAG signals
|
||||
.trst_n(jtag_trst_n), // JTAG reset
|
||||
.tck (jtag_tck), // JTAG clock
|
||||
|
@ -433,7 +433,7 @@ module swerv_wrapper
|
|||
.reg_en (dmi_reg_en), // 1 bit Write interface bit to Processor
|
||||
.reg_wr_en (dmi_reg_wr_en), // 1 bit Write enable to Processor
|
||||
.dmi_hard_reset (dmi_hard_reset) //a hard reset of the DTM, causing the DTM to forget about any outstanding DMI transactions
|
||||
);
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
# SweRV RISC-V Core<sup>TM</sup> 1.9 from Western Digital
|
||||
## Release Notes
|
||||
|
||||
* Removed unused scan_mode input from dmi_wrapper (PR#89)
|
||||
* Enhanced DMA/Side-Effect-load interlock to conditionally allow Side-Effect loads to be non-blocking
|
||||
* See PRM for new enable bit in MFDC[13]
|
||||
* Bug fixes for NMI, MPC, PMU corner cases, MPC ack timing fixes
|
||||
* Trigger chaining compliance fixes for 0.13.2 missing cases
|
||||
* Fixed qualification in DCCM access fault equation
|
||||
* Updated reset hookup for AHB gasket
|
||||
* Demo TB updates:
|
||||
* added AXI LSU/DMA bridge and ICCM preload by CPU test,
|
||||
* dhrystone test,
|
||||
* exec.log shows instruction mnemonics
|
||||
|
||||
|
||||
|
||||
# SweRV RISC-V Core<sup>TM</sup> 1.8 from Western Digital
|
||||
## Release Notes
|
||||
|
||||
|
|
|
@ -1,35 +1,6 @@
|
|||
#include "defines.h"
|
||||
|
||||
#define ITERATIONS 1
|
||||
extern int STACK;
|
||||
void main();
|
||||
|
||||
|
||||
#define STDOUT 0xd0580000
|
||||
|
||||
__asm (".section .text");
|
||||
__asm (".global _start");
|
||||
__asm ("_start:");
|
||||
|
||||
// Enable Caches in MRAC
|
||||
__asm ("li t0, 0x5f555555");
|
||||
__asm ("csrw 0x7c0, t0");
|
||||
|
||||
// Set stack pointer.
|
||||
__asm ("la sp, STACK");
|
||||
|
||||
__asm ("jal main");
|
||||
|
||||
// Write 0xff to STDOUT for TB to termiate test.
|
||||
__asm (".global _finish");
|
||||
__asm ("_finish:");
|
||||
__asm ("li t0, 0xd0580000");
|
||||
__asm ("addi t1, zero, 0xff");
|
||||
__asm ("sb t1, 0(t0)");
|
||||
__asm ("beq x0, x0, _finish");
|
||||
__asm (".rept 10");
|
||||
__asm ("nop");
|
||||
__asm (".endr");
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1200,7 +1171,7 @@ MAIN_RETURN_TYPE main(int argc, char *argv[]) {
|
|||
ee_printf("Total time (secs): %d\n",time_in_secs(total_time));
|
||||
if (time_in_secs(total_time) > 0)
|
||||
// ee_printf("Iterations/Sec : %d\n",default_num_contexts*results[0].iterations/time_in_secs(total_time));
|
||||
ee_printf("Iterat/Sec/MHz : %d.%d\n",1000*default_num_contexts*results[0].iterations/time_in_secs(total_time),
|
||||
ee_printf("Iterat/Sec/MHz : %d.%02d\n",1000*default_num_contexts*results[0].iterations/time_in_secs(total_time),
|
||||
100000*default_num_contexts*results[0].iterations/time_in_secs(total_time) % 100);
|
||||
#endif
|
||||
if (time_in_secs(total_time) < 10) {
|
||||
|
@ -2182,213 +2153,6 @@ void portable_fini(core_portable *p)
|
|||
}
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
// Special address. Writing (store byte instruction) to this address
|
||||
// causes the simulator to write to the console.
|
||||
volatile char __whisper_console_io = 0;
|
||||
|
||||
|
||||
static int
|
||||
whisperPutc(char c)
|
||||
{
|
||||
// __whisper_console_io = c;
|
||||
// __whisper_console_io = c;
|
||||
*(volatile char*)(STDOUT) = c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
whisperPuts(const char* s)
|
||||
{
|
||||
while (*s)
|
||||
whisperPutc(*s++);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
whisperPrintDecimal(int value)
|
||||
{
|
||||
char buffer[20];
|
||||
int charCount = 0;
|
||||
|
||||
unsigned neg = value < 0;
|
||||
if (neg)
|
||||
{
|
||||
value = -value;
|
||||
whisperPutc('-');
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
char c = '0' + (value % 10);
|
||||
value = value / 10;
|
||||
buffer[charCount++] = c;
|
||||
}
|
||||
while (value);
|
||||
|
||||
char* p = buffer + charCount - 1;
|
||||
for (unsigned i = 0; i < charCount; ++i)
|
||||
whisperPutc(*p--);
|
||||
|
||||
if (neg)
|
||||
charCount++;
|
||||
|
||||
return charCount;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
whisperPrintInt(int value, int base)
|
||||
{
|
||||
if (base == 10)
|
||||
return whisperPrintDecimal(value);
|
||||
|
||||
char buffer[20];
|
||||
int charCount = 0;
|
||||
|
||||
unsigned uu = value;
|
||||
|
||||
if (base == 8)
|
||||
{
|
||||
do
|
||||
{
|
||||
char c = '0' + (uu & 7);
|
||||
buffer[charCount++] = c;
|
||||
uu >>= 3;
|
||||
}
|
||||
while (uu);
|
||||
}
|
||||
else if (base == 16)
|
||||
{
|
||||
do
|
||||
{
|
||||
int digit = uu & 0xf;
|
||||
char c = digit < 10 ? '0' + digit : 'a' + digit - 10;
|
||||
buffer[charCount++] = c;
|
||||
uu >>= 4;
|
||||
}
|
||||
while (uu);
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
char* p = buffer + charCount - 1;
|
||||
for (unsigned i = 0; i < charCount; ++i)
|
||||
whisperPutc(*p--);
|
||||
|
||||
return charCount;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
whisperPrintfImpl(const char* format, va_list ap)
|
||||
{
|
||||
int count = 0; // Printed character count
|
||||
|
||||
for (const char* fp = format; *fp; fp++)
|
||||
{
|
||||
if (*fp != '%')
|
||||
{
|
||||
whisperPutc(*fp);
|
||||
++count;
|
||||
continue;
|
||||
}
|
||||
|
||||
++fp; // Skip %
|
||||
|
||||
if (*fp == 0)
|
||||
break;
|
||||
|
||||
if (*fp == '%')
|
||||
{
|
||||
whisperPutc('%');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*fp == '-')
|
||||
{
|
||||
fp++; // Pad right not yet implemented.
|
||||
}
|
||||
|
||||
while (*fp == '0')
|
||||
{
|
||||
fp++; // Pad zero not yet implented.
|
||||
}
|
||||
|
||||
if (*fp == '*')
|
||||
{
|
||||
int width = va_arg(ap, int);
|
||||
fp++; // Width not yet implemented.
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*fp >= '0' && *fp <= '9')
|
||||
++fp; // Width not yet implemented.
|
||||
}
|
||||
|
||||
switch (*fp)
|
||||
{
|
||||
case 'd':
|
||||
count += whisperPrintDecimal(va_arg(ap, int));
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
count += whisperPrintDecimal((unsigned) va_arg(ap, unsigned));
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
case 'X':
|
||||
count += whisperPrintInt(va_arg(ap, int), 16);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
count += whisperPrintInt(va_arg(ap, int), 8);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
whisperPutc(va_arg(ap, int));
|
||||
++count;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
count += whisperPuts(va_arg(ap, char*));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
whisperPrintf(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
int code = whisperPrintfImpl(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
printf(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
int code = whisperPrintfImpl(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
void* memset(void* s, int c, size_t n)
|
||||
{
|
||||
asm("mv t0, a0");
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
OFILES = crt0.o printf.o cmark.o
|
|
@ -0,0 +1 @@
|
|||
cmark.mki
|
|
@ -7,10 +7,12 @@ MEMORY {
|
|||
ICCM : ORIGIN = 0xee000000, LENGTH = 0x80000
|
||||
DCCM : ORIGIN = 0xf0040000, LENGTH = 0x10000
|
||||
CTL : ORIGIN = 0xfffffff0, LENGTH = 16
|
||||
IO : ORIGIN = 0xd0580000, LENGTH = 0x1000
|
||||
}
|
||||
SECTIONS {
|
||||
.text_init : {*(.text_init)} > EXTCODE
|
||||
.text.init : {*(.text.init)} > EXTCODE
|
||||
init_end = .;
|
||||
.data.io : { *(.data.io) } > IO
|
||||
.text : { *(.text) *(.text.startup)} > ICCM
|
||||
text_end = .;
|
||||
.data : { *(.*data) *(.rodata*) *(.sbss) STACK = ALIGN(16) + 0x1000;} > DCCM
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
cmark.mki
|
|
@ -0,0 +1,48 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright 2020 Western Digital Corporation or its affiliates.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
// startup code to support HLL programs
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
.section .text.init
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
// enable caching, except region 0xd
|
||||
li t0, 0x59555555
|
||||
csrw 0x7c0, t0
|
||||
|
||||
la sp, STACK
|
||||
|
||||
call main
|
||||
|
||||
|
||||
.global _finish
|
||||
_finish:
|
||||
la t0, tohost
|
||||
li t1, 0xff
|
||||
sb t1, 0(t0) // DemoTB test termination
|
||||
li t1, 1
|
||||
sw t1, 0(t0) // Whisper test termination
|
||||
beq x0, x0, _finish
|
||||
.rept 10
|
||||
nop
|
||||
.endr
|
||||
|
||||
.section .data.io
|
||||
.global tohost
|
||||
tohost: .word 0
|
||||
|
|
@ -5,9 +5,10 @@ ENTRY(_start)
|
|||
SECTIONS {
|
||||
.text : { *(.text*) }
|
||||
_end = .;
|
||||
. = 0xd0580000;
|
||||
.data.io : { *(.data.io) }
|
||||
. = 0xf0040000;
|
||||
.data : { *(.*data) *(.rodata*) *(.sbss) STACK = ALIGN(16) + 0x1000;}
|
||||
.bss : { *(.bss) }
|
||||
.data : { *(.*data) *(.rodata*) *(.*bss) STACK = ALIGN(16) + 0x1000;}
|
||||
. = 0xfffffff8;
|
||||
.data.ctl : { LONG(0xf0040000); LONG(STACK) }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
OUTPUT_ARCH( "riscv" )
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS {
|
||||
.text : { *(.text*) }
|
||||
. = 0x10000;
|
||||
.data : { *(.*data) *(.rodata*)}
|
||||
. = ALIGN(4);
|
||||
printf_start = .;
|
||||
. = 0xee000000;
|
||||
.data_load : AT(printf_start) {*(.data_text)}
|
||||
printf_end = printf_start + SIZEOF(.data_load);
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// Assembly code for Hello World
|
||||
// Not using only ALU ops for creating the string
|
||||
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#define STDOUT 0xd0580000
|
||||
|
||||
.set mfdc, 0x7f9
|
||||
.extern printf_start, printf_end
|
||||
// Code to execute
|
||||
.section .text
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
|
||||
|
||||
// Enable Caches in MRAC
|
||||
li x1, 0x5f555555
|
||||
csrw 0x7c0, x1
|
||||
li x3, 4 + (1<<13) // unblock DMA be stalled by fences mfdc[13]!!!
|
||||
csrw mfdc, x3 // disable store merging mfdc[2]
|
||||
li x3, RV_ICCM_SADR
|
||||
la x4, printf_start
|
||||
la x5, printf_end
|
||||
|
||||
|
||||
load:
|
||||
lw x6, 0 (x4)
|
||||
sw x6, 0 (x3)
|
||||
addi x4,x4,4
|
||||
addi x3,x3,4
|
||||
bltu x4, x5, load
|
||||
|
||||
fence.i
|
||||
call printf
|
||||
|
||||
// Write 0xff to STDOUT for TB to termiate test.
|
||||
_finish:
|
||||
li x3, STDOUT
|
||||
addi x5, x0, 0xff
|
||||
sb x5, 0(x3)
|
||||
beq x0, x0, _finish
|
||||
.rept 100
|
||||
nop
|
||||
.endr
|
||||
|
||||
.data
|
||||
hw_data:
|
||||
.ascii "----------------------------------------\n"
|
||||
.ascii "Hello World from SweRV EL2 ICCM @WDC !!\n"
|
||||
.ascii "----------------------------------------\n"
|
||||
.byte 0
|
||||
|
||||
.section .data_text, "ax"
|
||||
// Load string from hw_data
|
||||
// and write to stdout address
|
||||
|
||||
printf:
|
||||
li x3, STDOUT
|
||||
la x4, hw_data
|
||||
|
||||
loop:
|
||||
lb x5, 0(x4)
|
||||
sb x5, 0(x3)
|
||||
addi x4, x4, 1
|
||||
bnez x5, loop
|
||||
ret
|
||||
.long 0,1,2,3,4
|
|
@ -0,0 +1,312 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 Western Digital Corporation or its affiliates.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
extern volatile char tohost;
|
||||
|
||||
static int
|
||||
whisperPutc(char c)
|
||||
{
|
||||
tohost = c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
whisperPuts(const char* s)
|
||||
{
|
||||
while (*s)
|
||||
whisperPutc(*s++);
|
||||
whisperPutc('\n');
|
||||
// whisperPutc(0xd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
whisperPrintUnsigned(unsigned value, int width, char pad)
|
||||
{
|
||||
char buffer[20];
|
||||
int charCount = 0;
|
||||
|
||||
do
|
||||
{
|
||||
char c = '0' + (value % 10);
|
||||
value = value / 10;
|
||||
buffer[charCount++] = c;
|
||||
}
|
||||
while (value);
|
||||
|
||||
for (int i = charCount; i < width; ++i)
|
||||
whisperPutc(pad);
|
||||
|
||||
char* p = buffer + charCount - 1;
|
||||
for (int i = 0; i < charCount; ++i)
|
||||
whisperPutc(*p--);
|
||||
|
||||
return charCount;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
whisperPrintDecimal(int value, int width, char pad)
|
||||
{
|
||||
char buffer[20];
|
||||
int charCount = 0;
|
||||
|
||||
unsigned neg = value < 0;
|
||||
if (neg)
|
||||
{
|
||||
value = -value;
|
||||
whisperPutc('-');
|
||||
width--;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
char c = '0' + (value % 10);
|
||||
value = value / 10;
|
||||
buffer[charCount++] = c;
|
||||
}
|
||||
while (value);
|
||||
|
||||
for (int i = charCount; i < width; ++i)
|
||||
whisperPutc(pad);
|
||||
|
||||
char* p = buffer + charCount - 1;
|
||||
for (int i = 0; i < charCount; ++i)
|
||||
whisperPutc(*p--);
|
||||
|
||||
if (neg)
|
||||
charCount++;
|
||||
|
||||
return charCount;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
whisperPrintInt(int value, int width, int pad, int base)
|
||||
{
|
||||
if (base == 10)
|
||||
return whisperPrintDecimal(value, width, pad);
|
||||
|
||||
char buffer[20];
|
||||
int charCount = 0;
|
||||
|
||||
unsigned uu = value;
|
||||
|
||||
if (base == 8)
|
||||
{
|
||||
do
|
||||
{
|
||||
char c = '0' + (uu & 7);
|
||||
buffer[charCount++] = c;
|
||||
uu >>= 3;
|
||||
}
|
||||
while (uu);
|
||||
}
|
||||
else if (base == 16)
|
||||
{
|
||||
do
|
||||
{
|
||||
int digit = uu & 0xf;
|
||||
char c = digit < 10 ? '0' + digit : 'a' + digit - 10;
|
||||
buffer[charCount++] = c;
|
||||
uu >>= 4;
|
||||
}
|
||||
while (uu);
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
char* p = buffer + charCount - 1;
|
||||
for (unsigned i = 0; i < charCount; ++i)
|
||||
whisperPutc(*p--);
|
||||
|
||||
return charCount;
|
||||
}
|
||||
|
||||
/*
|
||||
// Print with g format
|
||||
static int
|
||||
whisperPrintDoubleG(double value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Print with f format
|
||||
static int
|
||||
whisperPrintDoubleF(double value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
int
|
||||
whisperPrintfImpl(const char* format, va_list ap)
|
||||
{
|
||||
int count = 0; // Printed character count
|
||||
|
||||
for (const char* fp = format; *fp; fp++)
|
||||
{
|
||||
char pad = ' ';
|
||||
int width = 0; // Field width
|
||||
|
||||
if (*fp != '%')
|
||||
{
|
||||
whisperPutc(*fp);
|
||||
++count;
|
||||
continue;
|
||||
}
|
||||
|
||||
++fp; // Skip %
|
||||
|
||||
if (*fp == 0)
|
||||
break;
|
||||
|
||||
if (*fp == '%')
|
||||
{
|
||||
whisperPutc('%');
|
||||
continue;
|
||||
}
|
||||
|
||||
while (*fp == '0')
|
||||
{
|
||||
pad = '0';
|
||||
fp++; // Pad zero not yet implented.
|
||||
}
|
||||
|
||||
if (*fp == '-')
|
||||
{
|
||||
fp++; // Pad right not yet implemented.
|
||||
}
|
||||
|
||||
if (*fp == '*')
|
||||
{
|
||||
int outWidth = va_arg(ap, int);
|
||||
fp++; // Width not yet implemented.
|
||||
}
|
||||
else if (*fp >= '0' && *fp <= '9')
|
||||
{ // Width not yet implemented.
|
||||
while (*fp >= '0' && *fp <= '9')
|
||||
width = width * 10 + (*fp++ - '0');
|
||||
}
|
||||
|
||||
switch (*fp)
|
||||
{
|
||||
case 'd':
|
||||
count += whisperPrintDecimal(va_arg(ap, int), width, pad);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
count += whisperPrintUnsigned((unsigned) va_arg(ap, unsigned), width, pad);
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
case 'X':
|
||||
count += whisperPrintInt(va_arg(ap, int), width, pad, 16);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
count += whisperPrintInt(va_arg(ap, int), width, pad, 8);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
whisperPutc(va_arg(ap, int));
|
||||
++count;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
count += whisperPuts(va_arg(ap, char*));
|
||||
break;
|
||||
/*
|
||||
case 'g':
|
||||
count += whisperPrintDoubleG(va_arg(ap, double));
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
count += whisperPrintDoubleF(va_arg(ap, double));
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
whisperPrintf(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
int code = whisperPrintfImpl(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int
|
||||
putchar(int c)
|
||||
{
|
||||
return whisperPutc(c);
|
||||
}
|
||||
|
||||
struct FILE;
|
||||
|
||||
int
|
||||
putc(int c, struct FILE* f)
|
||||
{
|
||||
return whisperPutc(c);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
puts(const char* s)
|
||||
{
|
||||
return whisperPuts(s);
|
||||
}
|
||||
|
||||
int
|
||||
printf(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
int code = whisperPrintfImpl(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
// function to read cpu mcycle csr for performance measurements
|
||||
// simplified version
|
||||
uint64_t get_mcycle(){
|
||||
unsigned int mcyclel;
|
||||
unsigned int mcycleh0 = 0, mcycleh1=1;
|
||||
uint64_t cycles;
|
||||
|
||||
while(mcycleh0 != mcycleh1) {
|
||||
asm volatile ("csrr %0,mcycleh" : "=r" (mcycleh0) );
|
||||
asm volatile ("csrr %0,mcycle" : "=r" (mcyclel) );
|
||||
asm volatile ("csrr %0,mcycleh" : "=r" (mcycleh1) );
|
||||
}
|
||||
cycles = mcycleh1;
|
||||
return (cycles << 32) | mcyclel;
|
||||
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
|
||||
// connects LSI master to external AXI slave and DMA slave
|
||||
module axi_lsu_dma_bridge
|
||||
#(
|
||||
parameter M_ID_WIDTH = 8,
|
||||
parameter S0_ID_WIDTH = 8
|
||||
)
|
||||
(
|
||||
input clk,
|
||||
input reset_l,
|
||||
|
||||
// master read bus
|
||||
input m_arvalid,
|
||||
input [M_ID_WIDTH-1:0] m_arid,
|
||||
input[31:0] m_araddr,
|
||||
output m_arready,
|
||||
|
||||
output m_rvalid,
|
||||
input m_rready,
|
||||
output [63:0] m_rdata,
|
||||
output [M_ID_WIDTH-1:0] m_rid,
|
||||
output [1:0] m_rresp,
|
||||
output m_rlast,
|
||||
|
||||
// master write bus
|
||||
input m_awvalid,
|
||||
input [M_ID_WIDTH-1:0] m_awid,
|
||||
input[31:0] m_awaddr,
|
||||
output m_awready,
|
||||
|
||||
input m_wvalid,
|
||||
output m_wready,
|
||||
|
||||
output[1:0] m_bresp,
|
||||
output m_bvalid,
|
||||
output[M_ID_WIDTH-1:0] m_bid,
|
||||
input m_bready,
|
||||
|
||||
// slave 0 if general ext memory
|
||||
output s0_arvalid,
|
||||
input s0_arready,
|
||||
|
||||
input s0_rvalid,
|
||||
input[S0_ID_WIDTH-1:0] s0_rid,
|
||||
input[1:0] s0_rresp,
|
||||
input[63:0] s0_rdata,
|
||||
input s0_rlast,
|
||||
output s0_rready,
|
||||
|
||||
output s0_awvalid,
|
||||
input s0_awready,
|
||||
|
||||
output s0_wvalid,
|
||||
input s0_wready,
|
||||
|
||||
input[1:0] s0_bresp,
|
||||
input s0_bvalid,
|
||||
input[S0_ID_WIDTH-1:0] s0_bid,
|
||||
output s0_bready,
|
||||
|
||||
// slave 1 if DMA port
|
||||
output s1_arvalid,
|
||||
input s1_arready,
|
||||
|
||||
input s1_rvalid,
|
||||
input[1:0] s1_rresp,
|
||||
input[63:0] s1_rdata,
|
||||
input s1_rlast,
|
||||
output s1_rready,
|
||||
|
||||
output s1_awvalid,
|
||||
input s1_awready,
|
||||
|
||||
output s1_wvalid,
|
||||
input s1_wready,
|
||||
|
||||
input[1:0] s1_bresp,
|
||||
input s1_bvalid,
|
||||
output s1_bready
|
||||
);
|
||||
|
||||
parameter ICCM_BASE = `RV_ICCM_BITS; // in LSBs
|
||||
localparam IDFIFOSZ = $clog2(`RV_DMA_BUF_DEPTH);
|
||||
bit[31:0] iccm_real_base_addr = `RV_ICCM_SADR ;
|
||||
|
||||
wire ar_slave_select;
|
||||
wire aw_slave_select;
|
||||
wire w_slave_select;
|
||||
|
||||
wire rresp_select;
|
||||
wire bresp_select;
|
||||
wire ar_iccm_select;
|
||||
wire aw_iccm_select;
|
||||
|
||||
reg [1:0] wsel_iptr, wsel_optr;
|
||||
reg [2:0] wsel_count;
|
||||
reg [3:0] wsel;
|
||||
|
||||
|
||||
reg [M_ID_WIDTH-1:0] arid [1<<IDFIFOSZ];
|
||||
reg [M_ID_WIDTH-1:0] awid [1<<IDFIFOSZ];
|
||||
reg [IDFIFOSZ-1:0] arid_cnt;
|
||||
reg [IDFIFOSZ-1:0] awid_cnt;
|
||||
reg [IDFIFOSZ-1:0] rid_cnt;
|
||||
reg [IDFIFOSZ-1:0] bid_cnt;
|
||||
|
||||
|
||||
// 1 select slave 1; 0 - slave 0
|
||||
assign ar_slave_select = ar_iccm_select;
|
||||
assign aw_slave_select = aw_iccm_select;
|
||||
|
||||
assign ar_iccm_select = m_araddr[31:ICCM_BASE] == iccm_real_base_addr[31:ICCM_BASE];
|
||||
assign aw_iccm_select = m_awaddr[31:ICCM_BASE] == iccm_real_base_addr[31:ICCM_BASE];
|
||||
|
||||
assign s0_arvalid = m_arvalid & ~ar_slave_select;
|
||||
assign s1_arvalid = m_arvalid & ar_slave_select;
|
||||
assign m_arready = ar_slave_select ? s1_arready : s0_arready;
|
||||
|
||||
|
||||
assign s0_awvalid = m_awvalid & ~aw_slave_select;
|
||||
assign s1_awvalid = m_awvalid & aw_slave_select;
|
||||
assign m_awready = aw_slave_select ? s1_awready : s0_awready;
|
||||
|
||||
|
||||
assign s0_wvalid = m_wvalid & ~w_slave_select;
|
||||
assign s1_wvalid = m_wvalid & w_slave_select;
|
||||
assign m_wready = w_slave_select ? s1_wready : s0_wready;
|
||||
assign w_slave_select = (wsel_count == 0 || wsel_count[2]) ? aw_slave_select : wsel[wsel_optr];
|
||||
|
||||
assign m_rvalid = s0_rvalid | s1_rvalid;
|
||||
assign s0_rready = m_rready & ~rresp_select;
|
||||
assign s1_rready = m_rready & rresp_select;
|
||||
assign m_rdata = rresp_select ? s1_rdata : s0_rdata;
|
||||
assign m_rresp = rresp_select ? s1_rresp : s0_rresp;
|
||||
assign m_rid = rresp_select ? arid[rid_cnt] : s0_rid;
|
||||
assign m_rlast = rresp_select ? s1_rlast : s0_rlast;
|
||||
|
||||
assign rresp_select = s1_rvalid & ~s0_rvalid;
|
||||
|
||||
assign m_bvalid = s0_bvalid | s1_bvalid;
|
||||
assign s0_bready = m_bready & ~bresp_select;
|
||||
assign s1_bready = m_bready & bresp_select;
|
||||
assign m_bid = bresp_select ? awid[bid_cnt] : s0_bid;
|
||||
assign m_bresp = bresp_select ? s1_bresp : s0_bresp;
|
||||
|
||||
|
||||
assign bresp_select = s1_bvalid & ~s0_bvalid;
|
||||
|
||||
|
||||
// W-channel select fifo
|
||||
always @ (posedge clk or negedge reset_l)
|
||||
if(!reset_l) begin
|
||||
wsel_count <= '0;
|
||||
wsel_iptr <= '0;
|
||||
wsel_optr <= '0;
|
||||
end
|
||||
else begin
|
||||
if(m_awvalid & m_awready) begin
|
||||
wsel[wsel_iptr] <= aw_slave_select;
|
||||
if(!(m_wready & m_wvalid )) wsel_count <= wsel_count + 1;
|
||||
wsel_iptr <= wsel_iptr + 1;
|
||||
end
|
||||
if(m_wvalid & m_wready) begin
|
||||
if(!(m_awready & m_awvalid ) ) wsel_count <= wsel_count - 1;
|
||||
wsel_optr <= wsel_optr + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// id replacement for narrow ID slave
|
||||
always @ (posedge clk or negedge reset_l)
|
||||
if(!reset_l) begin
|
||||
arid_cnt <= '0;
|
||||
rid_cnt <= '0;
|
||||
end
|
||||
else begin
|
||||
if(ar_slave_select & m_arready & m_arvalid) begin
|
||||
arid[arid_cnt] <= m_arid;
|
||||
arid_cnt <= arid_cnt + 1;
|
||||
end
|
||||
if(rresp_select & m_rready & m_rvalid) begin
|
||||
rid_cnt <= rid_cnt + 1;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
always @ (posedge clk or negedge reset_l)
|
||||
if(!reset_l) begin
|
||||
awid_cnt <= '0;
|
||||
bid_cnt <= '0;
|
||||
end
|
||||
else begin
|
||||
if(aw_slave_select & m_awready & m_awvalid) begin
|
||||
awid[awid_cnt] <= m_awid;
|
||||
awid_cnt <= awid_cnt + 1;
|
||||
end
|
||||
if(bresp_select & m_bready & m_bvalid) begin
|
||||
bid_cnt <= bid_cnt + 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,395 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// Run time disassembler functions
|
||||
// supports RISCV extentions I, C, M, A
|
||||
`ifndef RV_NUM_THREADS
|
||||
`define RV_NUM_THREADS 1
|
||||
`endif
|
||||
|
||||
bit[31:0] [31:0] gpr[`RV_NUM_THREADS];
|
||||
|
||||
// main DASM function
|
||||
function string dasm(input[31:0] opcode, input[31:0] pc, input[4:0] regn, input[31:0] regv, input tid=0);
|
||||
dasm = (opcode[1:0] == 2'b11) ? dasm32(opcode, pc, tid) : dasm16(opcode, pc, tid);
|
||||
if(regn) gpr[tid][regn] = regv;
|
||||
endfunction
|
||||
|
||||
|
||||
///////////////// 16 bits instructions ///////////////////////
|
||||
|
||||
function string dasm16( input[31:0] opcode, input[31:0] pc, input tid=0);
|
||||
case(opcode[1:0])
|
||||
0: return dasm16_0(opcode, tid);
|
||||
1: return dasm16_1(opcode, pc);
|
||||
2: return dasm16_2(opcode);
|
||||
endcase
|
||||
return $sformatf(".short 0x%h", opcode[15:0]);
|
||||
endfunction
|
||||
|
||||
function string dasm16_0( input[31:0] opcode, tid);
|
||||
case(opcode[15:13])
|
||||
3'b000: return dasm16_ciw(opcode);
|
||||
3'b001: return {"c.fld ", dasm16_cl(opcode, tid)};
|
||||
3'b010: return {"c.lw ", dasm16_cl(opcode, tid)};
|
||||
3'b011: return {"c.flw ", dasm16_cl(opcode, tid)};
|
||||
3'b101: return {"c.fsd ", dasm16_cl(opcode, tid)};
|
||||
3'b110: return {"c.sw ", dasm16_cl(opcode, tid)};
|
||||
3'b111: return {"c.fsw ", dasm16_cl(opcode, tid)};
|
||||
endcase
|
||||
return $sformatf(".short 0x%h", opcode[15:0]);
|
||||
endfunction
|
||||
|
||||
function string dasm16_ciw( input[31:0] opcode);
|
||||
int imm;
|
||||
imm=0;
|
||||
if(opcode[15:0] == 0) return ".short 0";
|
||||
{imm[5:4],imm[9:6],imm[2],imm[3]} = opcode[12:5];
|
||||
return $sformatf("c.addi4spn %s,0x%0h", abi_reg[opcode[4:2]+8], imm);
|
||||
endfunction
|
||||
|
||||
function string dasm16_cl( input[31:0] opcode, input tid=0);
|
||||
int imm;
|
||||
imm=0;
|
||||
imm[5:3] = opcode[12:10];
|
||||
imm[7:6] = opcode[6:5];
|
||||
|
||||
return $sformatf(" %s,%0d(%s) [%h]", abi_reg[opcode[4:2]+8], imm, abi_reg[opcode[9:7]+8], gpr[tid][opcode[9:7]+8]+imm);
|
||||
endfunction
|
||||
|
||||
function string dasm16_1( input[31:0] opcode, input[31:0] pc);
|
||||
case(opcode[15:13])
|
||||
3'b000: return opcode[11:7]==0 ? "c.nop" : {"c.addi ",dasm16_ci(opcode)};
|
||||
3'b001: return {"c.jal ", dasm16_cj(opcode, pc)};
|
||||
3'b010: return {"c.li ", dasm16_ci(opcode)};
|
||||
3'b011: return dasm16_1_3(opcode);
|
||||
3'b100: return dasm16_cr(opcode);
|
||||
3'b101: return {"c.j ", dasm16_cj(opcode, pc)};
|
||||
3'b110: return {"c.beqz ", dasm16_cb(opcode, pc)};
|
||||
3'b111: return {"c.bnez ", dasm16_cb(opcode, pc)};
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
function string dasm16_ci( input[31:0] opcode);
|
||||
int imm;
|
||||
imm=0;
|
||||
imm[4:0] = opcode[6:2];
|
||||
if(opcode[12]) imm [31:5] = '1;
|
||||
return $sformatf("%s,%0d", abi_reg[opcode[11:7]], imm);
|
||||
endfunction
|
||||
|
||||
function string dasm16_cj( input[31:0] opcode, input[31:0] pc);
|
||||
bit[31:0] imm;
|
||||
imm=0;
|
||||
{imm[11],imm[4],imm[9:8],imm[10],imm[6], imm[7],imm[3:1], imm[5]} = opcode[12:2];
|
||||
if(opcode[12]) imm [31:12] = '1;
|
||||
return $sformatf("0x%0h", imm+pc);
|
||||
endfunction
|
||||
|
||||
function string dasm16_cb( input[31:0] opcode, input[31:0] pc);
|
||||
bit[31:0] imm;
|
||||
imm=0;
|
||||
{imm[8],imm[4:3]} = opcode[12:10];
|
||||
{imm[7:6],imm[2:1], imm[5]} = opcode[6:2];
|
||||
if(opcode[12]) imm [31:9] = '1;
|
||||
return $sformatf("%s,0x%0h",abi_reg[opcode[9:7]+8], imm+pc);
|
||||
endfunction
|
||||
|
||||
function string dasm16_cr( input[31:0] opcode);
|
||||
bit[31:0] imm;
|
||||
|
||||
imm = 0;
|
||||
imm[4:0] = opcode[6:2];
|
||||
if(opcode[5]) imm [31:5] = '1;
|
||||
case(opcode[11:10])
|
||||
0: return $sformatf("c.srli %s,%0d", abi_reg[opcode[9:7]+8], imm[5:0]);
|
||||
1: return $sformatf("c.srai %s,%0d", abi_reg[opcode[9:7]+8], imm[5:0]);
|
||||
2: return $sformatf("c.andi %s,0x%0h", abi_reg[opcode[9:7]+8], imm);
|
||||
endcase
|
||||
|
||||
case(opcode[6:5])
|
||||
0: return $sformatf("c.sub %s,%s", abi_reg[opcode[9:7]+8], abi_reg[opcode[4:2]+8]);
|
||||
1: return $sformatf("c.xor %s,%s", abi_reg[opcode[9:7]+8], abi_reg[opcode[4:2]+8]);
|
||||
2: return $sformatf("c.or %s,%s", abi_reg[opcode[9:7]+8], abi_reg[opcode[4:2]+8]);
|
||||
3: return $sformatf("c.and %s,%s", abi_reg[opcode[9:7]+8], abi_reg[opcode[4:2]+8]);
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
function string dasm16_1_3( input[31:0] opcode);
|
||||
int imm;
|
||||
|
||||
imm=0;
|
||||
if(opcode[11:7] == 2) begin
|
||||
{imm[4], imm[6],imm[8:7], imm[5]} = opcode[6:2];
|
||||
if(opcode[12]) imm [31:9] = '1;
|
||||
return $sformatf("c.addi16sp %0d", imm);
|
||||
end
|
||||
else begin
|
||||
imm[16:12] = opcode[6:2];
|
||||
if(opcode[12]) imm [31:17] = '1;
|
||||
return $sformatf("c.lui %s,0x%0h", abi_reg[opcode[11:7]], imm);
|
||||
|
||||
end
|
||||
endfunction
|
||||
|
||||
function string dasm16_2( input[31:0] opcode, input tid=0);
|
||||
case(opcode[15:13])
|
||||
3'b000: return {"c.slli ", dasm16_ci(opcode)};
|
||||
3'b001: return {"c.fldsp ", dasm16_cls(opcode,1,tid)};
|
||||
3'b010: return {"c.lwsp ", dasm16_cls(opcode,0,tid)};
|
||||
3'b011: return {"c.flwsp ", dasm16_cls(opcode,0,tid)};
|
||||
3'b101: return {"c.fsdsp ", dasm16_css(opcode,1,tid)};
|
||||
3'b110: return {"c.swsp ", dasm16_css(opcode,0,tid)};
|
||||
3'b111: return {"c.fswsp ", dasm16_css(opcode,0,tid)};
|
||||
endcase
|
||||
if(opcode[12]) begin
|
||||
if(opcode[12:2] == 0) return "c.ebreak";
|
||||
else if(opcode[6:2] == 0) return $sformatf("c.jalr %s", abi_reg[opcode[11:7]]);
|
||||
else return $sformatf("c.add %s,%s", abi_reg[opcode[11:7]], abi_reg[opcode[6:2]]);
|
||||
end
|
||||
else begin
|
||||
if(opcode[6:2] == 0) return $sformatf("c.jr %s", abi_reg[opcode[11:7]]);
|
||||
else return $sformatf("c.mv %s,%s", abi_reg[opcode[11:7]], abi_reg[opcode[6:2]]);
|
||||
end
|
||||
endfunction
|
||||
|
||||
|
||||
function string dasm16_cls( input[31:0] opcode, input sh1=0, tid=0);
|
||||
bit[31:0] imm;
|
||||
imm=0;
|
||||
if(sh1) {imm[4:3],imm[8:6]} = opcode[6:2];
|
||||
else {imm[4:2],imm[7:6]} = opcode[6:2];
|
||||
imm[5] = opcode[12];
|
||||
return $sformatf("%s,0x%0h [%h]", abi_reg[opcode[11:7]], imm, gpr[tid][2]+imm);
|
||||
endfunction
|
||||
|
||||
function string dasm16_css( input[31:0] opcode, input sh1=0, tid=0);
|
||||
bit[31:0] imm;
|
||||
imm=0;
|
||||
if(sh1) {imm[5:3],imm[8:6]} = opcode[12:7];
|
||||
else {imm[5:2],imm[7:6]} = opcode[12:7];
|
||||
return $sformatf("%s,0x%0h [%h]", abi_reg[opcode[6:2]], imm, gpr[tid][2]+imm);
|
||||
endfunction
|
||||
|
||||
///////////////// 32 bit instructions ///////////////////////
|
||||
|
||||
function string dasm32( input[31:0] opcode, input[31:0] pc, input tid=0);
|
||||
case(opcode[6:0])
|
||||
7'b0110111: return {"lui ", dasm32_u(opcode)};
|
||||
7'b0010111: return {"auipc ", dasm32_u(opcode)};
|
||||
7'b1101111: return {"jal ", dasm32_j(opcode,pc)};
|
||||
7'b1100111: return {"jalr ", dasm32_jr(opcode,pc)};
|
||||
7'b1100011: return dasm32_b(opcode,pc);
|
||||
7'b0000011: return dasm32_l(opcode,tid);
|
||||
7'b0100011: return dasm32_s(opcode,tid);
|
||||
7'b0010011: return dasm32_ai(opcode);
|
||||
7'b0110011: return dasm32_ar(opcode);
|
||||
7'b0001111: return {"fence", dasm32_fence(opcode)};
|
||||
7'b1110011: return dasm32_e(opcode);
|
||||
7'b0101111: return dasm32_a(opcode,tid);
|
||||
|
||||
endcase
|
||||
return $sformatf(".long 0x%h", opcode);
|
||||
endfunction
|
||||
|
||||
function string dasm32_u( input[31:0] opcode);
|
||||
bit[31:0] imm;
|
||||
imm=0;
|
||||
imm[31:12] = opcode[31:12];
|
||||
return $sformatf("%s,0x%0h", abi_reg[opcode[11:7]], imm);
|
||||
endfunction
|
||||
|
||||
function string dasm32_j( input[31:0] opcode, input[31:0] pc);
|
||||
int imm;
|
||||
imm=0;
|
||||
{imm[20], imm[10:1], imm[11], imm[19:12]} = opcode[31:12];
|
||||
if(opcode[31]) imm[31:20] = '1;
|
||||
return $sformatf("%s,0x%0h",abi_reg[opcode[11:7]], imm+pc);
|
||||
endfunction
|
||||
|
||||
function string dasm32_jr( input[31:0] opcode, input[31:0] pc);
|
||||
int imm;
|
||||
imm=0;
|
||||
imm[11:1] = opcode[31:19];
|
||||
if(opcode[31]) imm[31:12] = '1;
|
||||
return $sformatf("%s,%s,0x%0h",abi_reg[opcode[11:7]], abi_reg[opcode[19:15]], imm+pc);
|
||||
endfunction
|
||||
|
||||
function string dasm32_b( input[31:0] opcode, input[31:0] pc);
|
||||
int imm;
|
||||
string mn;
|
||||
imm=0;
|
||||
{imm[12],imm[10:5]} = opcode[31:25];
|
||||
{imm[4:1],imm[11]} = opcode[11:7];
|
||||
if(opcode[31]) imm[31:12] = '1;
|
||||
case(opcode[14:12])
|
||||
0: mn = "beq ";
|
||||
1: mn = "bne ";
|
||||
2,3 : return $sformatf(".long 0x%h", opcode);
|
||||
4: mn = "blt ";
|
||||
5: mn = "bge ";
|
||||
6: mn = "bltu ";
|
||||
7: mn = "bgeu ";
|
||||
endcase
|
||||
return $sformatf("%s%s,%s,0x%0h", mn, abi_reg[opcode[19:15]], abi_reg[opcode[24:20]], imm+pc);
|
||||
endfunction
|
||||
|
||||
function string dasm32_l( input[31:0] opcode, input tid=0);
|
||||
int imm;
|
||||
string mn;
|
||||
imm=0;
|
||||
imm[11:0] = opcode[31:20];
|
||||
if(opcode[31]) imm[31:12] = '1;
|
||||
case(opcode[14:12])
|
||||
0: mn = "lb ";
|
||||
1: mn = "lh ";
|
||||
2: mn = "lw ";
|
||||
4: mn = "lbu ";
|
||||
5: mn = "lhu ";
|
||||
default : return $sformatf(".long 0x%h", opcode);
|
||||
endcase
|
||||
return $sformatf("%s%s,%0d(%s) [%h]", mn, abi_reg[opcode[11:7]], imm, abi_reg[opcode[19:15]], imm+gpr[tid][opcode[19:15]]);
|
||||
endfunction
|
||||
|
||||
function string dasm32_s( input[31:0] opcode, input tid=0);
|
||||
int imm;
|
||||
string mn;
|
||||
imm=0;
|
||||
imm[11:5] = opcode[31:25];
|
||||
imm[4:0] = opcode[11:7];
|
||||
if(opcode[31]) imm[31:12] = '1;
|
||||
case(opcode[14:12])
|
||||
0: mn = "sb ";
|
||||
1: mn = "sh ";
|
||||
2: mn = "sw ";
|
||||
default : return $sformatf(".long 0x%h", opcode);
|
||||
endcase
|
||||
return $sformatf("%s%s,%0d(%s) [%h]", mn, abi_reg[opcode[24:20]], imm, abi_reg[opcode[19:15]], imm+gpr[tid][opcode[19:15]]);
|
||||
endfunction
|
||||
|
||||
function string dasm32_ai( input[31:0] opcode);
|
||||
int imm;
|
||||
string mn;
|
||||
imm=0;
|
||||
imm[11:0] = opcode[31:20];
|
||||
if(opcode[31]) imm[31:12] = '1;
|
||||
case(opcode[14:12])
|
||||
0: mn = "addi ";
|
||||
2: mn = "slti ";
|
||||
3: mn = "sltiu ";
|
||||
4: mn = "xori ";
|
||||
6: mn = "ori ";
|
||||
7: mn = "andi ";
|
||||
default: return dasm32_si(opcode);
|
||||
endcase
|
||||
|
||||
return $sformatf("%s%s,%s,%0d", mn, abi_reg[opcode[11:7]], abi_reg[opcode[19:15]], imm);
|
||||
endfunction
|
||||
|
||||
function string dasm32_si( input[31:0] opcode);
|
||||
int imm;
|
||||
string mn;
|
||||
imm = opcode[24:20];
|
||||
case(opcode[14:12])
|
||||
1: mn = "slli";
|
||||
5: mn = opcode[30] ? "srli": "srai";
|
||||
endcase
|
||||
|
||||
return $sformatf("%s %s,%s,%0d", mn, abi_reg[opcode[11:7]], abi_reg[opcode[19:15]], imm);
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
function string dasm32_ar( input[31:0] opcode);
|
||||
string mn;
|
||||
if(opcode[25])
|
||||
case(opcode[14:12])
|
||||
0: mn = "mul ";
|
||||
1: mn = "mulh ";
|
||||
2: mn = "mulhsu ";
|
||||
3: mn = "mulhu ";
|
||||
4: mn = "div ";
|
||||
5: mn = "divu ";
|
||||
6: mn = "rem ";
|
||||
7: mn = "remu ";
|
||||
endcase
|
||||
else
|
||||
case(opcode[14:12])
|
||||
0: mn = opcode[30]? "sub ":"add ";
|
||||
1: mn = "sll ";
|
||||
2: mn = "slt ";
|
||||
3: mn = "sltu ";
|
||||
4: mn = "xor ";
|
||||
5: mn = opcode[30]? "sra ":"srl ";
|
||||
6: mn = "or ";
|
||||
7: mn = "and ";
|
||||
endcase
|
||||
return $sformatf("%s%s,%s,%s", mn, abi_reg[opcode[11:7]], abi_reg[opcode[19:15]], abi_reg[opcode[24:20]]);
|
||||
endfunction
|
||||
|
||||
function string dasm32_fence( input[31:0] opcode);
|
||||
return opcode[12] ? ".i" : "";
|
||||
endfunction
|
||||
|
||||
function string dasm32_e(input[31:0] opcode);
|
||||
if(opcode[31:7] == 0) return "ecall";
|
||||
else if({opcode[31:21],opcode [19:7]} == 0) return "ebreak";
|
||||
else
|
||||
case(opcode[14:12])
|
||||
1: return {"csrrw ", dasm32_csr(opcode)};
|
||||
2: return {"csrrs ", dasm32_csr(opcode)};
|
||||
3: return {"csrrc ", dasm32_csr(opcode)};
|
||||
5: return {"csrrwi ", dasm32_csr(opcode, 1)};
|
||||
6: return {"csrrsi ", dasm32_csr(opcode, 1)};
|
||||
7: return {"csrrci ", dasm32_csr(opcode, 1)};
|
||||
endcase
|
||||
|
||||
endfunction
|
||||
|
||||
|
||||
function string dasm32_csr(input[31:0] opcode, input im=0);
|
||||
bit[11:0] csr;
|
||||
csr = opcode[31:20];
|
||||
if(im) begin
|
||||
return $sformatf("%s,csr_%0h,0x%h", abi_reg[opcode[11:7]], csr, opcode[19:15]);
|
||||
end
|
||||
else begin
|
||||
return $sformatf("%s,csr_%0h,%s", abi_reg[opcode[11:7]], csr, abi_reg[opcode[19:15]]);
|
||||
end
|
||||
|
||||
endfunction
|
||||
|
||||
//atomics
|
||||
function string dasm32_a(input[31:0] opcode, input tid=0);
|
||||
case(opcode[31:27])
|
||||
'b00010: return $sformatf("lr.w %s,(%s) [%h]", abi_reg[opcode[11:7]], abi_reg[opcode[19:15]], gpr[tid][opcode[19:15]]);
|
||||
'b00011: return $sformatf("sc.w %s,%s,(%s) [%h]", abi_reg[opcode[11:7]], abi_reg[opcode[24:20]], abi_reg[opcode[19:15]], gpr[tid][opcode[19:15]]);
|
||||
'b00001: return {"amoswap.w", dasm32_amo(opcode, tid)};
|
||||
'b00000: return {"amoadd.w", dasm32_amo(opcode, tid)};
|
||||
'b00100: return {"amoxor.w", dasm32_amo(opcode, tid)};
|
||||
'b01100: return {"amoand.w", dasm32_amo(opcode, tid)};
|
||||
'b01000: return {"amoor.w", dasm32_amo(opcode, tid)};
|
||||
'b10000: return {"amomin.w", dasm32_amo(opcode, tid)};
|
||||
'b10100: return {"amomax.w", dasm32_amo(opcode, tid)};
|
||||
'b11000: return {"amominu.w", dasm32_amo(opcode, tid)};
|
||||
'b11100: return {"amomaxu.w", dasm32_amo(opcode, tid)};
|
||||
endcase
|
||||
return $sformatf(".long 0x%h", opcode);
|
||||
endfunction
|
||||
|
||||
function string dasm32_amo( input[31:0] opcode, input tid=0);
|
||||
return $sformatf(" %s,%s,(%s) [%h]", abi_reg[opcode[11:7]], abi_reg[opcode[24:20]], abi_reg[opcode[19:15]], gpr[tid][opcode[19:15]]);
|
||||
endfunction
|
|
@ -1,3 +1,4 @@
|
|||
+incdir+$RV_ROOT/testbench
|
||||
$RV_ROOT/design/swerv_wrapper.sv
|
||||
$RV_ROOT/design/mem.sv
|
||||
$RV_ROOT/design/pic_ctrl.sv
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,312 @@
|
|||
@00000000
|
||||
B7 52 55 59 93 82 52 55 73 90 02 7C 17 11 04 F0
|
||||
13 01 41 61 55 2A 97 02 58 D0 93 82 A2 FE 13 03
|
||||
F0 0F 23 80 62 00 05 43 23 A0 62 00 E3 05 00 FE
|
||||
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
|
||||
01 00 01 00 41 11 4A C0 37 29 00 00 83 27 09 73
|
||||
22 C4 00 41 94 43 03 AF 47 00 83 AE 87 00 03 AE
|
||||
07 01 03 A3 47 01 83 A8 87 01 03 A8 C7 01 90 57
|
||||
D8 57 CC 53 06 C6 26 C2 AA 84 88 53 14 C0 94 40
|
||||
23 22 E4 01 23 24 D4 01 23 28 C4 01 23 2A 64 00
|
||||
23 2C 14 01 23 2E 04 01 08 D0 10 D4 58 D4 4C D0
|
||||
15 47 D8 C4 14 C0 9C 43 B7 26 00 00 83 A5 86 72
|
||||
1C C0 03 26 09 73 58 C4 29 45 31 06 EF 00 A0 6E
|
||||
5C 40 A1 CF 9C 40 B2 40 22 44 03 AF 07 00 83 AE
|
||||
47 00 03 AE 87 00 03 A3 C7 00 83 A8 07 01 03 A8
|
||||
47 01 88 4F CC 4F 90 53 D4 53 98 57 DC 57 23 A0
|
||||
E4 01 23 A2 D4 01 23 A4 C4 01 23 A6 64 00 23 A8
|
||||
14 01 23 AA 04 01 88 CC CC CC 90 D0 D4 D0 98 D4
|
||||
DC D4 02 49 92 44 41 01 82 80 88 44 99 47 93 05
|
||||
84 00 5C C4 99 25 83 27 09 73 48 44 13 06 C4 00
|
||||
9C 43 B2 40 92 44 1C C0 22 44 02 49 A9 45 41 01
|
||||
9D A5 B7 27 00 00 03 C7 C7 72 93 07 10 04 63 03
|
||||
F7 00 82 80 1C 41 37 27 00 00 03 27 87 72 A5 07
|
||||
99 8F 1C C1 82 80 B7 27 00 00 03 A6 07 73 09 C6
|
||||
18 42 18 C1 03 A6 07 73 B7 27 00 00 83 A5 87 72
|
||||
31 06 29 45 0D A5 B7 27 00 00 83 C7 C7 72 37 27
|
||||
00 00 83 26 C7 7F 93 87 F7 FB 93 B7 17 00 D5 8F
|
||||
23 2E F7 7E B7 27 00 00 13 07 20 04 A3 86 E7 72
|
||||
82 80 B7 27 00 00 13 07 10 04 23 86 E7 72 B7 27
|
||||
00 00 23 AE 07 7E 82 80 37 07 04 F0 6D 71 13 07
|
||||
C7 59 B7 07 04 F0 93 87 C7 5B 03 2F 07 00 83 2E
|
||||
47 00 03 2E 87 00 DA D9 93 0F 01 0A 37 2B 00 00
|
||||
83 28 07 01 03 28 47 01 08 4F 83 55 C7 01 03 46
|
||||
E7 01 94 43 03 23 C7 00 23 28 FB 73 D8 43 89 4F
|
||||
23 24 81 10 23 22 91 10 7E D5 84 18 93 0F 80 02
|
||||
37 24 00 00 23 26 11 10 E2 D5 7E D7 7A D9 76 DB
|
||||
72 DD 23 20 21 11 CE DF D2 DD D6 DB DE D7 E6 D3
|
||||
EA D1 EE CF 23 22 94 72 26 D1 1A DF C6 C1 C2 C3
|
||||
83 A8 87 00 03 A8 C7 00 23 16 B1 0C 23 07 C1 0C
|
||||
8C 4B D0 4B 36 D8 3A DA 94 4F 03 D7 C7 01 83 C7
|
||||
E7 01 AA C5 37 0C 00 00 37 05 04 F0 23 16 E1 04
|
||||
23 07 F1 04 13 07 0C 01 A9 47 13 05 45 08 23 2E
|
||||
F7 64 02 D3 46 DC 42 DE AE C0 B2 C2 B6 C4 EF 00
|
||||
90 08 B7 07 04 F0 83 A7 C7 61 63 8A 07 4A 37 05
|
||||
04 F0 13 05 45 0B EF 00 10 07 37 05 04 F0 93 05
|
||||
80 3E 13 05 05 11 EF 00 10 08 EF 00 F0 09 B7 07
|
||||
00 00 23 A6 A7 00 B7 07 04 F0 93 87 C7 5D D8 43
|
||||
83 AD 07 00 37 08 04 F0 3A C2 98 47 85 44 B7 29
|
||||
00 00 3A C4 D8 47 37 2A 00 00 37 24 00 00 3A C6
|
||||
98 4B B7 2B 00 00 B7 2A 00 00 3A C8 D8 4B 93 0C
|
||||
C8 5F 3A CA 98 4F 3A CC 03 D7 C7 01 83 C7 E7 01
|
||||
23 1E E1 00 A3 0F F1 00 13 07 10 04 23 86 E9 72
|
||||
13 07 20 04 A3 06 E4 72 12 47 85 47 8C 08 BA CA
|
||||
22 47 08 18 23 2E FA 7E BA CC 32 47 3E D6 EE C8
|
||||
BA CE 42 47 BA D0 52 47 BA D2 62 47 BA D4 03 57
|
||||
C1 01 23 16 E1 06 03 47 F1 01 23 07 E1 06 4D 21
|
||||
93 37 15 00 30 10 8D 45 09 45 23 2E FA 7E 9D 47
|
||||
3E D4 15 21 A2 56 0D 46 93 05 0C 01 13 85 4B 73
|
||||
39 29 03 25 0B 73 7D 31 03 47 D4 72 93 07 00 04
|
||||
63 F7 E7 36 13 0D 10 04 0D 49 6A 85 93 05 30 04
|
||||
91 21 B2 57 13 07 1D 00 63 00 F5 30 83 47 D4 72
|
||||
13 7D F7 0F E3 F3 A7 FF 93 17 19 00 3E 99 A2 58
|
||||
83 C6 C9 72 13 07 10 04 33 46 19 03 B2 87 63 97
|
||||
E6 00 03 A7 8A 72 93 07 96 00 99 8F 85 04 13 07
|
||||
90 3E E3 9B E4 F2 46 C6 32 C4 3E C2 EF 00 C0 76
|
||||
AA 85 37 05 04 F0 B7 2C 00 00 13 05 05 14 23 A0
|
||||
BC 72 EF 00 40 73 37 05 04 F0 13 05 05 15 EF 00
|
||||
80 70 83 A5 8A 72 37 05 04 F0 13 05 85 18 B7 04
|
||||
04 F0 EF 00 40 71 95 45 13 85 44 1A EF 00 A0 70
|
||||
83 25 CA 7F 37 05 04 F0 13 05 05 1C EF 00 A0 6F
|
||||
85 45 13 85 44 1A EF 00 00 6F 83 C5 C9 72 37 05
|
||||
04 F0 13 05 C5 1D EF 00 00 6E B7 09 04 F0 93 05
|
||||
10 04 13 85 89 1F EF 00 00 6D 83 45 D4 72 37 05
|
||||
04 F0 13 05 45 21 EF 00 00 6C 93 05 20 04 13 85
|
||||
89 1F EF 00 40 6B 93 8B 4B 73 83 A5 0B 02 37 05
|
||||
04 F0 13 05 05 23 EF 00 00 6A 9D 45 13 85 44 1A
|
||||
EF 00 60 69 B7 07 00 00 93 87 07 01 83 A5 C7 65
|
||||
37 05 04 F0 13 05 C5 24 BD 2D 37 05 04 F0 13 05
|
||||
85 26 91 2D 03 27 0B 73 37 05 04 F0 13 05 45 29
|
||||
0C 43 37 0C 04 F0 B7 0B 04 F0 B1 2D 37 05 04 F0
|
||||
13 05 05 2B 0D 2D 03 27 0B 73 13 05 0C 2E B7 0A
|
||||
04 F0 4C 43 37 0A 04 F0 B7 09 04 F0 2D 2D 81 45
|
||||
13 85 44 1A 0D 2D 03 27 0B 73 13 85 CB 2F 37 04
|
||||
00 00 0C 47 0D 25 89 45 13 85 44 1A 29 2D 03 27
|
||||
0B 73 13 85 8A 31 4C 47 39 25 C5 45 13 85 44 1A
|
||||
19 25 83 25 0B 73 13 05 4A 33 37 2B 00 00 C1 05
|
||||
DD 2B 13 85 C9 34 C1 2B 03 27 4B 72 37 05 04 F0
|
||||
13 05 05 38 0C 43 C5 23 37 05 04 F0 13 05 C5 39
|
||||
5D 2B 03 27 4B 72 13 05 0C 2E 4C 43 E9 23 81 45
|
||||
13 85 44 1A C9 23 03 27 4B 72 13 85 CB 2F 0C 47
|
||||
5D 2B 85 45 13 85 44 1A 7D 23 03 27 4B 72 13 85
|
||||
8A 31 4C 47 4D 23 C9 45 13 85 44 1A 69 2B 83 25
|
||||
4B 72 13 05 4A 33 C1 05 79 23 13 85 C9 34 A5 23
|
||||
92 47 37 05 04 F0 13 05 C5 3D BE 85 AD 2B 95 45
|
||||
13 85 44 1A 8D 2B B2 48 22 46 37 05 04 F0 33 09
|
||||
19 41 93 17 39 00 33 89 27 41 B3 05 C9 40 13 05
|
||||
85 3F 91 2B B5 45 13 85 44 1A B1 23 A2 55 37 05
|
||||
04 F0 13 05 45 41 81 23 9D 45 13 85 44 1A 25 2B
|
||||
B2 55 37 05 04 F0 13 05 05 43 35 23 85 45 13 85
|
||||
44 1A 15 23 37 05 04 F0 0C 18 13 05 C5 44 21 2B
|
||||
37 05 04 F0 13 05 45 46 FD 21 37 05 04 F0 8C 08
|
||||
13 05 85 49 09 23 37 05 04 F0 13 05 05 4B E1 29
|
||||
29 45 55 29 B7 07 00 00 03 A7 C7 00 83 A5 0C 72
|
||||
93 07 70 0C 99 8D 23 24 B4 00 63 C4 B7 0A 37 05
|
||||
04 F0 13 05 45 4E C1 29 37 05 04 F0 13 05 45 4F
|
||||
5D 21 37 05 04 F0 13 05 C5 52 71 29 29 45 A5 29
|
||||
83 20 C1 10 03 24 81 10 83 24 41 10 03 29 01 10
|
||||
FE 59 6E 5A DE 5A 4E 5B BE 5B 2E 5C 9E 5C 0E 5D
|
||||
FE 4D 01 45 51 61 82 80 6C 10 01 45 7D 20 03 AE
|
||||
0C 00 03 A3 4C 00 83 A8 8C 00 03 A8 CC 00 03 A5
|
||||
0C 01 83 A5 4C 01 03 A6 8C 01 83 D6 CC 01 03 C7
|
||||
EC 01 83 47 D4 72 05 0D F2 C8 9A CA C6 CC C2 CE
|
||||
AA D0 AE D2 B2 D4 23 16 D1 06 23 07 E1 06 23 A4
|
||||
9A 72 13 7D FD 0F 26 89 E3 F1 A7 CB 75 B9 25 49
|
||||
7D B9 37 05 04 F0 13 06 80 3E 13 05 C5 54 25 21
|
||||
37 05 04 F0 13 05 45 57 39 29 83 25 84 00 B7 F7
|
||||
76 48 93 87 07 80 B3 C7 B7 02 13 06 40 06 37 05
|
||||
04 F0 13 05 45 59 33 E6 C7 02 B7 D7 9A 3B 93 87
|
||||
07 A0 B3 C5 B7 02 C5 2E 29 45 75 26 15 BF 37 05
|
||||
04 F0 13 05 05 0E C1 26 89 BE 09 47 63 0A E5 02
|
||||
8D 47 9C C1 85 47 63 09 F5 00 63 FF A7 00 91 47
|
||||
63 1F F5 00 98 C1 82 80 B7 27 00 00 03 A7 87 72
|
||||
93 07 40 06 E3 D9 E7 FE 23 A0 05 00 82 80 82 80
|
||||
85 47 9C C1 82 80 09 05 2E 95 08 C2 82 80 13 07
|
||||
56 00 13 08 80 0C 33 08 07 03 93 17 27 00 0A 06
|
||||
3E 95 14 C1 38 DD 54 C1 B3 07 C8 00 AE 97 94 4B
|
||||
D8 CB 98 CF 13 87 16 00 98 CB 18 41 C2 95 85 67
|
||||
B2 95 BE 95 23 AA E5 FA B7 27 00 00 15 47 23 A4
|
||||
E7 72 82 80 13 75 F5 0F 93 F5 F5 0F 63 04 B5 00
|
||||
01 45 82 80 B7 27 00 00 23 86 A7 72 05 45 82 80
|
||||
03 47 25 00 83 C7 35 00 63 02 F7 02 41 11 06 C6
|
||||
B1 2E 81 47 63 58 A0 00 B7 27 00 00 29 47 23 A4
|
||||
E7 72 85 47 B2 40 3E 85 41 01 82 80 01 A0 79 15
|
||||
13 35 15 00 82 80 03 48 05 00 63 0B 08 28 39 71
|
||||
22 DE 37 04 04 F0 26 DC 4A DA 4E D8 52 D6 AA 86
|
||||
56 D4 5A D2 5E D0 01 45 93 0F 50 02 B7 08 58 D0
|
||||
13 03 00 03 93 09 D0 02 13 09 A0 02 93 04 00 02
|
||||
13 04 04 00 29 4F 93 03 B1 00 A5 42 13 0A D0 02
|
||||
03 C6 16 00 93 87 16 00 63 03 F8 03 23 80 08 01
|
||||
05 05 BE 86 32 88 E3 15 08 FE 72 54 E2 54 52 59
|
||||
C2 59 32 5A A2 5A 12 5B 82 5B 21 61 82 80 75 D6
|
||||
13 8E 26 00 63 00 F6 07 63 1D 66 1E 03 C7 17 00
|
||||
BE 86 85 07 E3 0C 67 FE 89 06 03 C8 17 00 63 05
|
||||
37 03 63 0A 27 03 93 0A 07 FD 13 FE FA 0F 81 4E
|
||||
63 F2 C2 05 13 07 87 FA 13 77 F7 0F E3 E5 E4 FA
|
||||
0A 07 22 97 1C 43 82 87 42 87 03 C8 27 00 B6 87
|
||||
85 06 E3 1A 27 FD 42 87 91 05 03 C8 27 00 85 06
|
||||
81 4E C9 BF 23 80 08 01 03 C8 26 00 F2 86 E3 11
|
||||
08 F6 A5 BF 03 C8 17 00 19 A0 93 0A 07 FD 13 9E
|
||||
2E 00 76 9E 93 06 08 FD 3E 8B 06 0E 85 07 93 F6
|
||||
F6 0F 42 87 B3 8E CA 01 03 C8 17 00 E3 FF D2 FC
|
||||
93 06 2B 00 41 BF 98 41 81 47 91 05 11 A0 B2 87
|
||||
93 7E F7 00 13 8E 7E 05 63 C4 D2 01 13 8E 0E 03
|
||||
13 86 17 00 93 0E C1 00 B2 9E A3 8F CE FF 11 83
|
||||
79 FF 78 00 BA 97 03 C7 07 00 FD 17 23 80 E8 00
|
||||
E3 9B F3 FE 32 95 E3 15 08 EE 01 B7 03 AE 05 00
|
||||
01 47 91 05 B3 7A EE 03 13 0B C1 00 BA 87 05 07
|
||||
B3 0B EB 00 72 8B 93 8A 0A 03 A3 8F 5B FF 33 5E
|
||||
EE 03 E3 E1 62 FF 3A 8E 63 57 D7 01 23 80 C8 00
|
||||
05 0E E3 9D CE FF 70 00 B2 97 03 C6 07 00 FD 17
|
||||
23 80 C8 00 E3 9B 77 FE 3A 95 E3 1B 08 E8 75 B5
|
||||
98 41 91 05 83 47 07 00 99 C7 05 07 23 80 F8 00
|
||||
83 47 07 00 FD FB 23 80 E8 01 05 05 E3 1A 08 E6
|
||||
69 B5 90 41 01 47 91 05 13 7E 76 00 BA 87 93 0E
|
||||
C1 00 05 07 BA 9E 13 0E 0E 03 A3 8F CE FF 0D 82
|
||||
65 F6 70 00 B2 97 03 C6 07 00 FD 17 23 80 C8 00
|
||||
E3 9B 77 FE 3A 95 55 B7 83 AB 05 00 91 05 5E 87
|
||||
63 CA 0B 06 81 47 33 6E E7 03 3E 8B 93 0A C1 00
|
||||
85 07 BE 9A 33 47 E7 03 13 0E 0E 03 A3 8F CA FF
|
||||
7D F3 3E 87 63 D7 D7 01 23 80 C8 00 05 07 E3 1D
|
||||
D7 FF 78 00 5A 97 03 46 07 00 7D 17 23 80 C8 00
|
||||
E3 1B 77 FE 63 C4 0B 02 3E 95 E3 13 08 DE F5 BB
|
||||
83 C7 05 00 05 05 91 05 23 80 F8 00 E3 1A 08 DC
|
||||
ED B3 32 87 F2 86 13 06 00 02 01 BD 93 07 2B 00
|
||||
3E 95 E1 BF 33 07 70 41 23 80 48 01 FD 1E 59 B7
|
||||
01 45 82 80 39 71 13 03 41 02 2E D2 9A 85 06 CE
|
||||
32 D4 36 D6 3A D8 3E DA 42 DC 46 DE 1A C6 A1 33
|
||||
F2 40 21 61 82 80 13 77 F5 0F B7 07 58 D0 23 80
|
||||
E7 00 3A 85 82 80 13 77 F5 0F B7 07 58 D0 23 80
|
||||
E7 00 3A 85 82 80 83 47 05 00 37 07 58 D0 99 C7
|
||||
05 05 23 00 F7 00 83 47 05 00 FD FB A9 47 23 00
|
||||
F7 00 05 45 82 80 39 71 13 03 41 02 2E D2 9A 85
|
||||
06 CE 32 D4 36 D6 3A D8 3E DA 42 DC 46 DE 1A C6
|
||||
DD 31 F2 40 21 61 82 80 F3 25 00 B8 73 25 00 B0
|
||||
F3 27 00 B8 E3 9A F5 FE 82 80 00 00 33 67 B5 00
|
||||
93 03 F0 FF 13 77 37 00 63 10 07 10 B7 87 7F 7F
|
||||
93 87 F7 F7 03 26 05 00 83 A6 05 00 B3 72 F6 00
|
||||
33 63 F6 00 B3 82 F2 00 B3 E2 62 00 63 92 72 10
|
||||
63 16 D6 08 03 26 45 00 83 A6 45 00 B3 72 F6 00
|
||||
33 63 F6 00 B3 82 F2 00 B3 E2 62 00 63 9E 72 0C
|
||||
63 16 D6 06 03 26 85 00 83 A6 85 00 B3 72 F6 00
|
||||
33 63 F6 00 B3 82 F2 00 B3 E2 62 00 63 98 72 0C
|
||||
63 16 D6 04 03 26 C5 00 83 A6 C5 00 B3 72 F6 00
|
||||
33 63 F6 00 B3 82 F2 00 B3 E2 62 00 63 92 72 0C
|
||||
63 16 D6 02 03 26 05 01 83 A6 05 01 B3 72 F6 00
|
||||
33 63 F6 00 B3 82 F2 00 B3 E2 62 00 63 9C 72 0A
|
||||
13 05 45 01 93 85 45 01 E3 0E D6 F4 13 17 06 01
|
||||
93 97 06 01 63 1E F7 00 13 57 06 01 93 D7 06 01
|
||||
33 05 F7 40 93 75 F5 0F 63 90 05 02 67 80 00 00
|
||||
13 57 07 01 93 D7 07 01 33 05 F7 40 93 75 F5 0F
|
||||
63 94 05 00 67 80 00 00 13 77 F7 0F 93 F7 F7 0F
|
||||
33 05 F7 40 67 80 00 00 03 46 05 00 83 C6 05 00
|
||||
13 05 15 00 93 85 15 00 63 14 D6 00 E3 16 06 FE
|
||||
33 05 D6 40 67 80 00 00 13 05 45 00 93 85 45 00
|
||||
E3 1C D6 FC 13 05 00 00 67 80 00 00 13 05 85 00
|
||||
93 85 85 00 E3 12 D6 FC 13 05 00 00 67 80 00 00
|
||||
13 05 C5 00 93 85 C5 00 E3 18 D6 FA 13 05 00 00
|
||||
67 80 00 00 13 05 05 01 93 85 05 01 E3 1E D6 F8
|
||||
13 05 00 00 67 80 00 00
|
||||
@D0580000
|
||||
00 00 00 00
|
||||
@F0040000
|
||||
66 09 00 00 A6 08 00 00 A6 08 00 00 A6 08 00 00
|
||||
A6 08 00 00 A6 08 00 00 A6 08 00 00 A6 08 00 00
|
||||
A6 08 00 00 A6 08 00 00 A6 08 00 00 B0 0A 00 00
|
||||
58 0A 00 00 A6 08 00 00 A6 08 00 00 A6 08 00 00
|
||||
A6 08 00 00 A6 08 00 00 A6 08 00 00 A6 08 00 00
|
||||
A6 08 00 00 A6 08 00 00 A6 08 00 00 22 0A 00 00
|
||||
A6 08 00 00 A6 08 00 00 A6 08 00 00 00 0A 00 00
|
||||
A6 08 00 00 AC 09 00 00 A6 08 00 00 A6 08 00 00
|
||||
66 09 00 00 44 68 72 79 73 74 6F 6E 65 20 42 65
|
||||
6E 63 68 6D 61 72 6B 2C 20 56 65 72 73 69 6F 6E
|
||||
20 32 2E 31 20 28 4C 61 6E 67 75 61 67 65 3A 20
|
||||
43 29 00 00 50 72 6F 67 72 61 6D 20 63 6F 6D 70
|
||||
69 6C 65 64 20 77 69 74 68 20 27 72 65 67 69 73
|
||||
74 65 72 27 20 61 74 74 72 69 62 75 74 65 00 00
|
||||
50 72 6F 67 72 61 6D 20 63 6F 6D 70 69 6C 65 64
|
||||
20 77 69 74 68 6F 75 74 20 27 72 65 67 69 73 74
|
||||
65 72 27 20 61 74 74 72 69 62 75 74 65 00 00 00
|
||||
45 78 65 63 75 74 69 6F 6E 20 73 74 61 72 74 73
|
||||
2C 20 25 64 20 72 75 6E 73 20 74 68 72 6F 75 67
|
||||
68 20 44 68 72 79 73 74 6F 6E 65 0A 00 00 00 00
|
||||
45 6E 64 5F 74 69 6D 65 3D 25 64 0A 00 00 00 00
|
||||
46 69 6E 61 6C 20 76 61 6C 75 65 73 20 6F 66 20
|
||||
74 68 65 20 76 61 72 69 61 62 6C 65 73 20 75 73
|
||||
65 64 20 69 6E 20 74 68 65 20 62 65 6E 63 68 6D
|
||||
61 72 6B 3A 0A 00 00 00 49 6E 74 5F 47 6C 6F 62
|
||||
3A 20 20 20 20 20 20 20 20 20 20 20 20 25 64 0A
|
||||
00 00 00 00 20 20 20 20 20 20 20 20 73 68 6F 75
|
||||
6C 64 20 62 65 3A 20 20 20 25 64 0A 00 00 00 00
|
||||
42 6F 6F 6C 5F 47 6C 6F 62 3A 20 20 20 20 20 20
|
||||
20 20 20 20 20 25 64 0A 00 00 00 00 43 68 5F 31
|
||||
5F 47 6C 6F 62 3A 20 20 20 20 20 20 20 20 20 20
|
||||
20 25 63 0A 00 00 00 00 20 20 20 20 20 20 20 20
|
||||
73 68 6F 75 6C 64 20 62 65 3A 20 20 20 25 63 0A
|
||||
00 00 00 00 43 68 5F 32 5F 47 6C 6F 62 3A 20 20
|
||||
20 20 20 20 20 20 20 20 20 25 63 0A 00 00 00 00
|
||||
41 72 72 5F 31 5F 47 6C 6F 62 5B 38 5D 3A 20 20
|
||||
20 20 20 20 20 25 64 0A 00 00 00 00 41 72 72 5F
|
||||
32 5F 47 6C 6F 62 5B 38 5D 5B 37 5D 3A 20 20 20
|
||||
20 25 64 0A 00 00 00 00 20 20 20 20 20 20 20 20
|
||||
73 68 6F 75 6C 64 20 62 65 3A 20 20 20 4E 75 6D
|
||||
62 65 72 5F 4F 66 5F 52 75 6E 73 20 2B 20 31 30
|
||||
00 00 00 00 50 74 72 5F 47 6C 6F 62 2D 3E 50 74
|
||||
72 5F 43 6F 6D 70 3A 20 20 25 78 0A 00 00 00 00
|
||||
20 20 20 20 20 20 20 20 73 68 6F 75 6C 64 20 62
|
||||
65 3A 20 20 20 28 69 6D 70 6C 65 6D 65 6E 74 61
|
||||
74 69 6F 6E 2D 64 65 70 65 6E 64 65 6E 74 29 00
|
||||
20 20 44 69 73 63 72 3A 20 20 20 20 20 20 20 20
|
||||
20 20 20 20 20 25 64 0A 00 00 00 00 20 20 45 6E
|
||||
75 6D 5F 43 6F 6D 70 3A 20 20 20 20 20 20 20 20
|
||||
20 25 64 0A 00 00 00 00 20 20 49 6E 74 5F 43 6F
|
||||
6D 70 3A 20 20 20 20 20 20 20 20 20 20 25 64 0A
|
||||
00 00 00 00 20 20 53 74 72 5F 43 6F 6D 70 3A 20
|
||||
20 20 20 20 20 20 20 20 20 25 73 00 20 20 20 20
|
||||
20 20 20 20 73 68 6F 75 6C 64 20 62 65 3A 20 20
|
||||
20 44 48 52 59 53 54 4F 4E 45 20 50 52 4F 47 52
|
||||
41 4D 2C 20 53 4F 4D 45 20 53 54 52 49 4E 47 00
|
||||
4E 65 78 74 5F 50 74 72 5F 47 6C 6F 62 2D 3E 50
|
||||
74 72 5F 43 6F 6D 70 3A 25 78 0A 00 20 20 20 20
|
||||
20 20 20 20 73 68 6F 75 6C 64 20 62 65 3A 20 20
|
||||
20 28 69 6D 70 6C 65 6D 65 6E 74 61 74 69 6F 6E
|
||||
2D 64 65 70 65 6E 64 65 6E 74 29 2C 20 73 61 6D
|
||||
65 20 61 73 20 61 62 6F 76 65 00 00 49 6E 74 5F
|
||||
31 5F 4C 6F 63 3A 20 20 20 20 20 20 20 20 20 20
|
||||
20 25 64 0A 00 00 00 00 49 6E 74 5F 32 5F 4C 6F
|
||||
63 3A 20 20 20 20 20 20 20 20 20 20 20 25 64 0A
|
||||
00 00 00 00 49 6E 74 5F 33 5F 4C 6F 63 3A 20 20
|
||||
20 20 20 20 20 20 20 20 20 25 64 0A 00 00 00 00
|
||||
45 6E 75 6D 5F 4C 6F 63 3A 20 20 20 20 20 20 20
|
||||
20 20 20 20 20 25 64 0A 00 00 00 00 53 74 72 5F
|
||||
31 5F 4C 6F 63 3A 20 20 20 20 20 20 20 20 20 20
|
||||
20 25 73 00 20 20 20 20 20 20 20 20 73 68 6F 75
|
||||
6C 64 20 62 65 3A 20 20 20 44 48 52 59 53 54 4F
|
||||
4E 45 20 50 52 4F 47 52 41 4D 2C 20 31 27 53 54
|
||||
20 53 54 52 49 4E 47 00 53 74 72 5F 32 5F 4C 6F
|
||||
63 3A 20 20 20 20 20 20 20 20 20 20 20 25 73 00
|
||||
20 20 20 20 20 20 20 20 73 68 6F 75 6C 64 20 62
|
||||
65 3A 20 20 20 44 48 52 59 53 54 4F 4E 45 20 50
|
||||
52 4F 47 52 41 4D 2C 20 32 27 4E 44 20 53 54 52
|
||||
49 4E 47 00 55 73 65 72 20 74 69 6D 65 20 25 64
|
||||
0A 00 00 00 4D 65 61 73 75 72 65 64 20 74 69 6D
|
||||
65 20 74 6F 6F 20 73 6D 61 6C 6C 20 74 6F 20 6F
|
||||
62 74 61 69 6E 20 6D 65 61 6E 69 6E 67 66 75 6C
|
||||
20 72 65 73 75 6C 74 73 00 00 00 00 50 6C 65 61
|
||||
73 65 20 69 6E 63 72 65 61 73 65 20 6E 75 6D 62
|
||||
65 72 20 6F 66 20 72 75 6E 73 00 00 52 75 6E 20
|
||||
74 69 6D 65 20 3D 20 25 64 20 63 6C 6F 63 6B 73
|
||||
20 66 6F 72 20 25 64 20 44 68 72 79 73 74 6F 6E
|
||||
65 73 0A 00 44 68 72 79 73 74 6F 6E 65 73 20 70
|
||||
65 72 20 53 65 63 6F 6E 64 20 70 65 72 20 4D 48
|
||||
7A 3A 20 00 25 64 2E 25 30 32 64 00 44 48 52 59
|
||||
53 54 4F 4E 45 20 50 52 4F 47 52 41 4D 2C 20 53
|
||||
4F 4D 45 20 53 54 52 49 4E 47 00 00 44 48 52 59
|
||||
53 54 4F 4E 45 20 50 52 4F 47 52 41 4D 2C 20 31
|
||||
27 53 54 20 53 54 52 49 4E 47 00 00 44 48 52 59
|
||||
53 54 4F 4E 45 20 50 52 4F 47 52 41 4D 2C 20 32
|
||||
27 4E 44 20 53 54 52 49 4E 47 00 00 44 48 52 59
|
||||
53 54 4F 4E 45 20 50 52 4F 47 52 41 4D 2C 20 33
|
||||
27 52 44 20 53 54 52 49 4E 47 00 00 00 00 00 00
|
||||
@FFFFFFF8
|
||||
00 00 04 F0 20 16 04 F0
|
|
@ -25,4 +25,4 @@ B7 50 55 5F 93 80 50 55 73 90 00 7C B7 01 58 D0
|
|||
2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D
|
||||
2D 2D 2D 2D 2D 2D 2D 2D 0A 00
|
||||
@FFFFFFF8
|
||||
00 00 04 F0 70 80 04 F0
|
||||
00 00 04 F0 70 10 04 F0
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
@00000000
|
||||
B7 50 55 5F 93 80 50 55 73 90 00 7C 89 61 91 01
|
||||
73 90 91 7F B7 01 00 EE 17 02 01 00 13 02 42 06
|
||||
97 02 01 00 93 82 C2 08 03 23 02 00 23 A0 61 00
|
||||
11 02 91 01 E3 6A 52 FE 0F 10 00 00 97 00 00 EE
|
||||
E7 80 40 FC B7 01 58 D0 93 02 F0 0F 23 80 51 00
|
||||
E3 0A 00 FE 01 00 01 00 01 00 01 00 01 00 01 00
|
||||
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
|
||||
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
|
||||
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
|
||||
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
|
||||
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
|
||||
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
|
||||
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
|
||||
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
|
||||
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
|
||||
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
|
||||
01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00
|
||||
01 00 01 00 01 00 01 00 01 00 01 00
|
||||
@00010000
|
||||
2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D
|
||||
2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D
|
||||
2D 2D 2D 2D 2D 2D 2D 2D 0A 48 65 6C 6C 6F 20 57
|
||||
6F 72 6C 64 20 66 72 6F 6D 20 53 77 65 52 56 20
|
||||
45 4C 32 20 49 43 43 4D 20 20 40 57 44 43 20 21
|
||||
21 0A 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D
|
||||
2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D
|
||||
2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 0A 00
|
||||
@0001007C
|
||||
B7 01 58 D0 17 02 01 12 13 02 C2 FF 83 02 02 00
|
||||
23 80 51 00 05 02 E3 9B 02 FE 82 80 00 00 00 00
|
||||
01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
|
|
@ -9,4 +9,7 @@ SECTIONS
|
|||
_end = .;
|
||||
. = 0x10000;
|
||||
.data : ALIGN(0x800) { *(.*data) *(.rodata*) STACK = ALIGN(16) + 0x8000; }
|
||||
.bss : { *(.bss) }
|
||||
. = 0xd0580000;
|
||||
.data.io : { *(.data.io) }
|
||||
}
|
||||
|
|
|
@ -288,9 +288,33 @@ module tb_top;
|
|||
wire [1:0] dma_axi_rresp;
|
||||
wire dma_axi_rlast;
|
||||
|
||||
`endif
|
||||
wire[63:0] WriteData;
|
||||
wire lmem_axi_arvalid;
|
||||
wire lmem_axi_arready;
|
||||
|
||||
wire lmem_axi_rvalid;
|
||||
wire [`RV_LSU_BUS_TAG-1:0] lmem_axi_rid;
|
||||
wire [1:0] lmem_axi_rresp;
|
||||
wire [63:0] lmem_axi_rdata;
|
||||
wire lmem_axi_rlast;
|
||||
wire lmem_axi_rready;
|
||||
|
||||
wire lmem_axi_awvalid;
|
||||
wire lmem_axi_awready;
|
||||
|
||||
wire lmem_axi_wvalid;
|
||||
wire lmem_axi_wready;
|
||||
|
||||
wire [1:0] lmem_axi_bresp;
|
||||
wire lmem_axi_bvalid;
|
||||
wire [`RV_LSU_BUS_TAG-1:0] lmem_axi_bid;
|
||||
wire lmem_axi_bready;
|
||||
|
||||
|
||||
`endif
|
||||
wire[63:0] WriteData;
|
||||
string abi_reg[32]; // ABI register names
|
||||
|
||||
`define DEC rvtop.swerv.dec
|
||||
|
||||
assign mailbox_write = lmem.mailbox_write;
|
||||
assign WriteData = lmem.WriteData;
|
||||
|
@ -314,7 +338,7 @@ module tb_top;
|
|||
end
|
||||
// End Of test monitor
|
||||
if(mailbox_write && WriteData[7:0] == 8'hff) begin
|
||||
$display("\nFinished : minstret = %0d, mcycle = %0d", rvtop.swerv.dec.tlu.minstretl[31:0],rvtop.swerv.dec.tlu.mcyclel[31:0]);
|
||||
$display("\nFinished : minstret = %0d, mcycle = %0d", `DEC.tlu.minstretl[31:0],`DEC.tlu.mcyclel[31:0]);
|
||||
$display("See \"exec.log\" for execution trace with register updates..\n");
|
||||
$display("TEST_PASSED");
|
||||
$finish;
|
||||
|
@ -328,9 +352,9 @@ module tb_top;
|
|||
|
||||
// trace monitor
|
||||
always @(posedge core_clk) begin
|
||||
wb_valid[1:0] <= '{rvtop.swerv.dec.dec_i1_wen_wb, rvtop.swerv.dec.dec_i0_wen_wb};
|
||||
wb_dest[1:0] <= '{rvtop.swerv.dec.dec_i1_waddr_wb, rvtop.swerv.dec.dec_i0_waddr_wb};
|
||||
wb_data[1:0] <= '{rvtop.swerv.dec.dec_i1_wdata_wb, rvtop.swerv.dec.dec_i0_wdata_wb};
|
||||
wb_valid[1:0] <= '{`DEC.dec_i1_wen_wb, `DEC.dec_i0_wen_wb};
|
||||
wb_dest[1:0] <= '{`DEC.dec_i1_waddr_wb, `DEC.dec_i0_waddr_wb};
|
||||
wb_data[1:0] <= '{`DEC.dec_i1_wdata_wb, `DEC.dec_i0_wdata_wb};
|
||||
if (trace_rv_i_valid_ip !== 0) begin
|
||||
$fwrite(tp,"%b,%h,%h,%0h,%0h,3,%b,%h,%h,%b\n", trace_rv_i_valid_ip, trace_rv_i_address_ip[63:32], trace_rv_i_address_ip[31:0],
|
||||
trace_rv_i_insn_ip[63:32], trace_rv_i_insn_ip[31:0],trace_rv_i_exception_ip,trace_rv_i_ecause_ip,
|
||||
|
@ -340,15 +364,53 @@ module tb_top;
|
|||
for (int i=0; i<2; i++)
|
||||
if (trace_rv_i_valid_ip[i]==1) begin
|
||||
commit_count++;
|
||||
$fwrite (el, "%10d : %6s 0 %h %h %s\n", cycleCnt, $sformatf("#%0d",commit_count),
|
||||
trace_rv_i_address_ip[31+i*32 -:32], trace_rv_i_insn_ip[31+i*32-:32],
|
||||
(wb_dest[i] !=0 && wb_valid[i]) ? $sformatf("r%0d=%h", wb_dest[i], wb_data[i]) : "");
|
||||
$fwrite (el, "%10d : %8s %0d %h %h%13s ; %s\n",cycleCnt, $sformatf("#%0d",commit_count), 0,
|
||||
trace_rv_i_address_ip[31+i*32 -:32], trace_rv_i_insn_ip[31+i*32-:32],
|
||||
(wb_dest[i] !=0 && wb_valid[i]) ? $sformatf("%s=%h", abi_reg[wb_dest[i]], wb_data[i]) : " ",
|
||||
dasm(trace_rv_i_insn_ip[31+i*32 -:32], trace_rv_i_address_ip[31+i*32-:32], wb_dest[i] & {5{wb_valid[i]}}, wb_data[i])
|
||||
);
|
||||
end
|
||||
end
|
||||
if(`DEC.dec_nonblock_load_wen) begin
|
||||
$fwrite (el, "%10d : %10d%22s=%h ; nbL\n", cycleCnt, 0, abi_reg[`DEC.dec_nonblock_load_waddr], `DEC.lsu_nonblock_load_data);
|
||||
tb_top.gpr[0][`DEC.dec_nonblock_load_waddr] = `DEC.lsu_nonblock_load_data;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
initial begin
|
||||
abi_reg[0] = "zero";
|
||||
abi_reg[1] = "ra";
|
||||
abi_reg[2] = "sp";
|
||||
abi_reg[3] = "gp";
|
||||
abi_reg[4] = "tp";
|
||||
abi_reg[5] = "t0";
|
||||
abi_reg[6] = "t1";
|
||||
abi_reg[7] = "t2";
|
||||
abi_reg[8] = "s0";
|
||||
abi_reg[9] = "s1";
|
||||
abi_reg[10] = "a0";
|
||||
abi_reg[11] = "a1";
|
||||
abi_reg[12] = "a2";
|
||||
abi_reg[13] = "a3";
|
||||
abi_reg[14] = "a4";
|
||||
abi_reg[15] = "a5";
|
||||
abi_reg[16] = "a6";
|
||||
abi_reg[17] = "a7";
|
||||
abi_reg[18] = "s2";
|
||||
abi_reg[19] = "s3";
|
||||
abi_reg[20] = "s4";
|
||||
abi_reg[21] = "s5";
|
||||
abi_reg[22] = "s6";
|
||||
abi_reg[23] = "s7";
|
||||
abi_reg[24] = "s8";
|
||||
abi_reg[25] = "s9";
|
||||
abi_reg[26] = "s10";
|
||||
abi_reg[27] = "s11";
|
||||
abi_reg[28] = "t3";
|
||||
abi_reg[29] = "t4";
|
||||
abi_reg[30] = "t5";
|
||||
abi_reg[31] = "t6";
|
||||
// tie offs
|
||||
jtag_id[31:28] = 4'b1;
|
||||
jtag_id[27:12] = '0;
|
||||
|
@ -361,7 +423,8 @@ module tb_top;
|
|||
$readmemh("program.hex", imem.mem);
|
||||
tp = $fopen("trace_port.csv","w");
|
||||
el = $fopen("exec.log","w");
|
||||
$fwrite (el, "//Cycle : #inst 0 pc opcode reg regnum value\n");
|
||||
$fwrite (el, "// Cycle : #inst hart pc opcode reg=value ; mnemonic\n");
|
||||
$fwrite (el, "//---------------------------------------------------------------\n");
|
||||
fd = $fopen("console.log","w");
|
||||
commit_count = 0;
|
||||
preload_dccm();
|
||||
|
@ -595,40 +658,40 @@ swerv_wrapper rvtop (
|
|||
|
||||
//-------------------------- DMA AXI signals--------------------------
|
||||
// AXI Write Channels
|
||||
.dma_axi_awvalid (1'b0),
|
||||
.dma_axi_awvalid (dma_axi_awvalid),
|
||||
.dma_axi_awready (dma_axi_awready),
|
||||
.dma_axi_awid (dma_axi_awid),
|
||||
.dma_axi_awaddr (dma_axi_awaddr),
|
||||
.dma_axi_awsize (dma_axi_awsize),
|
||||
.dma_axi_awprot (dma_axi_awprot),
|
||||
.dma_axi_awlen (dma_axi_awlen),
|
||||
.dma_axi_awburst (dma_axi_awburst),
|
||||
.dma_axi_awid ('0), // ids are not used on DMA since it always responses in order
|
||||
.dma_axi_awaddr (lsu_axi_awaddr),
|
||||
.dma_axi_awsize (lsu_axi_awsize),
|
||||
.dma_axi_awprot ('0),
|
||||
.dma_axi_awlen ('0),
|
||||
.dma_axi_awburst ('0),
|
||||
|
||||
|
||||
.dma_axi_wvalid (1'b0),
|
||||
.dma_axi_wvalid (dma_axi_wvalid),
|
||||
.dma_axi_wready (dma_axi_wready),
|
||||
.dma_axi_wdata (dma_axi_wdata),
|
||||
.dma_axi_wstrb (dma_axi_wstrb),
|
||||
.dma_axi_wlast (dma_axi_wlast),
|
||||
.dma_axi_wdata (lsu_axi_wdata),
|
||||
.dma_axi_wstrb (lsu_axi_wstrb),
|
||||
.dma_axi_wlast (1'b1),
|
||||
|
||||
.dma_axi_bvalid (dma_axi_bvalid),
|
||||
.dma_axi_bready (1'b0),
|
||||
.dma_axi_bready (dma_axi_bready),
|
||||
.dma_axi_bresp (dma_axi_bresp),
|
||||
.dma_axi_bid (dma_axi_bid),
|
||||
.dma_axi_bid (),
|
||||
|
||||
|
||||
.dma_axi_arvalid (1'b0),
|
||||
.dma_axi_arvalid (dma_axi_arvalid),
|
||||
.dma_axi_arready (dma_axi_arready),
|
||||
.dma_axi_arid (dma_axi_arid),
|
||||
.dma_axi_araddr (dma_axi_araddr),
|
||||
.dma_axi_arsize (dma_axi_arsize),
|
||||
.dma_axi_arprot (dma_axi_arprot),
|
||||
.dma_axi_arlen (dma_axi_arlen),
|
||||
.dma_axi_arburst (dma_axi_arburst),
|
||||
.dma_axi_arid ('0),
|
||||
.dma_axi_araddr (lsu_axi_araddr),
|
||||
.dma_axi_arsize (lsu_axi_arsize),
|
||||
.dma_axi_arprot ('0),
|
||||
.dma_axi_arlen ('0),
|
||||
.dma_axi_arburst ('0),
|
||||
|
||||
.dma_axi_rvalid (dma_axi_rvalid),
|
||||
.dma_axi_rready (1'b0),
|
||||
.dma_axi_rid (dma_axi_rid),
|
||||
.dma_axi_rready (dma_axi_rready),
|
||||
.dma_axi_rid (),
|
||||
.dma_axi_rdata (dma_axi_rdata),
|
||||
.dma_axi_rresp (dma_axi_rresp),
|
||||
.dma_axi_rlast (dma_axi_rlast),
|
||||
|
@ -636,10 +699,10 @@ swerv_wrapper rvtop (
|
|||
.timer_int ( 1'b0 ),
|
||||
.extintsrc_req ( '0 ),
|
||||
|
||||
.lsu_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB master interface
|
||||
.ifu_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB master interface
|
||||
.dbg_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB Debug master interface
|
||||
.dma_bus_clk_en ( 1'b1 ),// Clock ratio b/w cpu core clk & AHB slave interface
|
||||
.lsu_bus_clk_en ( 1'b1 ),
|
||||
.ifu_bus_clk_en ( 1'b1 ),
|
||||
.dbg_bus_clk_en ( 1'b1 ),
|
||||
.dma_bus_clk_en ( 1'b1 ),
|
||||
|
||||
.trace_rv_i_insn_ip (trace_rv_i_insn_ip),
|
||||
.trace_rv_i_address_ip (trace_rv_i_address_ip),
|
||||
|
@ -659,23 +722,23 @@ swerv_wrapper rvtop (
|
|||
.mpc_debug_halt_req ( 1'b0),
|
||||
.mpc_debug_run_ack ( mpc_debug_run_ack),
|
||||
.mpc_debug_run_req ( 1'b1),
|
||||
.mpc_reset_run_req ( 1'b1), // Start running after reset
|
||||
.mpc_reset_run_req ( 1'b1),
|
||||
.debug_brkpt_status (debug_brkpt_status),
|
||||
|
||||
.i_cpu_halt_req ( 1'b0 ), // Async halt req to CPU
|
||||
.o_cpu_halt_ack ( o_cpu_halt_ack ), // core response to halt
|
||||
.o_cpu_halt_status ( o_cpu_halt_status ), // 1'b1 indicates core is halted
|
||||
.i_cpu_run_req ( 1'b0 ), // Async restart req to CPU
|
||||
.i_cpu_halt_req ( 1'b0 ),
|
||||
.o_cpu_halt_ack ( o_cpu_halt_ack ),
|
||||
.o_cpu_halt_status ( o_cpu_halt_status ),
|
||||
.i_cpu_run_req ( 1'b0 ),
|
||||
.o_debug_mode_status (o_debug_mode_status),
|
||||
.o_cpu_run_ack ( o_cpu_run_ack ), // Core response to run req
|
||||
.o_cpu_run_ack ( o_cpu_run_ack ),
|
||||
|
||||
.dec_tlu_perfcnt0 (dec_tlu_perfcnt0),
|
||||
.dec_tlu_perfcnt1 (dec_tlu_perfcnt1),
|
||||
.dec_tlu_perfcnt2 (dec_tlu_perfcnt2),
|
||||
.dec_tlu_perfcnt3 (dec_tlu_perfcnt3),
|
||||
|
||||
.scan_mode ( 1'b0 ), // To enable scan mode
|
||||
.mbist_mode ( 1'b0 ) // to enable mbist
|
||||
.scan_mode ( 1'b0 ),
|
||||
.mbist_mode ( 1'b0 )
|
||||
|
||||
);
|
||||
|
||||
|
@ -771,23 +834,23 @@ defparam lmem.TAGW =`RV_LSU_BUS_TAG;
|
|||
axi_slv lmem(
|
||||
.aclk(core_clk),
|
||||
.rst_l(rst_l),
|
||||
.arvalid(lsu_axi_arvalid),
|
||||
.arready(lsu_axi_arready),
|
||||
.arvalid(lmem_axi_arvalid),
|
||||
.arready(lmem_axi_arready),
|
||||
.araddr(lsu_axi_araddr),
|
||||
.arid(lsu_axi_arid),
|
||||
.arlen(lsu_axi_arlen),
|
||||
.arburst(lsu_axi_arburst),
|
||||
.arsize(lsu_axi_arsize),
|
||||
|
||||
.rvalid(lsu_axi_rvalid),
|
||||
.rready(lsu_axi_rready),
|
||||
.rdata(lsu_axi_rdata),
|
||||
.rresp(lsu_axi_rresp),
|
||||
.rid(lsu_axi_rid),
|
||||
.rlast(lsu_axi_rlast),
|
||||
.rvalid(lmem_axi_rvalid),
|
||||
.rready(lmem_axi_rready),
|
||||
.rdata(lmem_axi_rdata),
|
||||
.rresp(lmem_axi_rresp),
|
||||
.rid(lmem_axi_rid),
|
||||
.rlast(lmem_axi_rlast),
|
||||
|
||||
.awvalid(lsu_axi_awvalid),
|
||||
.awready(lsu_axi_awready),
|
||||
.awvalid(lmem_axi_awvalid),
|
||||
.awready(lmem_axi_awready),
|
||||
.awaddr(lsu_axi_awaddr),
|
||||
.awid(lsu_axi_awid),
|
||||
.awlen(lsu_axi_awlen),
|
||||
|
@ -796,14 +859,86 @@ axi_slv lmem(
|
|||
|
||||
.wdata(lsu_axi_wdata),
|
||||
.wstrb(lsu_axi_wstrb),
|
||||
.wvalid(lsu_axi_wvalid),
|
||||
.wready(lsu_axi_wready),
|
||||
.wvalid(lmem_axi_wvalid),
|
||||
.wready(lmem_axi_wready),
|
||||
|
||||
.bvalid(lsu_axi_bvalid),
|
||||
.bready(lsu_axi_bready),
|
||||
.bresp(lsu_axi_bresp),
|
||||
.bid(lsu_axi_bid)
|
||||
.bvalid(lmem_axi_bvalid),
|
||||
.bready(lmem_axi_bready),
|
||||
.bresp(lmem_axi_bresp),
|
||||
.bid(lmem_axi_bid)
|
||||
);
|
||||
|
||||
axi_lsu_dma_bridge # (`RV_LSU_BUS_TAG,`RV_LSU_BUS_TAG ) bridge(
|
||||
.clk(core_clk),
|
||||
.reset_l(rst_l),
|
||||
|
||||
.m_arvalid(lsu_axi_arvalid),
|
||||
.m_arid(lsu_axi_arid),
|
||||
.m_araddr(lsu_axi_araddr),
|
||||
.m_arready(lsu_axi_arready),
|
||||
|
||||
.m_rvalid(lsu_axi_rvalid),
|
||||
.m_rready(lsu_axi_rready),
|
||||
.m_rdata(lsu_axi_rdata),
|
||||
.m_rid(lsu_axi_rid),
|
||||
.m_rresp(lsu_axi_rresp),
|
||||
.m_rlast(lsu_axi_rlast),
|
||||
|
||||
.m_awvalid(lsu_axi_awvalid),
|
||||
.m_awid(lsu_axi_awid),
|
||||
.m_awaddr(lsu_axi_awaddr),
|
||||
.m_awready(lsu_axi_awready),
|
||||
|
||||
.m_wvalid(lsu_axi_wvalid),
|
||||
.m_wready(lsu_axi_wready),
|
||||
|
||||
.m_bresp(lsu_axi_bresp),
|
||||
.m_bvalid(lsu_axi_bvalid),
|
||||
.m_bid(lsu_axi_bid),
|
||||
.m_bready(lsu_axi_bready),
|
||||
|
||||
.s0_arvalid(lmem_axi_arvalid),
|
||||
.s0_arready(lmem_axi_arready),
|
||||
|
||||
.s0_rvalid(lmem_axi_rvalid),
|
||||
.s0_rid(lmem_axi_rid),
|
||||
.s0_rresp(lmem_axi_rresp),
|
||||
.s0_rdata(lmem_axi_rdata),
|
||||
.s0_rlast(lmem_axi_rlast),
|
||||
.s0_rready(lmem_axi_rready),
|
||||
|
||||
.s0_awvalid(lmem_axi_awvalid),
|
||||
.s0_awready(lmem_axi_awready),
|
||||
|
||||
.s0_wvalid(lmem_axi_wvalid),
|
||||
.s0_wready(lmem_axi_wready),
|
||||
.s0_bresp(lmem_axi_bresp),
|
||||
.s0_bvalid(lmem_axi_bvalid),
|
||||
.s0_bid(lmem_axi_bid),
|
||||
.s0_bready(lmem_axi_bready),
|
||||
|
||||
|
||||
.s1_arvalid(dma_axi_arvalid),
|
||||
.s1_arready(dma_axi_arready),
|
||||
|
||||
.s1_rvalid(dma_axi_rvalid),
|
||||
.s1_rresp(dma_axi_rresp),
|
||||
.s1_rdata(dma_axi_rdata),
|
||||
.s1_rlast(dma_axi_rlast),
|
||||
.s1_rready(dma_axi_rready),
|
||||
|
||||
.s1_awvalid(dma_axi_awvalid),
|
||||
.s1_awready(dma_axi_awready),
|
||||
|
||||
.s1_wvalid(dma_axi_wvalid),
|
||||
.s1_wready(dma_axi_wready),
|
||||
|
||||
.s1_bresp(dma_axi_bresp),
|
||||
.s1_bvalid(dma_axi_bvalid),
|
||||
.s1_bready(dma_axi_bready)
|
||||
|
||||
);
|
||||
|
||||
`endif
|
||||
|
||||
task preload_iccm;
|
||||
|
@ -967,4 +1102,14 @@ function int get_iccm_bank(input int addr, output int bank_idx);
|
|||
`endif
|
||||
endfunction
|
||||
|
||||
/* verilator lint_off WIDTH */
|
||||
/* verilator lint_off CASEINCOMPLETE */
|
||||
`include "dasm.svi"
|
||||
/* verilator lint_on CASEINCOMPLETE */
|
||||
/* verilator lint_on WIDTH */
|
||||
|
||||
|
||||
endmodule
|
||||
`ifdef RV_BUILD_AXI4
|
||||
`include "axi_lsu_dma_bridge.sv"
|
||||
`endif
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
export TEST = cmark_dccm
|
||||
export OFILES = crt0.o cmark_dccm.o printf.o
|
||||
export BUILD_DIR = ../snapshots/default
|
||||
|
||||
clean .DEFAULT:
|
||||
$(MAKE) -e -f $(RV_ROOT)/tools/MakeHex $@
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,12 @@
|
|||
OUTPUT_ARCH( "riscv" )
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS {
|
||||
.text : { *(.text*) }
|
||||
_end = .;
|
||||
. = 0xf0040000;
|
||||
.data : { *(.*data) *(.rodata*) *(.sbss) STACK = ALIGN(16) + 0x1000;}
|
||||
.bss : { *(.bss) }
|
||||
. = 0xfffffff8;
|
||||
.data.ctl : { LONG(0xf0040000); LONG(STACK) }
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
extern int STACK;
|
||||
void main();
|
||||
|
||||
|
||||
#define STDOUT 0xd0580000
|
||||
|
||||
__asm (".section .text");
|
||||
__asm (".global _start");
|
||||
__asm ("_start:");
|
||||
|
||||
// Enable Caches in MRAC
|
||||
__asm ("li t0, 0x5f555555");
|
||||
__asm ("csrw 0x7c0, t0");
|
||||
|
||||
// Set stack pointer.
|
||||
__asm ("la sp, STACK");
|
||||
|
||||
__asm ("jal main");
|
||||
|
||||
// Write 0xff to STDOUT for TB to termiate test.
|
||||
__asm (".global _finish");
|
||||
__asm ("_finish:");
|
||||
__asm ("li t0, 0xd0580000");
|
||||
__asm ("addi t1, zero, 0xff");
|
||||
__asm ("sb t1, 0(t0)");
|
||||
__asm ("beq x0, x0, _finish");
|
||||
__asm (".rept 10");
|
||||
__asm ("nop");
|
||||
__asm (".endr");
|
|
@ -0,0 +1,191 @@
|
|||
#include <stdarg.h>
|
||||
|
||||
// This should be in some .h file.
|
||||
#define STDOUT 0xd0580000
|
||||
|
||||
static int
|
||||
whisperPutc(char c)
|
||||
{
|
||||
// __whisper_console_io = c;
|
||||
// __whisper_console_io = c;
|
||||
*(volatile char*)(STDOUT) = c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
whisperPuts(const char* s)
|
||||
{
|
||||
while (*s)
|
||||
whisperPutc(*s++);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
whisperPrintDecimal(int value)
|
||||
{
|
||||
char buffer[20];
|
||||
int charCount = 0;
|
||||
|
||||
unsigned neg = value < 0;
|
||||
if (neg)
|
||||
{
|
||||
value = -value;
|
||||
whisperPutc('-');
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
char c = '0' + (value % 10);
|
||||
value = value / 10;
|
||||
buffer[charCount++] = c;
|
||||
}
|
||||
while (value);
|
||||
|
||||
char* p = buffer + charCount - 1;
|
||||
for (unsigned i = 0; i < charCount; ++i)
|
||||
whisperPutc(*p--);
|
||||
|
||||
if (neg)
|
||||
charCount++;
|
||||
|
||||
return charCount;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
whisperPrintInt(int value, int base)
|
||||
{
|
||||
if (base == 10)
|
||||
return whisperPrintDecimal(value);
|
||||
|
||||
char buffer[20];
|
||||
int charCount = 0;
|
||||
|
||||
unsigned uu = value;
|
||||
|
||||
if (base == 8)
|
||||
{
|
||||
do
|
||||
{
|
||||
char c = '0' + (uu & 7);
|
||||
buffer[charCount++] = c;
|
||||
uu >>= 3;
|
||||
}
|
||||
while (uu);
|
||||
}
|
||||
else if (base == 16)
|
||||
{
|
||||
do
|
||||
{
|
||||
int digit = uu & 0xf;
|
||||
char c = digit < 10 ? '0' + digit : 'a' + digit - 10;
|
||||
buffer[charCount++] = c;
|
||||
uu >>= 4;
|
||||
}
|
||||
while (uu);
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
char* p = buffer + charCount - 1;
|
||||
for (unsigned i = 0; i < charCount; ++i)
|
||||
whisperPutc(*p--);
|
||||
|
||||
return charCount;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
whisperPrintfImpl(const char* format, va_list ap)
|
||||
{
|
||||
int count = 0; // Printed character count
|
||||
|
||||
for (const char* fp = format; *fp; fp++)
|
||||
{
|
||||
if (*fp != '%')
|
||||
{
|
||||
whisperPutc(*fp);
|
||||
++count;
|
||||
continue;
|
||||
}
|
||||
|
||||
++fp; // Skip %
|
||||
|
||||
if (*fp == 0)
|
||||
break;
|
||||
|
||||
if (*fp == '%')
|
||||
{
|
||||
whisperPutc('%');
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*fp == '-')
|
||||
{
|
||||
fp++; // Pad right not yet implemented.
|
||||
}
|
||||
|
||||
while (*fp == '0')
|
||||
{
|
||||
fp++; // Pad zero not yet implented.
|
||||
}
|
||||
|
||||
if (*fp == '*')
|
||||
{
|
||||
int width = va_arg(ap, int);
|
||||
fp++; // Width not yet implemented.
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*fp >= '0' && *fp <= '9')
|
||||
++fp; // Width not yet implemented.
|
||||
}
|
||||
|
||||
switch (*fp)
|
||||
{
|
||||
case 'd':
|
||||
count += whisperPrintDecimal(va_arg(ap, int));
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
count += whisperPrintDecimal((unsigned) va_arg(ap, unsigned));
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
case 'X':
|
||||
count += whisperPrintInt(va_arg(ap, int), 16);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
count += whisperPrintInt(va_arg(ap, int), 8);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
whisperPutc(va_arg(ap, int));
|
||||
++count;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
count += whisperPuts(va_arg(ap, char*));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
whisperPrintf(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
int code = whisperPrintfImpl(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
This is dhrystone, compiled according to the spec:
|
||||
1. Files dhry_1.c and dhry2_.c compiled separately.
|
||||
2. No inlining.
|
||||
to run in demo TB:
|
||||
|
||||
make -f $RV_ROOT/tools/Makefile [<simulator>] TEST=dhry
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../asm/crt0.s
|
|
@ -0,0 +1,437 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
*
|
||||
* "DHRYSTONE" Benchmark Program
|
||||
* -----------------------------
|
||||
*
|
||||
* Version: C, Version 2.1
|
||||
*
|
||||
* File: dhry.h (part 1 of 3)
|
||||
*
|
||||
* Date: May 25, 1988
|
||||
*
|
||||
* Author: Reinhold P. Weicker
|
||||
* Siemens AG, E STE 35
|
||||
* Postfach 3240
|
||||
* 8520 Erlangen
|
||||
* Germany (West)
|
||||
* Phone: [xxx-49]-9131-7-20330
|
||||
* (8-17 Central European Time)
|
||||
* Usenet: ..!mcvax!unido!estevax!weicker
|
||||
*
|
||||
* Original Version (in Ada) published in
|
||||
* "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
|
||||
* pp. 1013 - 1030, together with the statistics
|
||||
* on which the distribution of statements etc. is based.
|
||||
*
|
||||
* In this C version, the following C library functions are used:
|
||||
* - strcpy, strcmp (inside the measurement loop)
|
||||
* - printf, scanf (outside the measurement loop)
|
||||
* In addition, Berkeley UNIX system calls "times ()" or "time ()"
|
||||
* are used for execution time measurement. For measurements
|
||||
* on other systems, these calls have to be changed.
|
||||
*
|
||||
* Collection of Results:
|
||||
* Reinhold Weicker (address see above) and
|
||||
*
|
||||
* Rick Richardson
|
||||
* PC Research. Inc.
|
||||
* 94 Apple Orchard Drive
|
||||
* Tinton Falls, NJ 07724
|
||||
* Phone: (201) 389-8963 (9-17 EST)
|
||||
* Usenet: ...!uunet!pcrat!rick
|
||||
*
|
||||
* Please send results to Rick Richardson and/or Reinhold Weicker.
|
||||
* Complete information should be given on hardware and software used.
|
||||
* Hardware information includes: Machine type, CPU, type and size
|
||||
* of caches; for microprocessors: clock frequency, memory speed
|
||||
* (number of wait states).
|
||||
* Software information includes: Compiler (and runtime library)
|
||||
* manufacturer and version, compilation switches, OS version.
|
||||
* The Operating System version may give an indication about the
|
||||
* compiler; Dhrystone itself performs no OS calls in the measurement loop.
|
||||
*
|
||||
* The complete output generated by the program should be mailed
|
||||
* such that at least some checks for correctness can be made.
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* History: This version C/2.1 has been made for two reasons:
|
||||
*
|
||||
* 1) There is an obvious need for a common C version of
|
||||
* Dhrystone, since C is at present the most popular system
|
||||
* programming language for the class of processors
|
||||
* (microcomputers, minicomputers) where Dhrystone is used most.
|
||||
* There should be, as far as possible, only one C version of
|
||||
* Dhrystone such that results can be compared without
|
||||
* restrictions. In the past, the C versions distributed
|
||||
* by Rick Richardson (Version 1.1) and by Reinhold Weicker
|
||||
* had small (though not significant) differences.
|
||||
*
|
||||
* 2) As far as it is possible without changes to the Dhrystone
|
||||
* statistics, optimizing compilers should be prevented from
|
||||
* removing significant statements.
|
||||
*
|
||||
* This C version has been developed in cooperation with
|
||||
* Rick Richardson (Tinton Falls, NJ), it incorporates many
|
||||
* ideas from the "Version 1.1" distributed previously by
|
||||
* him over the UNIX network Usenet.
|
||||
* I also thank Chaim Benedelac (National Semiconductor),
|
||||
* David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
|
||||
* Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
|
||||
* for their help with comments on earlier versions of the
|
||||
* benchmark.
|
||||
*
|
||||
* Changes: In the initialization part, this version follows mostly
|
||||
* Rick Richardson's version distributed via Usenet, not the
|
||||
* version distributed earlier via floppy disk by Reinhold Weicker.
|
||||
* As a concession to older compilers, names have been made
|
||||
* unique within the first 8 characters.
|
||||
* Inside the measurement loop, this version follows the
|
||||
* version previously distributed by Reinhold Weicker.
|
||||
*
|
||||
* At several places in the benchmark, code has been added,
|
||||
* but within the measurement loop only in branches that
|
||||
* are not executed. The intention is that optimizing compilers
|
||||
* should be prevented from moving code out of the measurement
|
||||
* loop, or from removing code altogether. Since the statements
|
||||
* that are executed within the measurement loop have NOT been
|
||||
* changed, the numbers defining the "Dhrystone distribution"
|
||||
* (distribution of statements, operand types and locality)
|
||||
* still hold. Except for sophisticated optimizing compilers,
|
||||
* execution times for this version should be the same as
|
||||
* for previous versions.
|
||||
*
|
||||
* Since it has proven difficult to subtract the time for the
|
||||
* measurement loop overhead in a correct way, the loop check
|
||||
* has been made a part of the benchmark. This does have
|
||||
* an impact - though a very minor one - on the distribution
|
||||
* statistics which have been updated for this version.
|
||||
*
|
||||
* All changes within the measurement loop are described
|
||||
* and discussed in the companion paper "Rationale for
|
||||
* Dhrystone version 2".
|
||||
*
|
||||
* Because of the self-imposed limitation that the order and
|
||||
* distribution of the executed statements should not be
|
||||
* changed, there are still cases where optimizing compilers
|
||||
* may not generate code for some statements. To a certain
|
||||
* degree, this is unavoidable for small synthetic benchmarks.
|
||||
* Users of the benchmark are advised to check code listings
|
||||
* whether code is generated for all statements of Dhrystone.
|
||||
*
|
||||
* Version 2.1 is identical to version 2.0 distributed via
|
||||
* the UNIX network Usenet in March 1988 except that it corrects
|
||||
* some minor deficiencies that were found by users of version 2.0.
|
||||
* The only change within the measurement loop is that a
|
||||
* non-executed "else" part was added to the "if" statement in
|
||||
* Func_3, and a non-executed "else" part removed from Proc_3.
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Defines: The following "Defines" are possible:
|
||||
* -DREG=register (default: Not defined)
|
||||
* As an approximation to what an average C programmer
|
||||
* might do, the "register" storage class is applied
|
||||
* (if enabled by -DREG=register)
|
||||
* - for local variables, if they are used (dynamically)
|
||||
* five or more times
|
||||
* - for parameters if they are used (dynamically)
|
||||
* six or more times
|
||||
* Note that an optimal "register" strategy is
|
||||
* compiler-dependent, and that "register" declarations
|
||||
* do not necessarily lead to faster execution.
|
||||
* -DNOSTRUCTASSIGN (default: Not defined)
|
||||
* Define if the C compiler does not support
|
||||
* assignment of structures.
|
||||
* -DNOENUMS (default: Not defined)
|
||||
* Define if the C compiler does not support
|
||||
* enumeration types.
|
||||
* -DTIMES (default)
|
||||
* -DTIME
|
||||
* The "times" function of UNIX (returning process times)
|
||||
* or the "time" function (returning wallclock time)
|
||||
* is used for measurement.
|
||||
* For single user machines, "time ()" is adequate. For
|
||||
* multi-user machines where you cannot get single-user
|
||||
* access, use the "times ()" function. If you have
|
||||
* neither, use a stopwatch in the dead of night.
|
||||
* "printf"s are provided marking the points "Start Timer"
|
||||
* and "Stop Timer". DO NOT use the UNIX "time(1)"
|
||||
* command, as this will measure the total time to
|
||||
* run this program, which will (erroneously) include
|
||||
* the time to allocate storage (malloc) and to perform
|
||||
* the initialization.
|
||||
* -DHZ=nnn
|
||||
* In Berkeley UNIX, the function "times" returns process
|
||||
* time in 1/HZ seconds, with HZ = 60 for most systems.
|
||||
* CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
|
||||
* A VALUE.
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Compilation model and measurement (IMPORTANT):
|
||||
*
|
||||
* This C version of Dhrystone consists of three files:
|
||||
* - dhry.h (this file, containing global definitions and comments)
|
||||
* - dhry_1.c (containing the code corresponding to Ada package Pack_1)
|
||||
* - dhry_2.c (containing the code corresponding to Ada package Pack_2)
|
||||
*
|
||||
* The following "ground rules" apply for measurements:
|
||||
* - Separate compilation
|
||||
* - No procedure merging
|
||||
* - Otherwise, compiler optimizations are allowed but should be indicated
|
||||
* - Default results are those without register declarations
|
||||
* See the companion paper "Rationale for Dhrystone Version 2" for a more
|
||||
* detailed discussion of these ground rules.
|
||||
*
|
||||
* For 16-Bit processors (e.g. 80186, 80286), times for all compilation
|
||||
* models ("small", "medium", "large" etc.) should be given if possible,
|
||||
* together with a definition of these models for the compiler system used.
|
||||
*
|
||||
**************************************************************************
|
||||
*
|
||||
* Dhrystone (C version) statistics:
|
||||
*
|
||||
* [Comment from the first distribution, updated for version 2.
|
||||
* Note that because of language differences, the numbers are slightly
|
||||
* different from the Ada version.]
|
||||
*
|
||||
* The following program contains statements of a high level programming
|
||||
* language (here: C) in a distribution considered representative:
|
||||
*
|
||||
* assignments 52 (51.0 %)
|
||||
* control statements 33 (32.4 %)
|
||||
* procedure, function calls 17 (16.7 %)
|
||||
*
|
||||
* 103 statements are dynamically executed. The program is balanced with
|
||||
* respect to the three aspects:
|
||||
*
|
||||
* - statement type
|
||||
* - operand type
|
||||
* - operand locality
|
||||
* operand global, local, parameter, or constant.
|
||||
*
|
||||
* The combination of these three aspects is balanced only approximately.
|
||||
*
|
||||
* 1. Statement Type:
|
||||
* ----------------- number
|
||||
*
|
||||
* V1 = V2 9
|
||||
* (incl. V1 = F(..)
|
||||
* V = Constant 12
|
||||
* Assignment, 7
|
||||
* with array element
|
||||
* Assignment, 6
|
||||
* with record component
|
||||
* --
|
||||
* 34 34
|
||||
*
|
||||
* X = Y +|-|"&&"|"|" Z 5
|
||||
* X = Y +|-|"==" Constant 6
|
||||
* X = X +|- 1 3
|
||||
* X = Y *|/ Z 2
|
||||
* X = Expression, 1
|
||||
* two operators
|
||||
* X = Expression, 1
|
||||
* three operators
|
||||
* --
|
||||
* 18 18
|
||||
*
|
||||
* if .... 14
|
||||
* with "else" 7
|
||||
* without "else" 7
|
||||
* executed 3
|
||||
* not executed 4
|
||||
* for ... 7 | counted every time
|
||||
* while ... 4 | the loop condition
|
||||
* do ... while 1 | is evaluated
|
||||
* switch ... 1
|
||||
* break 1
|
||||
* declaration with 1
|
||||
* initialization
|
||||
* --
|
||||
* 34 34
|
||||
*
|
||||
* P (...) procedure call 11
|
||||
* user procedure 10
|
||||
* library procedure 1
|
||||
* X = F (...)
|
||||
* function call 6
|
||||
* user function 5
|
||||
* library function 1
|
||||
* --
|
||||
* 17 17
|
||||
* ---
|
||||
* 103
|
||||
*
|
||||
* The average number of parameters in procedure or function calls
|
||||
* is 1.82 (not counting the function values aX *
|
||||
*
|
||||
* 2. Operators
|
||||
* ------------
|
||||
* number approximate
|
||||
* percentage
|
||||
*
|
||||
* Arithmetic 32 50.8
|
||||
*
|
||||
* + 21 33.3
|
||||
* - 7 11.1
|
||||
* * 3 4.8
|
||||
* / (int div) 1 1.6
|
||||
*
|
||||
* Comparison 27 42.8
|
||||
*
|
||||
* == 9 14.3
|
||||
* /= 4 6.3
|
||||
* > 1 1.6
|
||||
* < 3 4.8
|
||||
* >= 1 1.6
|
||||
* <= 9 14.3
|
||||
*
|
||||
* Logic 4 6.3
|
||||
*
|
||||
* && (AND-THEN) 1 1.6
|
||||
* | (OR) 1 1.6
|
||||
* ! (NOT) 2 3.2
|
||||
*
|
||||
* -- -----
|
||||
* 63 100.1
|
||||
*
|
||||
*
|
||||
* 3. Operand Type (counted once per operand reference):
|
||||
* ---------------
|
||||
* number approximate
|
||||
* percentage
|
||||
*
|
||||
* Integer 175 72.3 %
|
||||
* Character 45 18.6 %
|
||||
* Pointer 12 5.0 %
|
||||
* String30 6 2.5 %
|
||||
* Array 2 0.8 %
|
||||
* Record 2 0.8 %
|
||||
* --- -------
|
||||
* 242 100.0 %
|
||||
*
|
||||
* When there is an access path leading to the final operand (e.g. a record
|
||||
* component), only the final data type on the access path is counted.
|
||||
*
|
||||
*
|
||||
* 4. Operand Locality:
|
||||
* -------------------
|
||||
* number approximate
|
||||
* percentage
|
||||
*
|
||||
* local variable 114 47.1 %
|
||||
* global variable 22 9.1 %
|
||||
* parameter 45 18.6 %
|
||||
* value 23 9.5 %
|
||||
* reference 22 9.1 %
|
||||
* function result 6 2.5 %
|
||||
* constant 55 22.7 %
|
||||
* --- -------
|
||||
* 242 100.0 %
|
||||
*
|
||||
*
|
||||
* The program does not compute anything meaningful, but it is syntactically
|
||||
* and semantically correct. All variables have a value assigned to them
|
||||
* before they are used as a source operand.
|
||||
*
|
||||
* There has been no explicit effort to account for the effects of a
|
||||
* cache, or to balance the use of long or short displacements for code or
|
||||
* data.
|
||||
*
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/* Compiler and system dependent definitions: */
|
||||
|
||||
#ifndef TIME
|
||||
#undef TIMES
|
||||
#define TIMES
|
||||
#endif
|
||||
/* Use times(2) time function unless */
|
||||
/* explicitly defined otherwise */
|
||||
|
||||
#ifdef MSC_CLOCK
|
||||
#undef HZ
|
||||
#undef TIMES
|
||||
#include <time.h>
|
||||
#define HZ CLK_TCK
|
||||
#endif
|
||||
/* Use Microsoft C hi-res clock */
|
||||
|
||||
#ifdef TIMES
|
||||
#include <sys/types.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
#ifndef HZ
|
||||
#define HZ 100
|
||||
#endif
|
||||
/* for "times" */
|
||||
#endif
|
||||
|
||||
#define Mic_secs_Per_Second 1000000.0
|
||||
/* Berkeley UNIX C returns process times in seconds/HZ */
|
||||
|
||||
#ifdef NOSTRUCTASSIGN
|
||||
#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
|
||||
#else
|
||||
#define structassign(d, s) d = s
|
||||
#endif
|
||||
|
||||
#ifdef NOENUM
|
||||
#define Ident_1 0
|
||||
#define Ident_2 1
|
||||
#define Ident_3 2
|
||||
#define Ident_4 3
|
||||
#define Ident_5 4
|
||||
typedef int Enumeration;
|
||||
#else
|
||||
typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
|
||||
Enumeration;
|
||||
#endif
|
||||
/* for boolean and enumeration types in Ada, Pascal */
|
||||
|
||||
/* General definitions: */
|
||||
|
||||
//#include <stdio.h>
|
||||
/* for strcpy, strcmp */
|
||||
|
||||
#define Null 0
|
||||
/* Value of a Null pointer */
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
typedef int One_Thirty;
|
||||
typedef int One_Fifty;
|
||||
typedef char Capital_Letter;
|
||||
typedef int Boolean;
|
||||
typedef char Str_30 [31];
|
||||
typedef int Arr_1_Dim [50];
|
||||
typedef int Arr_2_Dim [50] [50];
|
||||
|
||||
typedef struct record
|
||||
{
|
||||
struct record *Ptr_Comp;
|
||||
Enumeration Discr;
|
||||
union {
|
||||
struct {
|
||||
Enumeration Enum_Comp;
|
||||
int Int_Comp;
|
||||
char Str_Comp [31];
|
||||
} var_1;
|
||||
struct {
|
||||
Enumeration E_Comp_2;
|
||||
char Str_2_Comp [31];
|
||||
} var_2;
|
||||
struct {
|
||||
char Ch_1_Comp;
|
||||
char Ch_2_Comp;
|
||||
} var_3;
|
||||
} variant;
|
||||
} Rec_Type, *Rec_Pointer;
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../asm/hello_world_dccm.ld
|
|
@ -0,0 +1,2 @@
|
|||
OFILES = crt0.o dhry_1.o dhry_2.o printf.o
|
||||
TEST_CFLAGS = -g -O3
|
|
@ -0,0 +1,452 @@
|
|||
#define SWERV
|
||||
/*
|
||||
****************************************************************************
|
||||
*
|
||||
* "DHRYSTONE" Benchmark Program
|
||||
* -----------------------------
|
||||
*
|
||||
* Version: C, Version 2.1
|
||||
*
|
||||
* File: dhry_1.c (part 2 of 3)
|
||||
*
|
||||
* Date: May 25, 1988
|
||||
*
|
||||
* Author: Reinhold P. Weicker
|
||||
*
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#ifdef SWERV
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
extern uint64_t get_mcycle();
|
||||
#endif
|
||||
|
||||
#include "dhry.h"
|
||||
|
||||
/* Global Variables: */
|
||||
|
||||
Rec_Pointer Ptr_Glob,
|
||||
Next_Ptr_Glob;
|
||||
int Int_Glob;
|
||||
Boolean Bool_Glob;
|
||||
char Ch_1_Glob,
|
||||
Ch_2_Glob;
|
||||
int Arr_1_Glob [50];
|
||||
int Arr_2_Glob [50] [50];
|
||||
|
||||
Enumeration Func_1 ();
|
||||
/* forward declaration necessary since Enumeration may not simply be int */
|
||||
|
||||
#ifndef REG
|
||||
Boolean Reg = false;
|
||||
#define REG
|
||||
/* REG becomes defined as empty */
|
||||
/* i.e. no register variables */
|
||||
#else
|
||||
Boolean Reg = true;
|
||||
#endif
|
||||
|
||||
/* variables for time measurement: */
|
||||
|
||||
#ifdef TIMES
|
||||
struct tms time_info;
|
||||
#define Too_Small_Time (2*HZ)
|
||||
/* Measurements should last at least about 2 seconds */
|
||||
#endif
|
||||
#ifdef TIME
|
||||
extern long time();
|
||||
/* see library function "time" */
|
||||
#define Too_Small_Time 2
|
||||
/* Measurements should last at least 2 seconds */
|
||||
#endif
|
||||
#ifdef MSC_CLOCK
|
||||
extern clock_t clock();
|
||||
#define Too_Small_Time (2*HZ)
|
||||
#endif
|
||||
|
||||
long
|
||||
Begin_Time,
|
||||
End_Time,
|
||||
User_Time;
|
||||
|
||||
float Microseconds,
|
||||
Dhrystones_Per_Second;
|
||||
|
||||
/* end of variables for time measurement */
|
||||
|
||||
|
||||
extern char* strcpy(char*, const char*);
|
||||
|
||||
extern Boolean Func_2 (Str_30, Str_30);
|
||||
extern void Proc_7 (One_Fifty Int_1_Par_Val, One_Fifty Int_2_Par_Val,
|
||||
One_Fifty *Int_Par_Ref);
|
||||
|
||||
extern void Proc_8 (Arr_1_Dim Arr_1_Par_Ref, Arr_2_Dim Arr_2_Par_Ref,
|
||||
int Int_1_Par_Val, int Int_2_Par_Val);
|
||||
|
||||
extern void Proc_6 (Enumeration Enum_Val_Par,
|
||||
Enumeration *Enum_Ref_Par);
|
||||
|
||||
void Proc_5();
|
||||
void Proc_4();
|
||||
|
||||
void Proc_1(Rec_Pointer Ptr_Val_Par);
|
||||
void Proc_2(One_Fifty *Int_Par_Ref);
|
||||
void Proc_3(Rec_Pointer *Ptr_Ref_Par);
|
||||
|
||||
|
||||
int
|
||||
main ()
|
||||
/*****/
|
||||
|
||||
/* main program, corresponds to procedures */
|
||||
/* Main and Proc_0 in the Ada version */
|
||||
{
|
||||
One_Fifty Int_1_Loc;
|
||||
REG One_Fifty Int_2_Loc;
|
||||
One_Fifty Int_3_Loc;
|
||||
REG char Ch_Index;
|
||||
Enumeration Enum_Loc;
|
||||
Str_30 Str_1_Loc;
|
||||
Str_30 Str_2_Loc;
|
||||
REG int Run_Index;
|
||||
REG int Number_Of_Runs;
|
||||
|
||||
/* Initializations */
|
||||
|
||||
Rec_Type rec0;
|
||||
Rec_Type rec1;
|
||||
|
||||
Next_Ptr_Glob = &rec0;
|
||||
Ptr_Glob = &rec1;
|
||||
|
||||
Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
|
||||
Ptr_Glob->Discr = Ident_1;
|
||||
Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
|
||||
Ptr_Glob->variant.var_1.Int_Comp = 40;
|
||||
strcpy (Ptr_Glob->variant.var_1.Str_Comp,
|
||||
"DHRYSTONE PROGRAM, SOME STRING");
|
||||
strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
|
||||
|
||||
Arr_2_Glob [8][7] = 10;
|
||||
/* Was missing in published program. Without this statement, */
|
||||
/* Arr_2_Glob [8][7] would have an undefined value. */
|
||||
/* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
|
||||
/* overflow may occur for this array element. */
|
||||
|
||||
printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
|
||||
if (Reg)
|
||||
{
|
||||
printf ("Program compiled with 'register' attribute\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("Program compiled without 'register' attribute\n");
|
||||
}
|
||||
|
||||
#ifndef SWERV
|
||||
printf ("Please give the number of runs through the benchmark: ");
|
||||
{
|
||||
int n = 1000;
|
||||
scanf ("%d", &n);
|
||||
Number_Of_Runs = n;
|
||||
}
|
||||
printf ("\n");
|
||||
#else
|
||||
// We do not have scanf. Hardwire number of runs.
|
||||
Number_Of_Runs = 1000;
|
||||
#endif
|
||||
|
||||
printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
|
||||
|
||||
/***************/
|
||||
/* Start timer */
|
||||
/***************/
|
||||
|
||||
#ifdef SWERV
|
||||
Begin_Time = get_mcycle();
|
||||
#else
|
||||
|
||||
#ifdef TIMES
|
||||
times (&time_info);
|
||||
Begin_Time = (long) time_info.tms_utime;
|
||||
#endif
|
||||
#ifdef TIME
|
||||
Begin_Time = time ( (long *) 0);
|
||||
#endif
|
||||
#ifdef MSC_CLOCK
|
||||
Begin_Time = clock();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
__asm("__perf_start:");
|
||||
|
||||
for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
|
||||
{
|
||||
__asm("__loop_start:");
|
||||
|
||||
Proc_5();
|
||||
Proc_4();
|
||||
/* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
|
||||
Int_1_Loc = 2;
|
||||
Int_2_Loc = 3;
|
||||
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
|
||||
Enum_Loc = Ident_2;
|
||||
Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
|
||||
/* Bool_Glob == 1 */
|
||||
while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
|
||||
{
|
||||
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
|
||||
/* Int_3_Loc == 7 */
|
||||
Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
|
||||
/* Int_3_Loc == 7 */
|
||||
Int_1_Loc += 1;
|
||||
} /* while */
|
||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
||||
Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
|
||||
/* Int_Glob == 5 */
|
||||
Proc_1 (Ptr_Glob);
|
||||
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
|
||||
/* loop body executed twice */
|
||||
{
|
||||
if (Enum_Loc == Func_1 (Ch_Index, 'C'))
|
||||
/* then, not executed */
|
||||
{
|
||||
Proc_6 (Ident_1, &Enum_Loc);
|
||||
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
|
||||
Int_2_Loc = Run_Index;
|
||||
Int_Glob = Run_Index;
|
||||
}
|
||||
}
|
||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
||||
Int_2_Loc = Int_2_Loc * Int_1_Loc;
|
||||
Int_1_Loc = Int_2_Loc / Int_3_Loc;
|
||||
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
|
||||
/* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
|
||||
Proc_2 (&Int_1_Loc);
|
||||
/* Int_1_Loc == 5 */
|
||||
|
||||
} /* loop "for Run_Index" */
|
||||
|
||||
__asm("__perf_end:");
|
||||
|
||||
/**************/
|
||||
/* Stop timer */
|
||||
/**************/
|
||||
|
||||
#ifdef SWERV
|
||||
End_Time = get_mcycle();
|
||||
printf("End_time=%d\n", (int) End_Time);
|
||||
#else
|
||||
#ifdef TIMES
|
||||
times (&time_info);
|
||||
End_Time = (long) time_info.tms_utime;
|
||||
#endif
|
||||
#ifdef TIME
|
||||
End_Time = time ( (long *) 0);
|
||||
#endif
|
||||
#ifdef MSC_CLOCK
|
||||
End_Time = clock();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
printf ("Final values of the variables used in the benchmark:\n\n");
|
||||
printf ("Int_Glob: %d\n", Int_Glob);
|
||||
printf (" should be: %d\n", 5);
|
||||
printf ("Bool_Glob: %d\n", Bool_Glob);
|
||||
printf (" should be: %d\n", 1);
|
||||
printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
|
||||
printf (" should be: %c\n", 'A');
|
||||
printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
|
||||
printf (" should be: %c\n", 'B');
|
||||
printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
|
||||
printf (" should be: %d\n", 7);
|
||||
printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
|
||||
printf (" should be: Number_Of_Runs + 10\n");
|
||||
printf ("Ptr_Glob->Ptr_Comp: %x\n", (int) Ptr_Glob->Ptr_Comp);
|
||||
printf (" should be: (implementation-dependent)\n");
|
||||
printf (" Discr: %d\n", Ptr_Glob->Discr);
|
||||
printf (" should be: %d\n", 0);
|
||||
printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
|
||||
printf (" should be: %d\n", 2);
|
||||
printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
|
||||
printf (" should be: %d\n", 17);
|
||||
printf (" Str_Comp: %s", Ptr_Glob->variant.var_1.Str_Comp);
|
||||
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
|
||||
printf ("Next_Ptr_Glob->Ptr_Comp:%x\n", (int) Next_Ptr_Glob->Ptr_Comp);
|
||||
printf (" should be: (implementation-dependent), same as above\n");
|
||||
printf (" Discr: %d\n", Next_Ptr_Glob->Discr);
|
||||
printf (" should be: %d\n", 0);
|
||||
printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
|
||||
printf (" should be: %d\n", 1);
|
||||
printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
|
||||
printf (" should be: %d\n", 18);
|
||||
printf (" Str_Comp: %s", Next_Ptr_Glob->variant.var_1.Str_Comp);
|
||||
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
|
||||
printf ("Int_1_Loc: %d\n", Int_1_Loc);
|
||||
printf (" should be: %d\n", 5);
|
||||
printf ("Int_2_Loc: %d\n", Int_2_Loc);
|
||||
printf (" should be: %d\n", 13);
|
||||
printf ("Int_3_Loc: %d\n", Int_3_Loc);
|
||||
printf (" should be: %d\n", 7);
|
||||
printf ("Enum_Loc: %d\n", Enum_Loc);
|
||||
printf (" should be: %d\n", 1);
|
||||
printf ("Str_1_Loc: %s", Str_1_Loc);
|
||||
printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
|
||||
printf ("Str_2_Loc: %s", Str_2_Loc);
|
||||
printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
|
||||
printf ("\n");
|
||||
|
||||
User_Time = End_Time - Begin_Time;
|
||||
|
||||
if (User_Time < Too_Small_Time)
|
||||
{
|
||||
printf ("User time %d\n", User_Time);
|
||||
printf ("Measured time too small to obtain meaningful results\n");
|
||||
printf ("Please increase number of runs\n");
|
||||
printf ("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef SWERV
|
||||
printf ("Run time = %d clocks for %d Dhrystones\n", User_Time, Number_Of_Runs );
|
||||
printf ("Dhrystones per Second per MHz: ");
|
||||
printf ("%d.%02d", 1000000*Number_Of_Runs/User_Time,(100000000*Number_Of_Runs/User_Time) % 100);
|
||||
#else
|
||||
#ifdef TIME
|
||||
Microseconds = (float) User_Time * Mic_secs_Per_Second
|
||||
/ (float) Number_Of_Runs;
|
||||
Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
|
||||
#else
|
||||
Microseconds = (float) User_Time * Mic_secs_Per_Second
|
||||
/ ((float) HZ * ((float) Number_Of_Runs));
|
||||
Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
|
||||
/ (float) User_Time;
|
||||
#endif
|
||||
printf ("Microseconds for one run through Dhrystone: ");
|
||||
printf ("%6.1f \n", Microseconds);
|
||||
printf ("Dhrystones per Second: ");
|
||||
printf ("%6.1f \n", Dhrystones_Per_Second);
|
||||
|
||||
#endif
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Proc_1 (Ptr_Val_Par)
|
||||
/******************/
|
||||
|
||||
REG Rec_Pointer Ptr_Val_Par;
|
||||
/* executed once */
|
||||
{
|
||||
REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
|
||||
/* == Ptr_Glob_Next */
|
||||
/* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
|
||||
/* corresponds to "rename" in Ada, "with" in Pascal */
|
||||
|
||||
structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
|
||||
Ptr_Val_Par->variant.var_1.Int_Comp = 5;
|
||||
Next_Record->variant.var_1.Int_Comp
|
||||
= Ptr_Val_Par->variant.var_1.Int_Comp;
|
||||
Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
|
||||
Proc_3 (&Next_Record->Ptr_Comp);
|
||||
/* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
|
||||
== Ptr_Glob->Ptr_Comp */
|
||||
if (Next_Record->Discr == Ident_1)
|
||||
/* then, executed */
|
||||
{
|
||||
Next_Record->variant.var_1.Int_Comp = 6;
|
||||
Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
|
||||
&Next_Record->variant.var_1.Enum_Comp);
|
||||
Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
|
||||
Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
|
||||
&Next_Record->variant.var_1.Int_Comp);
|
||||
}
|
||||
else /* not executed */
|
||||
structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
|
||||
} /* Proc_1 */
|
||||
|
||||
|
||||
void
|
||||
Proc_2 (Int_Par_Ref)
|
||||
/******************/
|
||||
/* executed once */
|
||||
/* *Int_Par_Ref == 1, becomes 4 */
|
||||
|
||||
One_Fifty *Int_Par_Ref;
|
||||
{
|
||||
One_Fifty Int_Loc;
|
||||
Enumeration Enum_Loc;
|
||||
|
||||
Int_Loc = *Int_Par_Ref + 10;
|
||||
do /* executed once */
|
||||
if (Ch_1_Glob == 'A')
|
||||
/* then, executed */
|
||||
{
|
||||
Int_Loc -= 1;
|
||||
*Int_Par_Ref = Int_Loc - Int_Glob;
|
||||
Enum_Loc = Ident_1;
|
||||
} /* if */
|
||||
while (Enum_Loc != Ident_1); /* true */
|
||||
} /* Proc_2 */
|
||||
|
||||
|
||||
void
|
||||
Proc_3 (Ptr_Ref_Par)
|
||||
/******************/
|
||||
/* executed once */
|
||||
/* Ptr_Ref_Par becomes Ptr_Glob */
|
||||
|
||||
Rec_Pointer *Ptr_Ref_Par;
|
||||
|
||||
{
|
||||
if (Ptr_Glob != Null)
|
||||
/* then, executed */
|
||||
*Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
|
||||
Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
|
||||
} /* Proc_3 */
|
||||
|
||||
|
||||
void
|
||||
Proc_4 () /* without parameters */
|
||||
/*******/
|
||||
/* executed once */
|
||||
{
|
||||
Boolean Bool_Loc;
|
||||
|
||||
Bool_Loc = Ch_1_Glob == 'A';
|
||||
Bool_Glob = Bool_Loc | Bool_Glob;
|
||||
Ch_2_Glob = 'B';
|
||||
} /* Proc_4 */
|
||||
|
||||
|
||||
void
|
||||
Proc_5 () /* without parameters */
|
||||
/*******/
|
||||
/* executed once */
|
||||
{
|
||||
Ch_1_Glob = 'A';
|
||||
Bool_Glob = false;
|
||||
} /* Proc_5 */
|
||||
|
||||
|
||||
/* Procedure for the assignment of structures, */
|
||||
/* if the C compiler doesn't support this feature */
|
||||
#ifdef NOSTRUCTASSIGN
|
||||
memcpy (d, s, l)
|
||||
register char *d;
|
||||
register char *s;
|
||||
register int l;
|
||||
{
|
||||
while (l--) *d++ = *s++;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
****************************************************************************
|
||||
*
|
||||
* "DHRYSTONE" Benchmark Program
|
||||
* -----------------------------
|
||||
*
|
||||
* Version: C, Version 2.1
|
||||
*
|
||||
* File: dhry_2.c (part 3 of 3)
|
||||
*
|
||||
* Date: May 25, 1988
|
||||
*
|
||||
* Author: Reinhold P. Weicker
|
||||
*
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "dhry.h"
|
||||
|
||||
#ifndef REG
|
||||
#define REG
|
||||
/* REG becomes defined as empty */
|
||||
/* i.e. no register variables */
|
||||
#endif
|
||||
|
||||
extern int Int_Glob;
|
||||
extern char Ch_1_Glob;
|
||||
|
||||
#if 0
|
||||
int
|
||||
strcmp(const char* s1, const char* s2)
|
||||
{
|
||||
while (*s1 && *s1 == *s2)
|
||||
{
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
if (*s1 == *s2)
|
||||
return 0;
|
||||
return *s1 > *s2? 1 : -1;
|
||||
}
|
||||
#else
|
||||
extern int strcmp( char* s1, char* s2);
|
||||
#endif
|
||||
|
||||
Boolean Func_3 (Enumeration Enum_Par_Val);
|
||||
|
||||
|
||||
void
|
||||
Proc_6 (Enum_Val_Par, Enum_Ref_Par)
|
||||
/*********************************/
|
||||
/* executed once */
|
||||
/* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
|
||||
|
||||
Enumeration Enum_Val_Par;
|
||||
Enumeration *Enum_Ref_Par;
|
||||
{
|
||||
*Enum_Ref_Par = Enum_Val_Par;
|
||||
if (! Func_3 (Enum_Val_Par))
|
||||
/* then, not executed */
|
||||
*Enum_Ref_Par = Ident_4;
|
||||
switch (Enum_Val_Par)
|
||||
{
|
||||
case Ident_1:
|
||||
*Enum_Ref_Par = Ident_1;
|
||||
break;
|
||||
case Ident_2:
|
||||
if (Int_Glob > 100)
|
||||
/* then */
|
||||
*Enum_Ref_Par = Ident_1;
|
||||
else *Enum_Ref_Par = Ident_4;
|
||||
break;
|
||||
case Ident_3: /* executed */
|
||||
*Enum_Ref_Par = Ident_2;
|
||||
break;
|
||||
case Ident_4: break;
|
||||
case Ident_5:
|
||||
*Enum_Ref_Par = Ident_3;
|
||||
break;
|
||||
} /* switch */
|
||||
} /* Proc_6 */
|
||||
|
||||
|
||||
void
|
||||
Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
|
||||
/**********************************************/
|
||||
/* executed three times */
|
||||
/* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
|
||||
/* Int_Par_Ref becomes 7 */
|
||||
/* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
|
||||
/* Int_Par_Ref becomes 17 */
|
||||
/* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
|
||||
/* Int_Par_Ref becomes 18 */
|
||||
One_Fifty Int_1_Par_Val;
|
||||
One_Fifty Int_2_Par_Val;
|
||||
One_Fifty *Int_Par_Ref;
|
||||
{
|
||||
One_Fifty Int_Loc;
|
||||
|
||||
Int_Loc = Int_1_Par_Val + 2;
|
||||
*Int_Par_Ref = Int_2_Par_Val + Int_Loc;
|
||||
} /* Proc_7 */
|
||||
|
||||
|
||||
void
|
||||
Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
|
||||
/*********************************************************************/
|
||||
/* executed once */
|
||||
/* Int_Par_Val_1 == 3 */
|
||||
/* Int_Par_Val_2 == 7 */
|
||||
Arr_1_Dim Arr_1_Par_Ref;
|
||||
Arr_2_Dim Arr_2_Par_Ref;
|
||||
int Int_1_Par_Val;
|
||||
int Int_2_Par_Val;
|
||||
{
|
||||
REG One_Fifty Int_Index;
|
||||
REG One_Fifty Int_Loc;
|
||||
|
||||
Int_Loc = Int_1_Par_Val + 5;
|
||||
Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
|
||||
Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
|
||||
Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
|
||||
for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
|
||||
Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
|
||||
Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
|
||||
Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
|
||||
Int_Glob = 5;
|
||||
} /* Proc_8 */
|
||||
|
||||
|
||||
Enumeration Func_1 (Ch_1_Par_Val, Ch_2_Par_Val)
|
||||
/*************************************************/
|
||||
/* executed three times */
|
||||
/* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
|
||||
/* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
|
||||
/* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
|
||||
|
||||
Capital_Letter Ch_1_Par_Val;
|
||||
Capital_Letter Ch_2_Par_Val;
|
||||
{
|
||||
Capital_Letter Ch_1_Loc;
|
||||
Capital_Letter Ch_2_Loc;
|
||||
|
||||
Ch_1_Loc = Ch_1_Par_Val;
|
||||
Ch_2_Loc = Ch_1_Loc;
|
||||
if (Ch_2_Loc != Ch_2_Par_Val)
|
||||
/* then, executed */
|
||||
return (Ident_1);
|
||||
else /* not executed */
|
||||
{
|
||||
Ch_1_Glob = Ch_1_Loc;
|
||||
return (Ident_2);
|
||||
}
|
||||
} /* Func_1 */
|
||||
|
||||
|
||||
Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
|
||||
/*************************************************/
|
||||
/* executed once */
|
||||
/* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
|
||||
/* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
|
||||
|
||||
Str_30 Str_1_Par_Ref;
|
||||
Str_30 Str_2_Par_Ref;
|
||||
{
|
||||
REG One_Thirty Int_Loc;
|
||||
Capital_Letter Ch_Loc;
|
||||
|
||||
Int_Loc = 2;
|
||||
while (Int_Loc <= 2) /* loop body executed once */
|
||||
if (Func_1 (Str_1_Par_Ref[Int_Loc],
|
||||
Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
|
||||
/* then, executed */
|
||||
{
|
||||
Ch_Loc = 'A';
|
||||
Int_Loc += 1;
|
||||
} /* if, while */
|
||||
if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
|
||||
/* then, not executed */
|
||||
Int_Loc = 7;
|
||||
if (Ch_Loc == 'R')
|
||||
/* then, not executed */
|
||||
return (true);
|
||||
else /* executed */
|
||||
{
|
||||
if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
|
||||
/* then, not executed */
|
||||
{
|
||||
Int_Loc += 7;
|
||||
Int_Glob = Int_Loc;
|
||||
return (true);
|
||||
}
|
||||
else /* executed */
|
||||
return (false);
|
||||
} /* if Ch_Loc */
|
||||
} /* Func_2 */
|
||||
|
||||
|
||||
Boolean Func_3 (Enum_Par_Val)
|
||||
/***************************/
|
||||
/* executed once */
|
||||
/* Enum_Par_Val == Ident_3 */
|
||||
Enumeration Enum_Par_Val;
|
||||
{
|
||||
Enumeration Enum_Loc;
|
||||
|
||||
Enum_Loc = Enum_Par_Val;
|
||||
if (Enum_Loc == Ident_3)
|
||||
/* then, executed */
|
||||
return (true);
|
||||
else /* not executed */
|
||||
return (false);
|
||||
} /* Func_3 */
|
||||
|
|
@ -0,0 +1 @@
|
|||
../../asm/printf.c
|
|
@ -0,0 +1,6 @@
|
|||
export TEST = hello_world
|
||||
export OFILES = hello_world.o
|
||||
export BUILD_DIR = ../snapshots/default
|
||||
|
||||
clean .DEFAULT:
|
||||
$(MAKE) -e -f $(RV_ROOT)/tools/MakeHex $@
|
|
@ -0,0 +1,72 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2019 Western Digital Corporation or its affiliates.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// Assembly code for Hello World
|
||||
// Not using only ALU ops for creating the string
|
||||
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#define STDOUT 0xd0580000
|
||||
|
||||
|
||||
// Code to execute
|
||||
.section .text
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
// Clear minstret
|
||||
csrw minstret, zero
|
||||
csrw minstreth, zero
|
||||
|
||||
// Set up MTVEC - not expecting to use it though
|
||||
li x1, RV_ICCM_SADR
|
||||
csrw mtvec, x1
|
||||
|
||||
|
||||
// Enable Caches in MRAC
|
||||
li x1, 0x5f555555
|
||||
csrw 0x7c0, x1
|
||||
|
||||
// Load string from hw_data
|
||||
// and write to stdout address
|
||||
|
||||
li x3, STDOUT
|
||||
la x4, hw_data
|
||||
|
||||
loop:
|
||||
lb x5, 0(x4)
|
||||
sb x5, 0(x3)
|
||||
addi x4, x4, 1
|
||||
bnez x5, loop
|
||||
|
||||
// Write 0xff to STDOUT for TB to terminate test.
|
||||
_finish:
|
||||
li x3, STDOUT
|
||||
addi x5, x0, 0xff
|
||||
sb x5, 0(x3)
|
||||
beq x0, x0, _finish
|
||||
.rept 100
|
||||
nop
|
||||
.endr
|
||||
|
||||
.global hw_data
|
||||
.data
|
||||
hw_data:
|
||||
.ascii "----------------------------------\n"
|
||||
.ascii "Hello World from SweRV EH1 @WDC !!\n"
|
||||
.ascii "----------------------------------\n"
|
||||
.byte 0
|
|
@ -13,12 +13,15 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
CONF_PARAMS = -set iccm_enable
|
||||
# Check for RV_ROOT
|
||||
ifeq (,$(wildcard ${RV_ROOT}/configs/swerv.config))
|
||||
$(error env var RV_ROOT does not point to a valid dir! Exiting!)
|
||||
endif
|
||||
|
||||
TEST_CFLAGS = -g -O3 -funroll-all-loops
|
||||
ABI = -mabi=ilp32 -march=rv32imc
|
||||
|
||||
# Allow snapshot override
|
||||
target = default
|
||||
snapshot = $(target)
|
||||
|
@ -40,6 +43,9 @@ TEST = hello_world
|
|||
# Define default test directory
|
||||
TEST_DIR = $(TBDIR)/asm
|
||||
HEX_DIR = $(TBDIR)/hex
|
||||
ifneq (,$(wildcard $(TBDIR)/tests/$(TEST)))
|
||||
TEST_DIR = $(TBDIR)/tests/$(TEST)
|
||||
endif
|
||||
|
||||
ifdef debug
|
||||
DEBUG_PLUS = +dumpon
|
||||
|
@ -57,6 +63,10 @@ else
|
|||
LINK = $(TEST_DIR)/$(TEST).ld
|
||||
endif
|
||||
|
||||
OFILES = $(TEST).o
|
||||
|
||||
-include $(TEST_DIR)/$(TEST).mki
|
||||
|
||||
VPATH = $(TEST_DIR) $(BUILD_DIR) $(TBDIR)
|
||||
TBFILES = $(TBDIR)/tb_top.sv $(TBDIR)/ahb_sif.sv
|
||||
|
||||
|
@ -67,13 +77,13 @@ includes = -I${RV_ROOT}/design/include -I${RV_ROOT}/design/lib -I${BUILD_DIR}
|
|||
CFLAGS += "-std=c++11"
|
||||
# Optimization for better performance; alternative is nothing for slower runtime (faster compiles)
|
||||
# -O2 for faster runtime (slower compiles), or -O for balance.
|
||||
VERILATOR_MAKE_FLAGS = OPT_FAST="-O2"
|
||||
VERILATOR_MAKE_FLAGS = OPT_FAST="-Os"
|
||||
|
||||
# Targets
|
||||
all: clean verilator
|
||||
|
||||
clean:
|
||||
rm -rf *.log *.s *.hex *.dis *.tbl irun* vcs* simv* snapshots swerv* \
|
||||
rm -rf *.log *.s *.hex *.dis *.tbl irun* vcs* simv* *.map snapshots swerv* \
|
||||
verilator* *.exe obj* *.o ucli.key vc_hdrs.h csrc *.csv \
|
||||
work dataset.asdb library.cfg
|
||||
|
||||
|
@ -81,16 +91,18 @@ clean:
|
|||
${BUILD_DIR}/defines.h :
|
||||
BUILD_PATH=${BUILD_DIR} ${SWERV_CONFIG} -target=$(target) $(CONF_PARAMS)
|
||||
|
||||
##################### Verilog Builds #####################################
|
||||
|
||||
verilator-build: ${TBFILES} ${BUILD_DIR}/defines.h test_tb_top.cpp
|
||||
echo '`undef ASSERT_ON' >> ${BUILD_DIR}/common_defines.vh
|
||||
$(VERILATOR) '-UASSERT_ON' --cc -CFLAGS ${CFLAGS} $(defines) $(includes) \
|
||||
$(VERILATOR) --cc -CFLAGS ${CFLAGS} $(defines) $(includes) \
|
||||
-Wno-UNOPTFLAT \
|
||||
-I${RV_ROOT}/testbench \
|
||||
-f ${RV_ROOT}/testbench/flist \
|
||||
${TBFILES} \
|
||||
--top-module tb_top -exe test_tb_top.cpp --autoflush $(VERILATOR_DEBUG)
|
||||
cp ${RV_ROOT}/testbench/test_tb_top.cpp obj_dir
|
||||
$(MAKE) -C obj_dir/ -f Vtb_top.mk $(VERILATOR_MAKE_FLAGS)
|
||||
$(MAKE) -j -C obj_dir/ -f Vtb_top.mk $(VERILATOR_MAKE_FLAGS)
|
||||
touch verilator-build
|
||||
|
||||
vcs-build: ${TBFILES} ${BUILD_DIR}/defines.h
|
||||
|
@ -108,7 +120,7 @@ irun-build: ${TBFILES} ${BUILD_DIR}/defines.h
|
|||
-incdir ${RV_ROOT}/design/lib -incdir ${RV_ROOT}/design/include -incdir ${BUILD_DIR} -vlog_ext +.vh+.h\
|
||||
$(defines) -f ${RV_ROOT}/testbench/flist\
|
||||
-top tb_top ${TBFILES} -I${RV_ROOT}/testbench \
|
||||
-elaborate -snapshot $(snapshot)
|
||||
-elaborate -snapshot $(snapshot) $(profile)
|
||||
touch irun-build
|
||||
|
||||
riviera-build: ${TBFILES} ${BUILD_DIR}/defines.h
|
||||
|
@ -121,23 +133,30 @@ riviera-build: ${TBFILES} ${BUILD_DIR}/defines.h
|
|||
${TBFILES}
|
||||
touch riviera-build
|
||||
|
||||
##################### Simulation Runs #####################################
|
||||
|
||||
verilator: program.hex verilator-build
|
||||
./obj_dir/Vtb_top ${DEBUG_PLUS}
|
||||
|
||||
irun: program.hex irun-build
|
||||
$(IRUN) -64bit -abvglobalfailurelimit 1 +lic_queue -licqueue -status -xmlibdirpath . -xmlibdirname swerv.build \
|
||||
-snapshot ${snapshot} -r ${snapshot} $(IRUN_DEBUG_RUN)
|
||||
$(IRUN) -64bit +lic_queue -licqueue -status -xmlibdirpath . -xmlibdirname swerv.build \
|
||||
-snapshot ${snapshot} -r ${snapshot} $(IRUN_DEBUG_RUN) $(profile)
|
||||
|
||||
vcs: program.hex vcs-build
|
||||
./simv $(DEBUG_PLUS) +vcs+lic+wait -l vcs.log
|
||||
|
||||
vlog: program.hex ${TBFILES} ${BUILD_DIR}/defines.h
|
||||
$(VLOG) -l vlog.log -sv -mfcu +incdir+${BUILD_DIR}+${RV_ROOT}/design/include+${RV_ROOT}/design/lib\
|
||||
$(defines) -f ${RV_ROOT}/testbench/flist ${TBFILES} -R ${DEBUG_PLUS}
|
||||
$(defines) -f ${RV_ROOT}/testbench/flist ${TBFILES} -R +nowarn3829 ${DEBUG_PLUS}
|
||||
|
||||
riviera: program.hex riviera-build
|
||||
vsim -c -lib work ${DEBUG_PLUS} ${RIVIERA_DEBUG} tb_top -do "run -all; exit" -l riviera.log
|
||||
|
||||
|
||||
|
||||
##################### Test Build #####################################
|
||||
|
||||
|
||||
ifeq ($(shell which $(GCC_PREFIX)-gcc 2> /dev/null),)
|
||||
program.hex: ${BUILD_DIR}/defines.h
|
||||
@echo " !!! No $(GCC_PREFIX)-gcc in path, using canned hex files !!"
|
||||
|
@ -147,19 +166,17 @@ ifneq (,$(wildcard $(TEST_DIR)/$(TEST).makefile))
|
|||
program.hex:
|
||||
$(MAKE) -f $(TEST_DIR)/$(TEST).makefile
|
||||
else
|
||||
program.hex: $(TEST).o $(LINK)
|
||||
program.hex: $(OFILES) $(LINK)
|
||||
@echo Building $(TEST)
|
||||
$(GCC_PREFIX)-ld -m elf32lriscv --discard-none -T$(LINK) -o $(TEST).exe $(TEST).o
|
||||
$(GCC_PREFIX)-gcc $(ABI) -Wl,-Map=$(TEST).map -lgcc -T$(LINK) -o $(TEST).exe $(OFILES) -nostartfiles $(TEST_LIBS)
|
||||
$(GCC_PREFIX)-objcopy -O verilog $(TEST).exe program.hex
|
||||
$(GCC_PREFIX)-objdump -S $(TEST).exe > $(TEST).dis
|
||||
@echo Completed building $(TEST)
|
||||
|
||||
%.o : %.s ${BUILD_DIR}/defines.h
|
||||
$(GCC_PREFIX)-cpp -I${BUILD_DIR} $< > $(TEST).cpp.s
|
||||
$(GCC_PREFIX)-as -march=rv32gc $(TEST).cpp.s -o $(TEST).o
|
||||
$(GCC_PREFIX)-cpp -I${BUILD_DIR} $< > $*.cpp.s
|
||||
$(GCC_PREFIX)-as $(ABI) $*.cpp.s -o $@
|
||||
|
||||
TEST_CFLAGS = -g -O3 -funroll-all-loops
|
||||
ABI = -mabi=ilp32 -march=rv32imc
|
||||
|
||||
%.o : %.c ${BUILD_DIR}/defines.h
|
||||
$(GCC_PREFIX)-gcc -I${BUILD_DIR} ${TEST_CFLAGS} ${ABI} -nostdlib -c $< -o $@
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
set_property is_global_include true [get_files config/common_defines.vh]
|
||||
set_property IS_GLOBAL_INCLUDE 1 [get_files include/def.sv]
|
||||
|
|
Loading…
Reference in New Issue