riscv regression suite, riscv_isa and riscv_compliance test integrated
diff --git a/.gitmodules b/.gitmodules
index a20fefd..8eccf3e 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,3 +2,13 @@
path = caravel
url = https://github.com/efabless/caravel-lite.git
branch = mpw-two
+[submodule "verilog/rtl/syntacore/scr1/dependencies/riscv-tests"]
+ path = verilog/rtl/syntacore/scr1/dependencies/riscv-tests
+ url = https://github.com/riscv/riscv-tests
+[submodule "verilog/rtl/syntacore/scr1/dependencies/riscv-compliance"]
+ path = verilog/rtl/syntacore/scr1/dependencies/riscv-compliance
+ url = https://github.com/riscv/riscv-compliance
+ branch = d51259b2a949be3af02e776c39e135402675ac9b
+[submodule "verilog/rtl/syntacore/scr1/dependencies/coremark"]
+ path = verilog/rtl/syntacore/scr1/dependencies/coremark
+ url = https://github.com/eembc/coremark
diff --git a/verilog/dv/riscv_regress/Makefile b/verilog/dv/riscv_regress/Makefile
new file mode 100644
index 0000000..c1bba74
--- /dev/null
+++ b/verilog/dv/riscv_regress/Makefile
@@ -0,0 +1,364 @@
+#------------------------------------------------------------------------------
+# Makefile for SCR1
+#------------------------------------------------------------------------------
+
+# PARAMETERS
+
+# CFG = <MAX, BASE, MIN, CUSTOM>
+# BUS = <AHB, AXI, WB>
+
+export CFG ?= MAX
+export BUS ?= WB
+
+ifeq ($(CFG), MAX)
+# Predefined configuration SCR1_CFG_RV32IMC_MAX
+ override ARCH := IMC
+ override VECT_IRQ := 1
+ override IPIC := 1
+ override TCM := 1
+ override SIM_CFG_DEF := SCR1_CFG_RV32IMC_MAX
+else
+ ifeq ($(CFG), BASE)
+ # Predefined configuration SCR1_CFG_RV32IC_BASE
+ override ARCH := IC
+ override VECT_IRQ := 1
+ override IPIC := 1
+ override TCM := 1
+ override SIM_CFG_DEF := SCR1_CFG_RV32IC_BASE
+ else
+ ifeq ($(CFG), MIN)
+ # Predefined configuration SCR1_CFG_RV32EC_MIN
+ override ARCH := EC
+ override VECT_IRQ := 0
+ override IPIC := 0
+ override TCM := 1
+ override SIM_CFG_DEF := SCR1_CFG_RV32EC_MIN
+ else
+ # CUSTOM configuration. Parameters can be overwritten
+ # These options are for compiling tests only. Set the corresponding RTL parameters manually in the file scr1_arch_description.svh.
+ # ARCH = <IMC, IC, IM, I, EMC, EM, EC, E>
+ # VECT_IRQ = <0, 1>
+ # IPIC = <0, 1>
+ # TCM = <0, 1>
+ ARCH ?= IMC
+ VECT_IRQ ?= 0
+ IPIC ?= 0
+ TCM ?= 0
+ SIM_CFG_DEF = SCR1_CFG_$(CFG)
+ endif
+ endif
+endif
+
+# export all overrided variables
+export ARCH
+export VECT_IRQ
+export IPIC
+export TCM
+export SIM_CFG_DEF
+
+ARCH_lowercase = $(shell echo $(ARCH) | tr A-Z a-z)
+BUS_lowercase = $(shell echo $(BUS) | tr A-Z a-z)
+
+ifeq ($(ARCH_lowercase),)
+ ARCH_tmp = imc
+else
+ ifneq (,$(findstring e,$(ARCH_lowercase)))
+ ARCH_tmp += e
+ EXT_CFLAGS += -D__RVE_EXT
+ else
+ ARCH_tmp += i
+ endif
+ ifneq (,$(findstring m,$(ARCH_lowercase)))
+ ARCH_tmp := $(ARCH_tmp)m
+ endif
+ ifneq (,$(findstring c,$(ARCH_lowercase)))
+ ARCH_tmp := $(ARCH_tmp)c
+ EXT_CFLAGS += -D__RVC_EXT
+ endif
+endif
+
+override ARCH=$(ARCH_tmp)
+
+# Use this parameter to enable tracelog
+TRACE ?= 0
+
+ifeq ($(TRACE), 1)
+ export SIM_TRACE_DEF = SCR1_TRACE_LOG_EN
+else
+ export SIM_TRACE_DEF = SCR1_TRACE_LOG_DIS
+endif
+
+
+# Use this parameter to pass additional options for simulation build command
+SIM_BUILD_OPTS ?=
+
+# Use this parameter to set the list of tests to run
+# TARGETS = <riscv_isa, riscv_compliance, coremark, dhrystone21, hello, isr_sample>
+export TARGETS :=
+
+
+export ABI ?= ilp32
+# Testbench memory delay patterns\
+ (FFFFFFFF - no delay, 00000000 - random delay, 00000001 - max delay)
+imem_pattern ?= FFFFFFFF
+dmem_pattern ?= FFFFFFFF
+
+VCS_OPTS ?=
+MODELSIM_OPTS ?=
+NCSIM_OPTS ?=
+VERILATOR_OPTS ?=
+
+current_goal := $(MAKECMDGOALS:run_%=%)
+ifeq ($(current_goal),)
+ current_goal := iverilog
+endif
+
+
+export root_dir := $(shell pwd)
+export bld_dir := $(root_dir)/build/$(current_goal)_$(BUS)_$(CFG)_$(ARCH)_IPIC_$(IPIC)_TCM_$(TCM)_VIRQ_$(VECT_IRQ)_TRACE_$(TRACE)
+
+## Caravel Pointers related to build directory
+CARAVEL_ROOT ?= $(root_dir)/../../../caravel
+CARAVEL_PATH ?= $(CARAVEL_ROOT)
+CARAVEL_FIRMWARE_PATH = $(CARAVEL_PATH)/verilog/dv/caravel
+CARAVEL_VERILOG_PATH = $(CARAVEL_PATH)/verilog
+CARAVEL_RTL_PATH = $(CARAVEL_VERILOG_PATH)/rtl
+CARAVEL_BEHAVIOURAL_MODELS = $(CARAVEL_VERILOG_PATH)/dv/caravel
+
+
+## User Project Pointers
+UPRJ_VERILOG_PATH ?= $(root_dir)/../../../verilog
+UPRJ_TESTS_PATH = $(root_dir)
+UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl
+UPRJ_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = $(root_dir)/../model
+UPRJ_BEHAVIOURAL_AGENTS = $(root_dir)/../agents
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+
+sv_list = ../../user_risc_regress_tb.v
+top_module = user_risc_regress_tb
+
+# TB Paths
+export sim_dir := $(UPRJ_RTL_PATH)/syntacore/scr1/sim
+export tst_dir := $(sim_dir)/tests
+export inc_dir := $(tst_dir)/common
+
+test_results := $(bld_dir)/test_results.txt
+test_info := $(bld_dir)/test_info
+sim_results := $(bld_dir)/sim_results.txt
+
+todo_list := $(bld_dir)/todo.txt
+
+# Environment
+export CROSS_PREFIX ?= riscv64-unknown-elf-
+export RISCV_GCC ?= $(CROSS_PREFIX)gcc
+export RISCV_OBJDUMP ?= $(CROSS_PREFIX)objdump -D
+export RISCV_ROM_OBJCOPY ?= $(CROSS_PREFIX)objcopy -j .text.init -j .text -O verilog
+export RISCV_RAM_OBJCOPY ?= $(CROSS_PREFIX)objcopy -R .text.init -R .text -O verilog
+export RISCV_READELF ?= $(CROSS_PREFIX)readelf -s
+
+ifneq (,$(findstring e,$(ARCH_lowercase)))
+# Tests can be compiled for RVE only if gcc version 8.0.0 or higher
+ GCCVERSIONGT7 := $(shell expr `$(RISCV_GCC) -dumpfullversion | cut -f1 -d'.'` \> 7)
+ ifeq "$(GCCVERSIONGT7)" "1"
+ ABI := ilp32e
+ endif
+endif
+
+#--
+ifeq (,$(findstring e,$(ARCH_lowercase)))
+ # These tests cannot be compiled for RVE
+ # Comment this target if you don't want to run the riscv_isa
+ TARGETS += riscv_isa
+
+ # Comment this target if you don't want to run the riscv_compliance
+ TARGETS += riscv_compliance
+endif
+
+# Comment this target if you don't want to run the isr_sample
+#TARGETS += isr_sample
+
+# Comment this target if you don't want to run the coremark
+#TARGETS += coremark
+
+# Comment this target if you don't want to run the dhrystone
+#TARGETS += dhrystone21
+
+# Comment this target if you don't want to run the hello test
+#TARGETS += hello
+
+
+# Targets
+.PHONY: tests run_iverilog run_modelsim run_modelsim_wlf run_vcs run_ncsim run_verilator run_verilator_wf
+
+default: clean_test_list run_verilator
+
+clean_test_list:
+ rm -f $(test_info)
+
+echo_out: tests
+ @echo " Test | build | simulation " ;
+ @echo "$$(cat $(test_results))"
+
+tests: $(TARGETS)
+
+$(test_info): clean_hex tests
+ cd $(bld_dir)
+
+isr_sample: | $(bld_dir)
+ $(MAKE) -C $(tst_dir)/isr_sample ARCH=$(ARCH) IPIC=$(IPIC) VECT_IRQ=$(VECT_IRQ)
+
+dhrystone21: | $(bld_dir)
+ $(MAKE) -C $(tst_dir)/benchmarks/dhrystone21 EXT_CFLAGS="$(EXT_CFLAGS)" ARCH=$(ARCH)
+
+coremark: | $(bld_dir)
+ -$(MAKE) -C $(tst_dir)/benchmarks/coremark EXT_CFLAGS="$(EXT_CFLAGS)" ARCH=$(ARCH)
+
+riscv_isa: | $(bld_dir)
+ $(MAKE) -C $(tst_dir)/riscv_isa ARCH=$(ARCH)
+
+riscv_compliance: | $(bld_dir)
+ $(MAKE) -C $(tst_dir)/riscv_compliance ARCH=$(ARCH)
+
+hello: | $(bld_dir)
+ -$(MAKE) -C $(tst_dir)/hello EXT_CFLAGS="$(EXT_CFLAGS)" ARCH=$(ARCH)
+
+test: | $(bld_dir)
+ -$(MAKE) -C $(tst_dir)/test EXT_CFLAGS="$(EXT_CFLAGS)" ARCH=$(ARCH)
+
+clean_hex: | $(bld_dir)
+ $(RM) $(bld_dir)/*.hex
+
+$(bld_dir):
+ mkdir -p $(bld_dir)
+
+run_vcs: $(test_info)
+ $(MAKE) -C $(root_dir)/sim build_vcs SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS);
+ printf "" > $(test_results);
+ cd $(bld_dir); \
+ $(bld_dir)/simv -V \
+ +test_info=$(test_info) \
+ +test_results=$(test_results) \
+ +imem_pattern=$(imem_pattern) \
+ +dmem_pattern=$(dmem_pattern) \
+ $(VCS_OPTS) | tee $(sim_results) ;\
+ printf " Test | build | simulation \n" ; \
+ printf "$$(cat $(test_results)) \n"
+run_modelsim: $(test_info)
+ $(MAKE) -C $(root_dir)/sim build_modelsim SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS); \
+ printf "" > $(test_results); \
+ cd $(bld_dir); \
+ vsim -c -do "run -all" +nowarn3691 \
+ +test_info=$(test_info) \
+ +test_results=$(test_results) \
+ +imem_pattern=$(imem_pattern) \
+ +dmem_pattern=$(dmem_pattern) \
+ work.$(top_module) \
+ $(MODELSIM_OPTS) | tee $(sim_results) ;\
+ printf "Simulation performed on $$(vsim -version) \n" ;\
+ printf " Test | build | simulation \n" ; \
+ printf "$$(cat $(test_results)) \n"
+
+run_iverilog: $(test_info)
+ cd $(bld_dir); \
+ iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+ -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+ -I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+ -I $(UPRJ_BEHAVIOURAL_AGENTS) \
+ -I $(UPRJ_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+ -I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_TESTS_PATH) \
+ $(sv_list) \
+ -o $(top_module).vvp; \
+ printf "" > $(test_results); \
+ iverilog-vpi ../../../vpi/system/system.c; \
+ vvp -M. -msystem $(top_module).vvp \
+ +test_info=$(test_info) \
+ +test_results=$(test_results) \
+ | tee $(sim_results) ;\
+ printf "Simulation performed on $$(vvp -V) \n" ;\
+ printf " Test | build | simulation \n" ; \
+ printf "$$(cat $(test_results)) \n"
+
+run_iverilog_wf: $(test_info)
+ $(MAKE) -C $(root_dir)/sim build_iverilog_wf SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS); \
+ printf "" > $(test_results); \
+ cd $(bld_dir); \
+ iverilog-vpi ../../sim/iverilog_vpi/system.c; \
+ vvp -M. -msystem $(top_module).vvp \
+ +test_info=$(test_info) \
+ +test_results=$(test_results) \
+ +imem_pattern=$(imem_pattern) \
+ +dmem_pattern=$(dmem_pattern) \
+ | tee $(sim_results) ;\
+ printf "Simulation performed on $$(vvp -V) \n" ;\
+ printf " Test | build | simulation \n" ; \
+ printf "$$(cat $(test_results)) \n"
+
+run_modelsim_wlf: $(test_info)
+ $(MAKE) -C $(root_dir)/sim build_modelsim_wlf SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS); \
+ printf "" > $(test_results); \
+ cd $(bld_dir); \
+ vsim -c -do "run -all" +nowarn3691 \
+ +test_info=$(test_info) \
+ +test_results=$(test_results) \
+ +imem_pattern=$(imem_pattern) \
+ +dmem_pattern=$(dmem_pattern) \
+ work.$(top_module) \
+ $(MODELSIM_OPTS) | tee $(sim_results) ;\
+ printf "Simulation performed on $$(vsim -version) \n" ;\
+ printf " Test | build | simulation \n" ; \
+ printf "$$(cat $(test_results)) \n"
+run_ncsim: $(test_info)
+ $(MAKE) -C $(root_dir)/sim build_ncsim SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS);
+ printf "" > $(test_results);
+ cd $(bld_dir); \
+ irun \
+ -R \
+ -64bit \
+ +test_info=$(test_info) \
+ +test_results=$(test_results) \
+ +imem_pattern=$(imem_pattern) \
+ +dmem_pattern=$(dmem_pattern) \
+ $(NCSIM_OPTS) | tee $(sim_results) ;\
+ printf "Simulation performed on $$(irun -version) \n" ;\
+ printf " Test | build | simulation \n" ; \
+ printf "$$(cat $(test_results)) \n"
+
+run_verilator: $(test_info)
+ $(MAKE) -C $(root_dir)/sim build_verilator SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS);
+ printf "" > $(test_results);
+ cd $(bld_dir); \
+ echo $(top_module) | tee $(sim_results); \
+ $(bld_dir)/verilator/V$(top_module) \
+ +test_info=$(test_info) \
+ +test_results=$(test_results) \
+ +imem_pattern=$(imem_pattern) \
+ +dmem_pattern=$(dmem_pattern) \
+ $(VERILATOR_OPTS) | tee -a $(sim_results) ;\
+ printf "Simulation performed on $$(verilator -version) \n" ;\
+ printf " Test | build | simulation \n" ; \
+ printf "$$(cat $(test_results)) \n"
+
+run_verilator_wf: $(test_info)
+ $(MAKE) -C $(root_dir)/sim build_verilator_wf SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS);
+ printf "" > $(test_results);
+ cd $(bld_dir); \
+ echo $(top_module) | tee $(sim_results); \
+ $(bld_dir)/verilator/V$(top_module) \
+ +test_info=$(test_info) \
+ +test_results=$(test_results) \
+ +imem_pattern=$(imem_pattern) \
+ +dmem_pattern=$(dmem_pattern) \
+ $(VERILATOR_OPTS) | tee -a $(sim_results) ;\
+ printf "Simulation performed on $$(verilator -version) \n" ;\
+ printf " Test | build | simulation \n" ; \
+ printf "$$(cat $(test_results)) \n"
+clean:
+ $(MAKE) -C $(tst_dir)/benchmarks/dhrystone21 clean
+ $(MAKE) -C $(tst_dir)/riscv_isa clean
+ $(MAKE) -C $(tst_dir)/riscv_compliance clean
+ $(RM) -R $(root_dir)/build/*
+ $(RM) $(test_info)
diff --git a/verilog/dv/riscv_regress/riscv_runtests.sv b/verilog/dv/riscv_regress/riscv_runtests.sv
new file mode 100644
index 0000000..8f12e4e
--- /dev/null
+++ b/verilog/dv/riscv_regress/riscv_runtests.sv
@@ -0,0 +1,366 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file <scr1_top_tb_runtests.sv>
+/// @brief SCR1 testbench run tests
+///
+
+//-------------------------------------------------------------------------------
+// Run tests
+//-------------------------------------------------------------------------------
+
+initial begin
+ //$value$plusargs("imem_pattern=%h", imem_req_ack_stall);
+ //$value$plusargs("dmem_pattern=%h", dmem_req_ack_stall);
+
+ //$display("imem_pattern:%x",imem_req_ack_stall);
+ //$display("dmem_pattern:%x",dmem_req_ack_stall);
+`ifdef SIGNATURE_OUT
+ $value$plusargs("test_name=%s", s_testname);
+ b_single_run_flag = 1;
+`else // SIGNATURE_OUT
+
+ $value$plusargs("test_info=%s", s_info);
+ $value$plusargs("test_results=%s", s_results);
+
+ f_info = $fopen(s_info, "r");
+ f_results = $fopen(s_results, "a");
+`endif // SIGNATURE_OUT
+
+
+
+end
+/***
+// Debug message - dinesh A
+ logic [`SCR1_DMEM_AWIDTH-1:0] core2imem_addr_o_r; // DMEM address
+ logic [`SCR1_DMEM_AWIDTH-1:0] core2dmem_addr_o_r; // DMEM address
+ logic core2dmem_cmd_o_r;
+
+ `define RISC_CORE i_top.i_core_top
+
+ always@(posedge `RISC_CORE.clk) begin
+ if(`RISC_CORE.imem2core_req_ack_i && `RISC_CORE.core2imem_req_o)
+ core2imem_addr_o_r <= `RISC_CORE.core2imem_addr_o;
+
+ if(`RISC_CORE.dmem2core_req_ack_i && `RISC_CORE.core2dmem_req_o) begin
+ core2dmem_addr_o_r <= `RISC_CORE.core2dmem_addr_o;
+ core2dmem_cmd_o_r <= `RISC_CORE.core2dmem_cmd_o;
+ end
+
+ if(`RISC_CORE.imem2core_resp_i !=0)
+ $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x Resonse: %x", core2imem_addr_o_r,`RISC_CORE.imem2core_rdata_i,`RISC_CORE.imem2core_resp_i);
+ if((`RISC_CORE.dmem2core_resp_i !=0) && core2dmem_cmd_o_r)
+ $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", core2dmem_addr_o_r,`RISC_CORE.core2dmem_wdata_o,`RISC_CORE.dmem2core_resp_i);
+ if((`RISC_CORE.dmem2core_resp_i !=0) && !core2dmem_cmd_o_r)
+ $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", core2dmem_addr_o_r,`RISC_CORE.dmem2core_rdata_i,`RISC_CORE.dmem2core_resp_i);
+ end
+**/
+/**
+ logic [31:0] test_count;
+ `define RISC_CORE i_top.i_core_top
+ `define RISC_EXU i_top.i_core_top.i_pipe_top.i_pipe_exu
+
+ initial begin
+ test_count = 0;
+ end
+
+
+ always@(posedge `RISC_CORE.clk) begin
+ if(`RISC_EXU.pc_curr_upd) begin
+ $display("RISCV-DEBUG => Cnt: %x PC: %x", test_count,`RISC_EXU.pc_curr_ff);
+ test_count <= test_count+1;
+ end
+ end
+**/
+
+always_ff @(posedge clk) begin
+ bit test_pass;
+ int unsigned f_test;
+ if (test_running) begin
+ test_pass = 1;
+ rst_init <= 1'b0;
+ if ((u_top.u_riscv_top.i_core_top.i_pipe_top.curr_pc == SCR1_SIM_EXIT_ADDR) & ~rst_init & &rst_cnt) begin
+ `ifdef VERILATOR
+ logic [255:0] full_filename;
+ full_filename = test_file;
+ `else // VERILATOR
+ string full_filename;
+ full_filename = test_file;
+ `endif // VERILATOR
+
+ if (is_compliance(test_file)) begin
+
+ logic [31:0] tmpv, start, stop, ref_data, test_data;
+ integer fd;
+ `ifdef VERILATOR
+ logic [2047:0] tmpstr;
+ `else // VERILATOR
+ string tmpstr;
+ `endif // VERILATOR
+ test_running <= 1'b0;
+ test_pass = 1;
+
+ $sformat(tmpstr, "riscv64-unknown-elf-readelf -s %s | grep 'begin_signature\\|end_signature' | awk '{print $2}' > elfinfo", get_filename(test_file));
+ fd = $fopen("script.sh", "w");
+ if (fd == 0) begin
+ $write("Can't open script.sh\n");
+ $display("ERRIR:Can't open script.sh\n");
+ test_pass = 0;
+ end
+ $fwrite(fd, "%s", tmpstr);
+ $fclose(fd);
+ $system("sh script.sh");
+
+ fd = $fopen("elfinfo", "r");
+ if (fd == 0) begin
+ $write("Can't open elfinfo\n");
+ $display("ERROR: Can't open elfinfo\n");
+ test_pass = 0;
+ end
+ if ($fscanf(fd,"%h\n%h", start, stop) != 2) begin
+ $write("Wrong elfinfo data\n");
+ $display("ERROR:Wrong elfinfo data: start: %x stop: %x\n",start,stop);
+ test_pass = 0;
+ end
+ if (start > stop) begin
+ tmpv = start;
+ start = stop;
+ stop = tmpv;
+ end
+ $fclose(fd);
+
+ if((start & 32'h1FFF) > 512)
+ $display("ERROR: Start address is more than 512, Start: %x",start & 32'h1FFF);
+ if((stop & 32'h1FFF) > 512)
+ $display("ERROR: Stop address is more than 512, Start: %x",stop & 32'h1FFF);
+
+ `ifdef SIGNATURE_OUT
+
+ $sformat(tmpstr, "%s.signature.output", s_testname);
+`ifdef VERILATOR
+ tmpstr = remove_trailing_whitespaces(tmpstr);
+`endif
+ fd = $fopen(tmpstr, "w");
+ while ((start != stop)) begin
+ test_data[31:24] = u_sdram8.Bank0[(start & 32'h1FFF)+3];
+ test_data[23:16] = u_sdram8.Bank0[(start & 32'h1FFF)+2];
+ test_data[15:8] = u_sdram8.Bank0[(start & 32'h1FFF)+1];
+ test_data[7:0] = u_sdram8.Bank0[(start & 32'h1FFF)+0];
+ $fwrite(fd, "%x", test_data);
+ $fwrite(fd, "%s", "\n");
+ start += 4;
+ end
+ $fclose(fd);
+ `else //SIGNATURE_OUT
+ $sformat(tmpstr, "riscv_compliance/ref_data/%s", get_ref_filename(test_file));
+`ifdef VERILATOR
+ tmpstr = remove_trailing_whitespaces(tmpstr);
+`endif
+ fd = $fopen(tmpstr,"r");
+ if (fd == 0) begin
+ $write("Can't open reference_data file: %s\n", tmpstr);
+ $display("ERROR: Can't open reference_data file: %s\n", tmpstr);
+ test_pass = 0;
+ end
+ while (!$feof(fd) && (start != stop)) begin
+ $fscanf(fd, "0x%h,\n", ref_data);
+ //----------------------------------------------------
+ // Note: 32'h2xxx_xxxx address mapped to SDRAM
+ // Assumed all signaure are with-in first 512 location of memory,
+ // other-wise need to switch bank
+ // --------------------------------------------------
+ test_data[31:24] = u_sdram8.Bank0[(start & 32'h1FFF)+3];
+ test_data[23:16] = u_sdram8.Bank0[(start & 32'h1FFF)+2];
+ test_data[15:8] = u_sdram8.Bank0[(start & 32'h1FFF)+1];
+ test_data[7:0] = u_sdram8.Bank0[(start & 32'h1FFF)+0];
+ //$display("Compare Addr: %x ref_data : %x, test_data: %x",start,ref_data,test_data);
+ test_pass &= (ref_data == test_data);
+ if(ref_data != test_data)
+ $display("ERROR: Compare Addr: %x ref_data : %x, test_data: %x",start,ref_data,test_data);
+ start += 4;
+ end
+ $fclose(fd);
+ tests_total += 1;
+ tests_passed += test_pass;
+ if (test_pass) begin
+ $write("\033[0;32mTest passed\033[0m\n");
+ end else begin
+ $write("\033[0;31mTest failed-2\033[0m\n");
+ end
+ `endif // SIGNATURE_OUT
+ end else begin
+ test_running <= 1'b0;
+ test_pass = (u_top.u_riscv_top.i_core_top.i_pipe_top.i_pipe_mprf.mprf_int[10] == 0);
+ tests_total += 1;
+ tests_passed += test_pass;
+ `ifndef SIGNATURE_OUT
+ if (test_pass) begin
+ $write("\033[0;32mTest passed\033[0m\n");
+ end else begin
+ $write("\033[0;31mTest failed\033[0m\n");
+ end
+ `endif //SIGNATURE_OUT
+ end
+ $fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "OK" , (test_pass ? "PASS" : "__FAIL"));
+ end
+ end else begin
+`ifdef VERILATOR
+ `ifdef SIGNATURE_OUT
+ if ((s_testname.len() != 0) && (b_single_run_flag)) begin
+ $sformat(test_file, "%s.bin", s_testname);
+ `else //SIGNATURE_OUT
+ if ($fgets(test_file,f_info)) begin
+ test_file = test_file >> 8; // < Removing trailing LF symbol ('\n')
+ `endif //SIGNATURE_OUT
+`else // VERILATOR
+ if (!$feof(f_info)) begin
+ $fscanf(f_info, "%s\n", test_file);
+`endif // VERILATOR
+ f_test = $fopen(test_file,"r");
+ if (f_test != 0) begin
+ // Launch new test
+ `ifdef SCR1_TRACE_LOG_EN
+ u_top.u_riscv_top.i_core_top.i_pipe_top.i_tracelog.test_name = test_file;
+ `endif // SCR1_TRACE_LOG_EN
+ //i_memory_tb.test_file = test_file;
+ //i_memory_tb.test_file_init = 1'b1;
+ `ifndef SIGNATURE_OUT
+ $write("\033[0;34m---Test: %s\033[0m\n", test_file);
+ `endif //SIGNATURE_OUT
+ test_running <= 1'b1;
+ rst_init <= 1'b1;
+ `ifdef SIGNATURE_OUT
+ b_single_run_flag = 0;
+ `endif
+ end else begin
+ $fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "__FAIL", "--------");
+ end
+ end else begin
+ // Exit
+ `ifndef SIGNATURE_OUT
+ $display("\n#--------------------------------------");
+ $display("# Summary: %0d/%0d tests passed", tests_passed, tests_total);
+ $display("#--------------------------------------\n");
+ $fclose(f_info);
+ $fclose(f_results);
+ `endif
+ $finish();
+ end
+ end
+end
+
+
+ `ifdef VERILATOR
+ function bit is_compliance (logic [255:0] testname);
+ bit res;
+ logic [79:0] pattern;
+ begin
+ pattern = 80'h636f6d706c69616e6365; // compliance
+ res = 0;
+ for (int i = 0; i<= 176; i++) begin
+ if(testname[i+:80] == pattern) begin
+ return ~res;
+ end
+ end
+ `ifdef SIGNATURE_OUT
+ return ~res;
+ `else
+ return res;
+ `endif
+ end
+ endfunction : is_compliance
+
+ function logic [255:0] get_filename (logic [255:0] testname);
+ logic [255:0] res;
+ int i, j;
+ begin
+ testname[7:0] = 8'h66;
+ testname[15:8] = 8'h6C;
+ testname[23:16] = 8'h65;
+
+ for (i = 0; i <= 248; i += 8) begin
+ if (testname[i+:8] == 0) begin
+ break;
+ end
+ end
+ i -= 8;
+ for (j = 255; i >= 0;i -= 8) begin
+ res[j-:8] = testname[i+:8];
+ j -= 8;
+ end
+ for (; j >= 0;j -= 8) begin
+ res[j-:8] = 0;
+ end
+
+ return res;
+ end
+ endfunction : get_filename
+
+ function logic [255:0] get_ref_filename (logic [255:0] testname);
+ logic [255:0] res;
+ int i, j;
+ logic [79:0] pattern;
+ begin
+ pattern = 80'h636f6d706c69616e6365; // compliance
+
+ for(int i = 0; i <= 176; i++) begin
+ if(testname[i+:80] == pattern) begin
+ testname[(i-8)+:88] = 0;
+ break;
+ end
+ end
+
+ for(i = 32; i <= 248; i += 8) begin
+ if(testname[i+:8] == 0) break;
+ end
+ i -= 8;
+ for(j = 255; i > 24; i -= 8) begin
+ res[j-:8] = testname[i+:8];
+ j -= 8;
+ end
+ for(; j >=0;j -= 8) begin
+ res[j-:8] = 0;
+ end
+
+ return res;
+ end
+ endfunction : get_ref_filename
+
+ function logic [2047:0] remove_trailing_whitespaces (logic [2047:0] str);
+ int i;
+ begin
+ for (i = 0; i <= 2040; i += 8) begin
+ if (str[i+:8] != 8'h20) begin
+ break;
+ end
+ end
+ str = str >> i;
+ return str;
+ end
+ endfunction: remove_trailing_whitespaces
+
+ `else // VERILATOR
+ function bit is_compliance (string testname);
+ begin
+ return (testname.substr(0, 9) == "compliance");
+ end
+ endfunction : is_compliance
+
+ function string get_filename (string testname);
+ int length;
+ begin
+ length = testname.len();
+ testname[length-1] = "f";
+ testname[length-2] = "l";
+ testname[length-3] = "e";
+
+ return testname;
+ end
+ endfunction : get_filename
+
+ function string get_ref_filename (string testname);
+ begin
+ return testname.substr(11, testname.len() - 5);
+ end
+ endfunction : get_ref_filename
+
+ `endif // VERILATOR
+
diff --git a/verilog/dv/riscv_regress/uprj_netlists.v b/verilog/dv/riscv_regress/uprj_netlists.v
new file mode 100644
index 0000000..e53865f
--- /dev/null
+++ b/verilog/dv/riscv_regress/uprj_netlists.v
@@ -0,0 +1,138 @@
+// SPDX-FileCopyrightText: 2020 Efabless Corporation
+//
+// 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.
+// SPDX-License-Identifier: Apache-2.0
+
+// Include caravel global defines for the number of the user project IO pads
+`include "defines.v"
+ `define USE_POWER_PINS
+ `define UNIT_DELAY #0.1
+
+`ifdef GL
+ `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v"
+ `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v"
+ `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v"
+ `include "libs.ref/sky130_fd_sc_hvl/verilog/sky130_fd_sc_hvl.v"
+ `include "libs.ref//sky130_fd_sc_hd/verilog/sky130_ef_sc_hd__fakediode_2.v"
+
+ `include "glbl_cfg.v"
+ `include "sdram.v"
+ `include "spi_master.v"
+ `include "uart_i2cm_usb.v"
+ `include "wb_interconnect.v"
+ `include "user_project_wrapper.v"
+ `include "syntacore.v"
+ `include "wb_host.v"
+ `include "clk_skew_adjust.v"
+
+`else
+ `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v"
+ `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v"
+ `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v"
+ `include "libs.ref/sky130_fd_sc_hvl/verilog/sky130_fd_sc_hvl.v"
+
+
+ `include "spi_master/src/spim_top.sv"
+ `include "spi_master/src/spim_if.sv"
+ `include "spi_master/src/spim_fifo.sv"
+ `include "spi_master/src/spim_regs.sv"
+ `include "spi_master/src/spim_clkgen.sv"
+ `include "spi_master/src/spim_ctrl.sv"
+ `include "spi_master/src/spim_rx.sv"
+ `include "spi_master/src/spim_tx.sv"
+
+ `include "uart/src/uart_core.sv"
+ `include "uart/src/uart_cfg.sv"
+ `include "uart/src/uart_rxfsm.sv"
+ `include "uart/src/uart_txfsm.sv"
+ `include "lib/async_fifo_th.sv"
+ `include "lib/reset_sync.sv"
+ `include "lib/double_sync_low.v"
+ `include "lib/clk_buf.v"
+
+ `include "i2cm/src/core/i2cm_bit_ctrl.v"
+ `include "i2cm/src/core/i2cm_byte_ctrl.v"
+ `include "i2cm/src/core/i2cm_top.v"
+
+ `include "usb1_host/src/core/usbh_core.sv"
+ `include "usb1_host/src/core/usbh_crc16.sv"
+ `include "usb1_host/src/core/usbh_crc5.sv"
+ `include "usb1_host/src/core/usbh_fifo.sv"
+ `include "usb1_host/src/core/usbh_sie.sv"
+ `include "usb1_host/src/phy/usb_fs_phy.v"
+ `include "usb1_host/src/phy/usb_transceiver.v"
+ `include "usb1_host/src/top/usb1_host.sv"
+
+ `include "uart_i2c_usb/src/uart_i2c_usb.sv"
+
+ `include "sdram_ctrl/src/top/sdrc_top.v"
+ `include "sdram_ctrl/src/wb2sdrc/wb2sdrc.v"
+ `include "lib/async_fifo.sv"
+ `include "sdram_ctrl/src/core/sdrc_core.v"
+ `include "sdram_ctrl/src/core/sdrc_bank_ctl.v"
+ `include "sdram_ctrl/src/core/sdrc_bank_fsm.v"
+ `include "sdram_ctrl/src/core/sdrc_bs_convert.v"
+ `include "sdram_ctrl/src/core/sdrc_req_gen.v"
+ `include "sdram_ctrl/src/core/sdrc_xfr_ctl.v"
+
+ `include "lib/registers.v"
+ `include "lib/clk_ctl.v"
+ `include "digital_core/src/glbl_cfg.sv"
+
+ `include "wb_host/src/wb_host.sv"
+ `include "lib/async_wb.sv"
+
+ `include "lib/wb_stagging.sv"
+ `include "wb_interconnect/src/wb_arb.sv"
+ `include "wb_interconnect/src/wb_interconnect.sv"
+
+
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_hdu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_tdu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_ipic.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_csr.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_exu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_ialu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_idu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_ifu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_lsu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_mprf.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_mul.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_div.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_top.sv"
+ `include "syntacore/scr1/src/core/primitives/scr1_reset_cells.sv"
+ `include "syntacore/scr1/src/core/primitives/scr1_cg.sv"
+ `include "syntacore/scr1/src/core/scr1_clk_ctrl.sv"
+ `include "syntacore/scr1/src/core/scr1_tapc_shift_reg.sv"
+ `include "syntacore/scr1/src/core/scr1_tapc.sv"
+ `include "syntacore/scr1/src/core/scr1_tapc_synchronizer.sv"
+ `include "syntacore/scr1/src/core/scr1_core_top.sv"
+ `include "syntacore/scr1/src/core/scr1_dm.sv"
+ `include "syntacore/scr1/src/core/scr1_dmi.sv"
+ `include "syntacore/scr1/src/core/scr1_scu.sv"
+
+ `include "syntacore/scr1/src/top/scr1_dmem_router.sv"
+ `include "syntacore/scr1/src/top/scr1_dp_memory.sv"
+ `include "syntacore/scr1/src/top/scr1_tcm.sv"
+ `include "syntacore/scr1/src/top/scr1_timer.sv"
+ `include "syntacore/scr1/src/top/scr1_dmem_wb.sv"
+ `include "syntacore/scr1/src/top/scr1_imem_wb.sv"
+ `include "syntacore/scr1/src/top/scr1_intf.sv"
+ `include "syntacore/scr1/src/top/scr1_top_wb.sv"
+ `include "lib/sync_fifo.sv"
+
+ `include "user_project_wrapper.v"
+ // we are using netlist file for clk_skew_adjust as it has
+ // standard cell + power pin
+ `include "gl/clk_skew_adjust.v"
+`endif
diff --git a/verilog/dv/riscv_regress/user_risc_regress_tb.v b/verilog/dv/riscv_regress/user_risc_regress_tb.v
new file mode 100644
index 0000000..37d6fb2
--- /dev/null
+++ b/verilog/dv/riscv_regress/user_risc_regress_tb.v
@@ -0,0 +1,615 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// 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.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Standalone User validation Test bench ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This is a standalone test bench to validate the ////
+//// Digital core. ////
+//// 1. User Risc core is booted using compiled code of ////
+//// user_risc_boot.c ////
+//// 2. User Risc core uses Serial Flash and SDRAM to boot ////
+//// 3. After successful boot, Risc core will write signature ////
+//// in to user register from 0x3000_0018 to 0x3000_002C ////
+//// 4. Through the External Wishbone Interface we read back ////
+//// and validate the user register to declared pass fail ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 16th Feb 2021, Dinesh A ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`default_nettype wire
+
+`timescale 1 ns / 1 ns
+
+`include "s25fl256s.sv"
+`include "uprj_netlists.v"
+`include "mt48lc8m8a2.v"
+
+module user_risc_regress_tb;
+ reg clock;
+ reg wb_rst_i;
+ reg power1, power2;
+ reg power3, power4;
+
+ reg wbd_ext_cyc_i; // strobe/request
+ reg wbd_ext_stb_i; // strobe/request
+ reg [31:0] wbd_ext_adr_i; // address
+ reg wbd_ext_we_i; // write
+ reg [31:0] wbd_ext_dat_i; // data output
+ reg [3:0] wbd_ext_sel_i; // byte enable
+
+ wire [31:0] wbd_ext_dat_o; // data input
+ wire wbd_ext_ack_o; // acknowlegement
+ wire wbd_ext_err_o; // error
+ wire clk;
+
+ // User I/O
+ wire [37:0] io_oeb;
+ wire [37:0] io_out;
+ wire [37:0] io_in;
+
+ wire gpio;
+ wire [37:0] mprj_io;
+ wire [7:0] mprj_io_0;
+ reg test_fail;
+ reg [31:0] read_data;
+
+
+ int unsigned f_results;
+ int unsigned f_info;
+
+ string s_results;
+ string s_info;
+ `ifdef SIGNATURE_OUT
+ string s_testname;
+ bit b_single_run_flag;
+ `endif // SIGNATURE_OUT
+
+
+ `ifdef VERILATOR
+ logic [255:0] test_file;
+ logic [255:0] test_ram_file;
+ `else // VERILATOR
+ string test_file;
+ string test_ram_file;
+
+ `endif // VERILATOR
+
+
+ event reinit_event;
+ bit test_running;
+ int unsigned tests_passed;
+ int unsigned tests_total;
+
+ logic [7:0] tem_mem[0:2047];
+
+
+ //-----------------------------------------------------------------
+ // Since this is regression, reset will be applied multiple time
+ // Reset logic
+ // ----------------------------------------------------------------
+ bit [1:0] rst_cnt;
+ bit rst_init;
+ wire rst_n;
+
+
+ assign rst_n = &rst_cnt;
+ assign wb_rst_i = !rst_n;
+
+ always_ff @(posedge clk) begin
+ if (rst_init) begin
+ rst_cnt <= '0;
+ -> reinit_event;
+ end
+ else if (~&rst_cnt) rst_cnt <= rst_cnt + 1'b1;
+ end
+
+ // External clock is used by default. Make this artificially fast for the
+ // simulation. Normally this would be a slow clock and the digital PLL
+ // would be the fast clock.
+
+ always #12.5 clock <= (clock === 1'b0);
+
+ assign clk = clock;
+
+ initial begin
+ clock = 0;
+ wbd_ext_cyc_i ='h0; // strobe/request
+ wbd_ext_stb_i ='h0; // strobe/request
+ wbd_ext_adr_i ='h0; // address
+ wbd_ext_we_i ='h0; // write
+ wbd_ext_dat_i ='h0; // data output
+ wbd_ext_sel_i ='h0; // byte enable
+ end
+
+ `ifdef WFDUMP
+ initial begin
+ $dumpfile("simx.vcd");
+ $dumpvars(2, user_risc_regress_tb);
+ $dumpvars(3, user_risc_regress_tb.u_top.u_sdram_ctrl);
+ $dumpvars(4, user_risc_regress_tb.u_top.u_riscv_top);
+ end
+ `endif
+
+ integer i;
+
+ always @reinit_event
+ begin
+ // Initialize the SPI memory with hex content
+ // Wait for reset removal
+ wait (rst_n == 1);
+
+ // Initialize the SPI memory with hex content
+ $write("\033[0;34m---Initializing the SPI Memory with Hexfile: %s\033[0m\n", test_file);
+ $readmemh(test_file,u_spi_flash_256mb.Mem);
+
+ // some of the RISCV test need SRAM area for specific
+ // instruction execution like fence
+ $sformat(test_ram_file, "%s.ram",test_file);
+ //--------------------------------------------------------------
+ // SDRAM Bank are 512Byte, But Risc compliance test has
+ // more than 512byte of init data, so we are locally copying
+ // it temp memory and then spliting into two banks
+ // --------------------------------------------------------------
+ $readmemh(test_ram_file,tem_mem);
+ $writememh("sdram_bank0.hex",tem_mem,0,511);
+ $writememh("sdram_bank1.hex",tem_mem,512,1023);
+ $writememh("sdram_bank2.hex",tem_mem,1024,1535);
+ $writememh("sdram_bank3.hex",tem_mem,1536,2047);
+ $readmemh("sdram_bank0.hex",u_sdram8.Bank0,0,511);
+ $readmemh("sdram_bank1.hex",u_sdram8.Bank1,0,511);
+ $readmemh("sdram_bank2.hex",u_sdram8.Bank2,0,511);
+ $readmemh("sdram_bank3.hex",u_sdram8.Bank3,0,511);
+ //for(i =32'h00; i < 32'h100; i = i+1)
+ // $display("Location: %x, Data: %x", i, u_sdram8.Bank0[i]);
+
+ #200;
+ repeat (10) @(posedge clock);
+ $display("Monitor: Core reset removal");
+
+ // Remove Wb Reset
+ wb_user_core_write('h3080_0000,'h1);
+ repeat (2) @(posedge clock);
+ #1;
+ //------------ fuse_mhartid= 0x00
+ wb_user_core_write('h3000_0004,'h0);
+
+ repeat (2) @(posedge clock);
+ #1;
+ //------------ SDRAM Config - 2
+ wb_user_core_write('h3000_0014,'h100_019E);
+
+ repeat (2) @(posedge clock);
+ #1;
+ //------------ SDRAM Config - 1
+ wb_user_core_write('h3000_0010,'h2F17_2246);
+
+ repeat (2) @(posedge clock);
+ #1;
+ // Remove all the reset
+ wb_user_core_write('h3080_0000,'hF);
+
+ end
+
+wire USER_VDD1V8 = 1'b1;
+wire VSS = 1'b0;
+
+//-------------------------------------------------------------------------------
+// Run tests
+//-------------------------------------------------------------------------------
+
+`include "riscv_runtests.sv"
+
+
+//-------------------------------------------------------------------------------
+// Core instance
+//-------------------------------------------------------------------------------
+
+user_project_wrapper u_top(
+`ifdef USE_POWER_PINS
+ .vccd1(USER_VDD1V8), // User area 1 1.8V supply
+ .vssd1(VSS), // User area 1 digital ground
+`endif
+ .wb_clk_i (clock), // System clock
+ .user_clock2 (1'b1), // Real-time clock
+ .wb_rst_i (wb_rst_i), // Regular Reset signal
+
+ .wbs_cyc_i (wbd_ext_cyc_i), // strobe/request
+ .wbs_stb_i (wbd_ext_stb_i), // strobe/request
+ .wbs_adr_i (wbd_ext_adr_i), // address
+ .wbs_we_i (wbd_ext_we_i), // write
+ .wbs_dat_i (wbd_ext_dat_i), // data output
+ .wbs_sel_i (wbd_ext_sel_i), // byte enable
+
+ .wbs_dat_o (wbd_ext_dat_o), // data input
+ .wbs_ack_o (wbd_ext_ack_o), // acknowlegement
+
+
+ // Logic Analyzer Signals
+ .la_data_in ('0) ,
+ .la_data_out (),
+ .la_oenb ('0),
+
+
+ // IOs
+ .io_in (io_in) ,
+ .io_out (io_out) ,
+ .io_oeb (io_oeb) ,
+
+ .user_irq ()
+
+);
+
+
+logic [15:0] riscv_dmem_req_cnt; // cnt dmem req
+initial
+begin
+ riscv_dmem_req_cnt = 0;
+end
+
+always @(posedge u_top.wbd_riscv_dmem_stb_i)
+begin
+ riscv_dmem_req_cnt = riscv_dmem_req_cnt+1;
+end
+
+
+`ifndef GL // Drive Power for Hold Fix Buf
+ // All standard cell need power hook-up for functionality work
+ initial begin
+ force u_top.u_spi_master.u_delay1_sdio0.VPWR =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay1_sdio0.VPB =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay1_sdio0.VGND =VSS;
+ force u_top.u_spi_master.u_delay1_sdio0.VNB = VSS;
+ force u_top.u_spi_master.u_delay2_sdio0.VPWR =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay2_sdio0.VPB =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay2_sdio0.VGND =VSS;
+ force u_top.u_spi_master.u_delay2_sdio0.VNB = VSS;
+ force u_top.u_spi_master.u_buf_sdio0.VPWR =USER_VDD1V8;
+ force u_top.u_spi_master.u_buf_sdio0.VPB =USER_VDD1V8;
+ force u_top.u_spi_master.u_buf_sdio0.VGND =VSS;
+ force u_top.u_spi_master.u_buf_sdio0.VNB =VSS;
+
+ force u_top.u_spi_master.u_delay1_sdio1.VPWR =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay1_sdio1.VPB =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay1_sdio1.VGND =VSS;
+ force u_top.u_spi_master.u_delay1_sdio1.VNB = VSS;
+ force u_top.u_spi_master.u_delay2_sdio1.VPWR =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay2_sdio1.VPB =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay2_sdio1.VGND =VSS;
+ force u_top.u_spi_master.u_delay2_sdio1.VNB = VSS;
+ force u_top.u_spi_master.u_buf_sdio1.VPWR =USER_VDD1V8;
+ force u_top.u_spi_master.u_buf_sdio1.VPB =USER_VDD1V8;
+ force u_top.u_spi_master.u_buf_sdio1.VGND =VSS;
+ force u_top.u_spi_master.u_buf_sdio1.VNB =VSS;
+
+ force u_top.u_spi_master.u_delay1_sdio2.VPWR =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay1_sdio2.VPB =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay1_sdio2.VGND =VSS;
+ force u_top.u_spi_master.u_delay1_sdio2.VNB = VSS;
+ force u_top.u_spi_master.u_delay2_sdio2.VPWR =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay2_sdio2.VPB =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay2_sdio2.VGND =VSS;
+ force u_top.u_spi_master.u_delay2_sdio2.VNB = VSS;
+ force u_top.u_spi_master.u_buf_sdio2.VPWR =USER_VDD1V8;
+ force u_top.u_spi_master.u_buf_sdio2.VPB =USER_VDD1V8;
+ force u_top.u_spi_master.u_buf_sdio2.VGND =VSS;
+ force u_top.u_spi_master.u_buf_sdio2.VNB =VSS;
+
+ force u_top.u_spi_master.u_delay1_sdio3.VPWR =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay1_sdio3.VPB =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay1_sdio3.VGND =VSS;
+ force u_top.u_spi_master.u_delay1_sdio3.VNB = VSS;
+ force u_top.u_spi_master.u_delay2_sdio3.VPWR =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay2_sdio3.VPB =USER_VDD1V8;
+ force u_top.u_spi_master.u_delay2_sdio3.VGND =VSS;
+ force u_top.u_spi_master.u_delay2_sdio3.VNB = VSS;
+ force u_top.u_spi_master.u_buf_sdio3.VPWR =USER_VDD1V8;
+ force u_top.u_spi_master.u_buf_sdio3.VPB =USER_VDD1V8;
+ force u_top.u_spi_master.u_buf_sdio3.VGND =VSS;
+ force u_top.u_spi_master.u_buf_sdio3.VNB =VSS;
+
+ force u_top.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
+ force u_top.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPB =USER_VDD1V8;
+ force u_top.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VGND =VSS;
+ force u_top.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VNB = VSS;
+
+ force u_top.u_wb_host.u_buf_wb_rst.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_wb_rst.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_wb_rst.VGND =VSS;
+ force u_top.u_wb_host.u_buf_wb_rst.VNB = VSS;
+
+ force u_top.u_wb_host.u_buf_cpu_rst.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_cpu_rst.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_cpu_rst.VGND =VSS;
+ force u_top.u_wb_host.u_buf_cpu_rst.VNB = VSS;
+
+ force u_top.u_wb_host.u_buf_spi_rst.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_spi_rst.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_spi_rst.VGND =VSS;
+ force u_top.u_wb_host.u_buf_spi_rst.VNB = VSS;
+
+ force u_top.u_wb_host.u_buf_sdram_rst.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_sdram_rst.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_sdram_rst.VGND =VSS;
+ force u_top.u_wb_host.u_buf_sdram_rst.VNB = VSS;
+
+ force u_top.u_wb_host.u_buf_uart_rst.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_uart_rst.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_uart_rst.VGND =VSS;
+ force u_top.u_wb_host.u_buf_uart_rst.VNB = VSS;
+
+ force u_top.u_wb_host.u_buf_i2cm_rst.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_i2cm_rst.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_i2cm_rst.VGND =VSS;
+ force u_top.u_wb_host.u_buf_i2cm_rst.VNB = VSS;
+
+ force u_top.u_wb_host.u_buf_usb_rst.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_usb_rst.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_usb_rst.VGND =VSS;
+ force u_top.u_wb_host.u_buf_usb_rst.VNB = VSS;
+
+ force u_top.u_wb_host.u_clkbuf_sdram.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_sdram.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_sdram.VGND =VSS;
+ force u_top.u_wb_host.u_clkbuf_sdram.VNB = VSS;
+
+ force u_top.u_wb_host.u_clkbuf_cpu.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_cpu.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_cpu.VGND =VSS;
+ force u_top.u_wb_host.u_clkbuf_cpu.VNB = VSS;
+
+ force u_top.u_wb_host.u_clkbuf_rtc.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_rtc.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_rtc.VGND =VSS;
+ force u_top.u_wb_host.u_clkbuf_rtc.VNB = VSS;
+
+ force u_top.u_wb_host.u_clkbuf_usb.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_usb.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_usb.VGND =VSS;
+ force u_top.u_wb_host.u_clkbuf_usb.VNB = VSS;
+ end
+`endif
+
+//------------------------------------------------------
+// Integrate the Serial flash with qurd support to
+// user core using the gpio pads
+// ----------------------------------------------------
+
+ wire flash_clk = io_out[30];
+ wire flash_csb = io_out[31];
+ // Creating Pad Delay
+ wire #1 io_oeb_32 = io_oeb[32];
+ wire #1 io_oeb_33 = io_oeb[33];
+ wire #1 io_oeb_34 = io_oeb[34];
+ wire #1 io_oeb_35 = io_oeb[35];
+ tri flash_io0 = (io_oeb_32== 1'b0) ? io_out[32] : 1'bz;
+ tri flash_io1 = (io_oeb_33== 1'b0) ? io_out[33] : 1'bz;
+ tri flash_io2 = (io_oeb_34== 1'b0) ? io_out[34] : 1'bz;
+ tri flash_io3 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
+
+ assign io_in[32] = flash_io0;
+ assign io_in[33] = flash_io1;
+ assign io_in[34] = flash_io2;
+ assign io_in[35] = flash_io3;
+
+
+ // Quard flash
+ s25fl256s #(.mem_file_name("add.hex"),
+ .otp_file_name("none"),
+ .TimingModel("S25FL512SAGMFI010_F_30pF"))
+ u_spi_flash_256mb (
+ // Data Inputs/Outputs
+ .SI (flash_io0),
+ .SO (flash_io1),
+ // Controls
+ .SCK (flash_clk),
+ .CSNeg (flash_csb),
+ .WPNeg (flash_io2),
+ .HOLDNeg (flash_io3),
+ .RSTNeg (!wb_rst_i)
+
+ );
+
+
+
+//------------------------------------------------
+// Integrate the SDRAM 8 BIT Memory
+// -----------------------------------------------
+
+wire [7:0] Dq ; // SDRAM Read/Write Data Bus
+wire [0:0] sdr_dqm ; // SDRAM DATA Mask
+wire [1:0] sdr_ba ; // SDRAM Bank Select
+wire [12:0] sdr_addr ; // SDRAM ADRESS
+wire sdr_cs_n ; // chip select
+wire sdr_cke ; // clock gate
+wire sdr_ras_n ; // ras
+wire sdr_cas_n ; // cas
+wire sdr_we_n ; // write enable
+wire sdram_clk ;
+
+assign Dq[7:0] = (io_oeb[7:0] == 8'h0) ? io_out [7:0] : 8'hZZ;
+assign sdr_addr[12:0] = io_out [20:8] ;
+assign sdr_ba[1:0] = io_out [22:21] ;
+assign sdr_dqm[0] = io_out [23] ;
+assign sdr_we_n = io_out [24] ;
+assign sdr_cas_n = io_out [25] ;
+assign sdr_ras_n = io_out [26] ;
+assign sdr_cs_n = io_out [27] ;
+assign sdr_cke = io_out [28] ;
+assign sdram_clk = io_out [29] ;
+assign io_in[29] = sdram_clk;
+assign #(1) io_in[7:0] = Dq;
+
+// to fix the sdram interface timing issue
+wire #(1) sdram_clk_d = sdram_clk;
+
+ // SDRAM 8bit
+mt48lc8m8a2 #(.data_bits(8)) u_sdram8 (
+ .Dq (Dq ) ,
+ .Addr (sdr_addr[11:0] ),
+ .Ba (sdr_ba ),
+ .Clk (sdram_clk_d ),
+ .Cke (sdr_cke ),
+ .Cs_n (sdr_cs_n ),
+ .Ras_n (sdr_ras_n ),
+ .Cas_n (sdr_cas_n ),
+ .We_n (sdr_we_n ),
+ .Dqm (sdr_dqm )
+ );
+
+
+task wb_user_core_write;
+input [31:0] address;
+input [31:0] data;
+begin
+ repeat (1) @(posedge clock);
+ #1;
+ wbd_ext_adr_i =address; // address
+ wbd_ext_we_i ='h1; // write
+ wbd_ext_dat_i =data; // data output
+ wbd_ext_sel_i ='hF; // byte enable
+ wbd_ext_cyc_i ='h1; // strobe/request
+ wbd_ext_stb_i ='h1; // strobe/request
+ wait(wbd_ext_ack_o == 1);
+ repeat (1) @(posedge clock);
+ #1;
+ wbd_ext_cyc_i ='h0; // strobe/request
+ wbd_ext_stb_i ='h0; // strobe/request
+ wbd_ext_adr_i ='h0; // address
+ wbd_ext_we_i ='h0; // write
+ wbd_ext_dat_i ='h0; // data output
+ wbd_ext_sel_i ='h0; // byte enable
+ $display("DEBUG WB USER ACCESS WRITE Address : %x, Data : %x",address,data);
+ repeat (2) @(posedge clock);
+end
+endtask
+
+task wb_user_core_read;
+input [31:0] address;
+output [31:0] data;
+reg [31:0] data;
+begin
+ repeat (1) @(posedge clock);
+ #1;
+ wbd_ext_adr_i =address; // address
+ wbd_ext_we_i ='h0; // write
+ wbd_ext_dat_i ='0; // data output
+ wbd_ext_sel_i ='hF; // byte enable
+ wbd_ext_cyc_i ='h1; // strobe/request
+ wbd_ext_stb_i ='h1; // strobe/request
+ wait(wbd_ext_ack_o == 1);
+ data = wbd_ext_dat_o;
+ repeat (1) @(posedge clock);
+ #1;
+ wbd_ext_cyc_i ='h0; // strobe/request
+ wbd_ext_stb_i ='h0; // strobe/request
+ wbd_ext_adr_i ='h0; // address
+ wbd_ext_we_i ='h0; // write
+ wbd_ext_dat_i ='h0; // data output
+ wbd_ext_sel_i ='h0; // byte enable
+ $display("DEBUG WB USER ACCESS READ Address : %x, Data : %x",address,data);
+ repeat (2) @(posedge clock);
+end
+endtask
+
+`ifdef GL
+
+wire wbd_spi_stb_i = u_top.u_spi_master.wbd_stb_i;
+wire wbd_spi_ack_o = u_top.u_spi_master.wbd_ack_o;
+wire wbd_spi_we_i = u_top.u_spi_master.wbd_we_i;
+wire [31:0] wbd_spi_adr_i = u_top.u_spi_master.wbd_adr_i;
+wire [31:0] wbd_spi_dat_i = u_top.u_spi_master.wbd_dat_i;
+wire [31:0] wbd_spi_dat_o = u_top.u_spi_master.wbd_dat_o;
+wire [3:0] wbd_spi_sel_i = u_top.u_spi_master.wbd_sel_i;
+
+wire wbd_sdram_stb_i = u_top.u_sdram_ctrl.wb_stb_i;
+wire wbd_sdram_ack_o = u_top.u_sdram_ctrl.wb_ack_o;
+wire wbd_sdram_we_i = u_top.u_sdram_ctrl.wb_we_i;
+wire [31:0] wbd_sdram_adr_i = u_top.u_sdram_ctrl.wb_addr_i;
+wire [31:0] wbd_sdram_dat_i = u_top.u_sdram_ctrl.wb_dat_i;
+wire [31:0] wbd_sdram_dat_o = u_top.u_sdram_ctrl.wb_dat_o;
+wire [3:0] wbd_sdram_sel_i = u_top.u_sdram_ctrl.wb_sel_i;
+
+wire wbd_uart_stb_i = u_top.u_uart_i2c_usb.reg_cs;
+wire wbd_uart_ack_o = u_top.u_uart_i2c_usb.reg_ack;
+wire wbd_uart_we_i = u_top.u_uart_i2c_usb.reg_wr;
+wire [7:0] wbd_uart_adr_i = u_top.u_uart_i2c_usb.reg_addr;
+wire [7:0] wbd_uart_dat_i = u_top.u_uart_i2c_usb.reg_wdata;
+wire [7:0] wbd_uart_dat_o = u_top.u_uart_i2c_usb.reg_rdata;
+wire wbd_uart_sel_i = u_top.u_uart_i2c_usb.reg_be;
+
+`endif
+
+/**
+`ifdef GL
+//-----------------------------------------------------------------------------
+// RISC IMEM amd DMEM Monitoring TASK
+//-----------------------------------------------------------------------------
+
+`define RISC_CORE user_uart_tb.u_top.u_core.u_riscv_top
+
+always@(posedge `RISC_CORE.wb_clk) begin
+ if(`RISC_CORE.wbd_imem_ack_i)
+ $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x", `RISC_CORE.wbd_imem_adr_o,`RISC_CORE.wbd_imem_dat_i);
+ if(`RISC_CORE.wbd_dmem_ack_i && `RISC_CORE.wbd_dmem_we_o)
+ $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_o);
+ if(`RISC_CORE.wbd_dmem_ack_i && !`RISC_CORE.wbd_dmem_we_o)
+ $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_i);
+end
+
+`endif
+**/
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/vpi/system/system.c b/verilog/dv/vpi/system/system.c
new file mode 100644
index 0000000..1501a09
--- /dev/null
+++ b/verilog/dv/vpi/system/system.c
@@ -0,0 +1,52 @@
+# include <vpi_user.h>
+
+static int system_compiletf(char*user_data)
+{
+ return 0;
+}
+
+static int system_calltf(char*name)
+{
+ vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
+ vpiHandle argv = vpi_iterate(vpiArgument, callh);
+ vpiHandle arg_handle;
+ s_vpi_value value_s;
+
+
+ /* Check that there are arguments. */
+ if (argv == 0) {
+ vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
+ (int)vpi_get(vpiLineNo, callh));
+ vpi_printf("%s requires two arguments.\n", name);
+ vpip_set_return_value(1);
+ vpi_control(vpiFinish, 1);
+ return 0;
+ }
+
+ /* Check that the first argument is a string. */
+ arg_handle = vpi_scan(argv);
+ vpi_free_object(argv); /* not calling scan until returns null */
+ value_s.format = vpiStringVal; /* read as a string */
+ vpi_get_value(arg_handle, &value_s);
+ vpi_printf("System Cmd: %s\n",value_s.value.str);
+ system(value_s.value.str);
+ return 0;
+}
+
+void system_register()
+{
+ s_vpi_systf_data tf_data;
+
+ tf_data.type = vpiSysTask;
+ tf_data.tfname = "$system";
+ tf_data.calltf = system_calltf;
+ tf_data.compiletf = system_compiletf;
+ tf_data.sizetf = 0;
+ tf_data.user_data = "$system";
+ vpi_register_systf(&tf_data);
+}
+
+void (*vlog_startup_routines[])() = {
+ system_register,
+ 0
+};
diff --git a/verilog/rtl/syntacore/scr1/dependencies/coremark b/verilog/rtl/syntacore/scr1/dependencies/coremark
new file mode 160000
index 0000000..7f420b6
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/dependencies/coremark
@@ -0,0 +1 @@
+Subproject commit 7f420b6bdbff436810ef75381059944e2b0d79e8
diff --git a/verilog/rtl/syntacore/scr1/dependencies/riscv-compliance b/verilog/rtl/syntacore/scr1/dependencies/riscv-compliance
new file mode 160000
index 0000000..9141cf9
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/dependencies/riscv-compliance
@@ -0,0 +1 @@
+Subproject commit 9141cf9274b610d059199e8aa2e21f54a0bc6a6e
diff --git a/verilog/rtl/syntacore/scr1/dependencies/riscv-tests b/verilog/rtl/syntacore/scr1/dependencies/riscv-tests
new file mode 160000
index 0000000..e30978a
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/dependencies/riscv-tests
@@ -0,0 +1 @@
+Subproject commit e30978a71921159aec38eeefd848fca4ed39a826
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/coremark/Makefile b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/coremark/Makefile
new file mode 100644
index 0000000..90ba866
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/coremark/Makefile
@@ -0,0 +1,24 @@
+src_dir := $(dir $(lastword $(MAKEFILE_LIST)))
+depend_dir := $(src_dir)/../../../dependencies/coremark
+
+ifeq ("$(ITERATIONS)","")
+ITERATIONS=1
+endif
+
+ADD_CFLAGS += -DITERATIONS=$(ITERATIONS)
+ADD_VPATH := $(depend_dir)
+ADD_incs := -I$(src_dir)/src -I$(depend_dir)
+
+c_src := core_portme.c sc_print.c
+coremark_src := ./src/core_list_join.c ./src/core_matrix.c ./src/core_main.c ./src/core_util.c ./src/core_state.c
+c_src += core_list_join.c core_matrix.c core_main.c core_util.c core_state.c
+
+include $(inc_dir)/common.mk
+
+default: log_requested_tgt $(bld_dir)/coremark.elf $(bld_dir)/coremark.hex $(bld_dir)/coremark.dump
+
+log_requested_tgt:
+ echo coremark.hex>> $(bld_dir)/test_info
+
+clean:
+ $(RM) $(c_objs) $(asm_objs) $(bld_dir)/coremark.hex $(bld_dir)/coremark.dump
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/coremark/core_portme.c b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/coremark/core_portme.c
new file mode 100644
index 0000000..3c801f7
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/coremark/core_portme.c
@@ -0,0 +1,141 @@
+/*
+ File : core_portme.c
+*/
+/*
+ Author : Shay Gal-On, EEMBC
+ Legal : TODO!
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "coremark.h"
+#include "core_portme.h"
+#include "riscv_csr_encoding.h"
+#include "sc_test.h"
+
+#if VALIDATION_RUN
+ volatile ee_s32 seed1_volatile=0x3415;
+ volatile ee_s32 seed2_volatile=0x3415;
+ volatile ee_s32 seed3_volatile=0x66;
+#endif
+#if PERFORMANCE_RUN
+ volatile ee_s32 seed1_volatile=0x0;
+ volatile ee_s32 seed2_volatile=0x0;
+ volatile ee_s32 seed3_volatile=0x66;
+#endif
+#if PROFILE_RUN
+ volatile ee_s32 seed1_volatile=0x8;
+ volatile ee_s32 seed2_volatile=0x8;
+ volatile ee_s32 seed3_volatile=0x8;
+#endif
+ volatile ee_s32 seed4_volatile=ITERATIONS;
+ volatile ee_s32 seed5_volatile=0;
+
+/* Porting : Timing functions
+ How to capture time and convert to seconds must be ported to whatever is supported by the platform.
+ e.g. Read value from on board RTC, read value from cpu clock cycles performance counter etc.
+ Sample implementation for standard time.h and windows.h definitions included.
+*/
+#if 1
+CORETIMETYPE barebones_clock() {
+ unsigned long n;
+ __asm__ __volatile__ (
+ "rdtime %0"
+ : "=r" (n));
+ return n;
+}
+#define CLOCKS_PER_SEC 10000000
+
+/* Define : TIMER_RES_DIVIDER
+ Divider to trade off timer resolution and total time that can be measured.
+
+ Use lower values to increase resolution, but make sure that overflow does not occur.
+ If there are issues with the return value overflowing, increase this value.
+ */
+/* #define NSECS_PER_SEC CLOCKS_PER_SEC */
+/* #define CORETIMETYPE clock_t */
+#define GETMYTIME(_t) (*_t=barebones_clock())
+#define MYTIMEDIFF(fin,ini) ((fin)-(ini))
+#define TIMER_RES_DIVIDER 1
+#define SAMPLE_TIME_IMPLEMENTATION 1
+#define EE_TICKS_PER_SEC (CLOCKS_PER_SEC / TIMER_RES_DIVIDER)
+#else
+
+#endif
+
+/** Define Host specific (POSIX), or target specific global time variables. */
+static CORETIMETYPE start_time_val, stop_time_val;
+
+/* Function : start_time
+ This function will be called right before starting the timed portion of the benchmark.
+
+ Implementation may be capturing a system timer (as implemented in the example code)
+ or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0.
+*/
+void start_time(void) {
+ GETMYTIME(&start_time_val );
+}
+/* Function : stop_time
+ This function will be called right after ending the timed portion of the benchmark.
+
+ Implementation may be capturing a system timer (as implemented in the example code)
+ or other system parameters - e.g. reading the current value of cpu cycles counter.
+*/
+void stop_time(void) {
+ GETMYTIME(&stop_time_val );
+}
+/* Function : get_time
+ Return an abstract "ticks" number that signifies time on the system.
+
+ Actual value returned may be cpu cycles, milliseconds or any other value,
+ as long as it can be converted to seconds by <time_in_secs>.
+ This methodology is taken to accomodate any hardware or simulated platform.
+ The sample implementation returns millisecs by default,
+ and the resolution is controlled by <TIMER_RES_DIVIDER>
+*/
+CORE_TICKS get_time(void) {
+ CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
+ return elapsed;
+}
+/* Function : time_in_secs
+ Convert the value returned by get_time to seconds.
+
+ The <secs_ret> type is used to accomodate systems with no support for floating point.
+ Default implementation implemented by the EE_TICKS_PER_SEC macro above.
+*/
+secs_ret time_in_secs(CORE_TICKS ticks) {
+ secs_ret retval=((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
+ return retval;
+}
+
+ee_u32 default_num_contexts=1;
+
+/* Function : portable_init
+ Target specific initialization code
+ Test for some common mistakes.
+*/
+void portable_init(core_portable *p, int *argc, char *argv[])
+{
+ ee_printf("CoreMark 1.0\n");
+ if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) {
+ ee_printf("ERROR! Please define ee_ptr_int to a type that holds a pointer! (%u != %u)\n", sizeof(ee_ptr_int), sizeof(ee_u8 *));
+ }
+ if (sizeof(ee_u32) != 4) {
+ ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type! (%u)\n", sizeof(ee_u32));
+ }
+ p->portable_id=1;
+}
+/* Function : portable_fini
+ Target specific final code
+*/
+void portable_fini(core_portable *p)
+{
+ p->portable_id=0;
+
+ report_results(0, 0, 0, 0, 0);
+
+ /* results[0].iterations * 10000000/(total_time) */
+
+ /* extern void tohost_exit(long code); */
+
+ /* tohost_exit(0); */
+}
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/coremark/core_portme.h b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/coremark/core_portme.h
new file mode 100644
index 0000000..857930f
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/coremark/core_portme.h
@@ -0,0 +1,210 @@
+/* File : core_portme.h */
+
+/*
+ Author : Shay Gal-On, EEMBC
+ Legal : TODO!
+*/
+/* Topic : Description
+ This file contains configuration constants required to execute on different platforms
+*/
+#ifndef CORE_PORTME_H
+#define CORE_PORTME_H
+/************************/
+/* Data types and settings */
+/************************/
+/* Configuration : HAS_FLOAT
+ Define to 1 if the platform supports floating point.
+*/
+#ifndef HAS_FLOAT
+#define HAS_FLOAT 0
+#endif
+/* Configuration : HAS_TIME_H
+ Define to 1 if platform has the time.h header file,
+ and implementation of functions thereof.
+*/
+#ifndef HAS_TIME_H
+#define HAS_TIME_H 0
+#endif
+/* Configuration : USE_CLOCK
+ Define to 1 if platform has the time.h header file,
+ and implementation of functions thereof.
+*/
+#ifndef USE_CLOCK
+#define USE_CLOCK 0
+#endif
+/* Configuration : HAS_STDIO
+ Define to 1 if the platform has stdio.h.
+*/
+#ifndef HAS_STDIO
+#define HAS_STDIO 1
+#endif
+/* Configuration : HAS_PRINTF
+ Define to 1 if the platform has stdio.h and implements the printf function.
+*/
+#ifndef HAS_PRINTF
+#define HAS_PRINTF 0
+#endif
+
+#include "sc_print.h"
+#define ee_printf sc_printf
+
+/* static inline int ee_printf(const char *fmt, ...) {} */
+
+/* Configuration : CORE_TICKS
+ Define type of return from the timing functions.
+ */
+/* #include <time.h> */
+/* typedef clock_t CORE_TICKS; */
+#include <stdint.h>
+#include <stddef.h>
+#define CORETIMETYPE uint32_t
+typedef uint32_t CORE_TICKS;
+
+/* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION
+ Initialize these strings per platform
+*/
+#ifndef COMPILER_VERSION
+ #ifdef __GNUC__
+ #define COMPILER_VERSION "GCC"__VERSION__
+ #else
+ #define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)"
+ #endif
+#endif
+#ifndef COMPILER_FLAGS
+ #define COMPILER_FLAGS FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */
+#endif
+#ifndef MEM_LOCATION
+ /* #define MEM_LOCATION "STACK" */
+ #define MEM_LOCATION "STATIC"
+#endif
+
+/* Data Types :
+ To avoid compiler issues, define the data types that need ot be used for 8b, 16b and 32b in <core_portme.h>.
+
+ *Imprtant* :
+ ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!!
+*/
+typedef int16_t ee_s16;
+typedef uint16_t ee_u16;
+typedef int32_t ee_s32;
+typedef float ee_f32;
+typedef uint8_t ee_u8;
+typedef uint32_t ee_u32;
+typedef uintptr_t ee_ptr_int;
+typedef size_t ee_size_t;
+/* align_mem :
+ This macro is used to align an offset to point to a 32b value. It is used in the Matrix algorithm to initialize the input memory blocks.
+*/
+#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x) - 1) & ~3))
+
+/* Configuration : SEED_METHOD
+ Defines method to get seed values that cannot be computed at compile time.
+
+ Valid values :
+ SEED_ARG - from command line.
+ SEED_FUNC - from a system function.
+ SEED_VOLATILE - from volatile variables.
+*/
+#ifndef SEED_METHOD
+#define SEED_METHOD SEED_VOLATILE
+#endif
+
+/* Configuration : MEM_METHOD
+ Defines method to get a block of memry.
+
+ Valid values :
+ MEM_MALLOC - for platforms that implement malloc and have malloc.h.
+ MEM_STATIC - to use a static memory array.
+ MEM_STACK - to allocate the data block on the stack (NYI).
+*/
+#ifndef MEM_METHOD
+/* #define MEM_METHOD MEM_STACK */
+#define MEM_METHOD MEM_STATIC
+#endif
+
+/* Configuration : MULTITHREAD
+ Define for parallel execution
+
+ Valid values :
+ 1 - only one context (default).
+ N>1 - will execute N copies in parallel.
+
+ Note :
+ If this flag is defined to more then 1, an implementation for launching parallel contexts must be defined.
+
+ Two sample implementations are provided. Use <USE_PTHREAD> or <USE_FORK> to enable them.
+
+ It is valid to have a different implementation of <core_start_parallel> and <core_end_parallel> in <core_portme.c>,
+ to fit a particular architecture.
+*/
+#ifndef MULTITHREAD
+#define MULTITHREAD 1
+#define USE_PTHREAD 0
+#define USE_FORK 0
+#define USE_SOCKET 0
+#endif
+
+/* Configuration : MAIN_HAS_NOARGC
+ Needed if platform does not support getting arguments to main.
+
+ Valid values :
+ 0 - argc/argv to main is supported
+ 1 - argc/argv to main is not supported
+
+ Note :
+ This flag only matters if MULTITHREAD has been defined to a value greater then 1.
+*/
+#ifndef MAIN_HAS_NOARGC
+#define MAIN_HAS_NOARGC 1
+#endif
+
+/* Configuration : MAIN_HAS_NORETURN
+ Needed if platform does not support returning a value from main.
+
+ Valid values :
+ 0 - main returns an int, and return value will be 0.
+ 1 - platform does not support returning a value from main
+*/
+#ifndef MAIN_HAS_NORETURN
+#define MAIN_HAS_NORETURN 0
+#endif
+
+/* Variable : default_num_contexts
+ Not used for this simple port, must cintain the value 1.
+*/
+extern ee_u32 default_num_contexts;
+
+typedef struct CORE_PORTABLE_S {
+ ee_u8 portable_id;
+} core_portable;
+
+/* target specific init/fini */
+void portable_init(core_portable *p, int *argc, char *argv[]);
+void portable_fini(core_portable *p);
+
+#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN)
+#if (TOTAL_DATA_SIZE==1200)
+#define PROFILE_RUN 1
+#elif (TOTAL_DATA_SIZE==2000)
+#define PERFORMANCE_RUN 1
+#else
+#define VALIDATION_RUN 1
+#endif
+#endif
+
+typedef ee_s16 MATDAT;
+typedef ee_s32 MATRES;
+
+
+ee_u16 crcu8(ee_u8 data, ee_u16 crc ) __attribute__ ((hot));
+ee_u16 crcu16(ee_u16 newval, ee_u16 crc) __attribute__ ((hot));
+ee_u16 crcu32(ee_u32 newval, ee_u16 crc) __attribute__ ((hot));
+ee_u16 crc16(ee_s16 newval, ee_u16 crc) __attribute__ ((hot));
+ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval) __attribute__ ((hot));
+void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val) __attribute__ ((hot));
+void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) __attribute__ ((hot));
+void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) __attribute__ ((hot));
+void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) __attribute__ ((hot));
+void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val) __attribute__ ((hot));
+
+#endif /* CORE_PORTME_H */
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/dhrystone21/Makefile b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/dhrystone21/Makefile
new file mode 100644
index 0000000..7056489
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/dhrystone21/Makefile
@@ -0,0 +1,16 @@
+src_dir := $(dir $(lastword $(MAKEFILE_LIST)))
+
+ADD_FLAGS := -flto
+ADD_CFLAGS := -DSELF_TIMED=1 -DTIME=1
+
+c_src := sc_print.c dhry_1.c dhry_2.c
+
+include $(inc_dir)/common.mk
+
+default: log_requested_tgt $(bld_dir)/dhrystone21.elf $(bld_dir)/dhrystone21.hex $(bld_dir)/dhrystone21.dump
+
+log_requested_tgt:
+ @echo dhrystone21.hex>> $(bld_dir)/test_info
+
+clean:
+ $(RM) $(c_objs) $(asm_objs) $(bld_dir)/dhrystone21.elf $(bld_dir)/dhrystone21.hex $(bld_dir)/dhrystone21.dump
\ No newline at end of file
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/dhrystone21/dhry.h b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/dhrystone21/dhry.h
new file mode 100644
index 0000000..cba0059
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/dhrystone21/dhry.h
@@ -0,0 +1,446 @@
+/*****************************************************************************
+ * The BYTE UNIX Benchmarks - Release 3
+ * Module: dhry.h SID: 3.4 5/15/91 19:30:21
+ *
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ * Ben Smith, Rick Grehan or Tom Yager
+ * ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
+ *
+ *****************************************************************************
+ * Modification Log:
+ * addapted from:
+ *
+ *
+ * "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, AUT E 51
+ * Postfach 3220
+ * 8520 Erlangen
+ * Germany (West)
+ * Phone: [+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) 834-1378 (9-17 EST)
+ * Usenet: ...!seismo!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 as implicit parameters).
+ *
+ *
+ * 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
+#define TIMES
+#endif
+ /* Use times(2) time function unless */
+ /* explicitly defined otherwise */
+
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+ /* for "times" */
+#endif
+
+#define Mic_secs_Per_Second 1000000
+ /* 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>
+#include <string.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;
+
+#include "sc_print.h"
+#include "csr.h"
+
+# define printf sc_printf
+
+#define HZ 1000000
+static long time(long *x)
+{
+ return rdcycle();
+}
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/dhrystone21/dhry_1.c b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/dhrystone21/dhry_1.c
new file mode 100644
index 0000000..d52acbb
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/dhrystone21/dhry_1.c
@@ -0,0 +1,461 @@
+/*****************************************************************************
+ * The BYTE UNIX Benchmarks - Release 3
+ * Module: dhry_1.c SID: 3.4 5/15/91 19:30:21
+ *
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ * Ben Smith, Rick Grehan or Tom Yager
+ * ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
+ *
+ *****************************************************************************
+ *
+ * *** WARNING **** With BYTE's modifications applied, results obtained with
+ * ******* this version of the Dhrystone program may not be applicable
+ * to other versions.
+ *
+ * Modification Log:
+ * 10/22/97 - code cleanup to remove ANSI C compiler warnings
+ * Andy Kahn <kahn@zk3.dec.com>
+ *
+ * Adapted from:
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_1.c (part 2 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ ***************************************************************************/
+char SCCSid[] = "@(#) @(#)dhry_1.c:3.4 -- 5/15/91 19:30:21";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "dhry.h"
+//#include "timeit.c"
+
+unsigned long Run_Index;
+/*
+void report()
+{
+ fprintf(stderr,"COUNT|%ld|1|lps\n", Run_Index);
+ exit(0);
+}
+*/
+/* 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;
+/* extern int times (); */
+ /* see library function "times" */
+#define Too_Small_Time 120
+ /* 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
+
+long Begin_Time,
+ End_Time,
+ User_Time;
+#if 0
+float Microseconds,
+ Dhrystones_Per_Second;
+#else
+long Microseconds,
+ Dhrystones_Per_Second;
+#endif
+
+/* end of variables for time measurement */
+
+void Proc_1 (REG Rec_Pointer Ptr_Val_Par);
+void Proc_2 (One_Fifty *Int_Par_Ref);
+void Proc_3 (Rec_Pointer *Ptr_Ref_Par);
+void Proc_4 (void);
+void Proc_5 (void);
+
+
+extern Boolean Func_2(Str_30, Str_30);
+extern void Proc_6(Enumeration, Enumeration *);
+extern void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
+extern void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
+
+int main (argc, argv)
+int argc;
+char *argv[];
+ /* main program, corresponds to procedures */
+ /* Main and Proc_0 in the Ada version */
+{
+#ifdef SELF_TIMED
+ int Number_Of_Runs;
+#else /* SELF_TIMED */
+ int duration;
+#endif /* SELF_TIMED */
+ 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;
+
+ /* Initializations */
+#if 0
+ Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+ Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+#else
+ static Rec_Type glob1, glob2;
+ Next_Ptr_Glob = &glob1;
+ Ptr_Glob = &glob2;
+#endif
+
+ 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. */
+
+#ifdef SELF_TIMED
+ Number_Of_Runs = 500;//500000;
+ if (argc >= 2) {
+ Number_Of_Runs = atoi(argv[1]);
+ }
+ printf ("\n");
+ printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
+ printf ("\n");
+ if (Reg)
+ {
+ printf ("Program compiled with 'register' attribute\n");
+ printf ("\n");
+ }
+ else
+ {
+ printf ("Program compiled without 'register' attribute\n");
+ printf ("\n");
+ }
+#ifdef PRATTLE
+ printf ("Please give the number of runs through the benchmark: ");
+ {
+ int n;
+ scanf ("%d", &n);
+ Number_Of_Runs = n;
+ }
+ printf ("\n");
+#endif /* PRATTLE */
+
+ printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
+
+ Run_Index = 0;
+#else /* SELF_TIMED */
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s duration\n", argv[0]);
+ exit(1);
+ }
+
+ duration = atoi(argv[1]);
+ Run_Index = 0;
+ wake_me(duration, report);
+#endif /* SELF_TIMED */
+
+ /***************/
+ /* Start timer */
+ /***************/
+
+#ifdef SELF_TIMED
+#ifdef TIMES
+ times (&time_info);
+ Begin_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+ Begin_Time = time ( (long *) 0);
+#endif
+#endif /* SELF_TIMED */
+
+#ifdef SELF_TIMED
+ for (Run_Index = 1; Run_Index <= Number_Of_Runs ; ++Run_Index)
+#else /* SELF_TIMED */
+ for (Run_Index = 1; ; ++Run_Index)
+#endif /* SELF_TIMED */
+ {
+
+ 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" */
+
+ /**************/
+ /* Stop timer */
+ /**************/
+#ifdef SELF_TIMED
+#ifdef TIMES
+ times (&time_info);
+ End_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+ End_Time = time ( (long *) 0);
+#endif
+#endif /* SELF_TIMED */
+
+ /* BYTE version never executes this stuff */
+#ifdef SELF_TIMED
+ printf ("Execution ends\n");
+ printf ("\n");
+ printf ("Final values of the variables used in the benchmark:\n");
+ printf ("\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->\n");
+ printf (" Ptr_Comp: %d\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\n", Ptr_Glob->variant.var_1.Str_Comp);
+ printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
+ printf ("Next_Ptr_Glob->\n");
+ printf (" Ptr_Comp: %d\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\n",
+ 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\n", Str_1_Loc);
+ printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
+ printf ("Str_2_Loc: %s\n", 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 ("Measured time too small to obtain meaningful results\n");
+ printf ("Please increase number of runs\n");
+ printf ("\n");
+ }
+ else
+ {
+#if 0
+#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
+#else
+ Microseconds = ((User_Time / Number_Of_Runs) * Mic_secs_Per_Second) / HZ;
+ Dhrystones_Per_Second = (HZ * Number_Of_Runs) / User_Time;
+
+ sc_printf("Number_Of_Runs= %ld, HZ= %ld\n", Number_Of_Runs, HZ);
+ sc_printf("Time: begin= %ld, end= %ld, diff= %ld\n", Begin_Time, End_Time, User_Time);
+ sc_printf("Microseconds for one run through Dhrystone: %ld\n", Microseconds);
+ sc_printf("Dhrystones per Second: %ld\n", Dhrystones_Per_Second);
+
+#endif
+ }
+#endif /* SELF_TIMED */
+}
+
+
+void Proc_1 (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 (One_Fifty *Int_Par_Ref)
+ /* executed once */
+ /* *Int_Par_Ref == 1, becomes 4 */
+{
+ One_Fifty Int_Loc;
+ Enumeration Enum_Loc;
+
+ Enum_Loc = 0;
+
+ 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 (Rec_Pointer *Ptr_Ref_Par)
+ /* executed once */
+ /* Ptr_Ref_Par becomes Ptr_Glob */
+{
+ 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 (void) /* 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 (void) /* 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
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/dhrystone21/dhry_2.c b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/dhrystone21/dhry_2.c
new file mode 100644
index 0000000..140161f
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/benchmarks/dhrystone21/dhry_2.c
@@ -0,0 +1,209 @@
+/*****************************************************************************
+ * The BYTE UNIX Benchmarks - Release 3
+ * Module: dhry_2.c SID: 3.4 5/15/91 19:30:22
+ *
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ * Ben Smith, Rick Grehan or Tom Yager
+ * ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
+ *
+ *****************************************************************************
+ * Modification Log:
+ * 10/22/97 - code cleanup to remove ANSI C compiler warnings
+ * Andy Kahn <kahn@zk3.dec.com>
+ *
+ * Adapted from:
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * **** WARNING **** See warning in n.dhry_1.c
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_2.c (part 3 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ ****************************************************************************/
+/* SCCSid is defined in dhry_1.c */
+
+#include <string.h>
+#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;
+
+void Proc_6(Enumeration, Enumeration *);
+void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
+void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
+Enumeration Func_1(Capital_Letter, Capital_Letter);
+Boolean Func_2(Str_30, Str_30);
+Boolean Func_3(Enumeration);
+
+void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
+ /* executed once */
+ /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
+{
+ *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)
+One_Fifty Int_1_Par_Val;
+One_Fifty Int_2_Par_Val;
+One_Fifty *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_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 (Capital_Letter Ch_1_Par_Val, Capital_Letter 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_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;
+
+ Ch_Loc = 'A';
+ 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 */
+
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/common.mk b/verilog/rtl/syntacore/scr1/sim/tests/common/common.mk
index b9c0e03..8a1d054 100644
--- a/verilog/rtl/syntacore/scr1/sim/tests/common/common.mk
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/common.mk
@@ -56,7 +56,8 @@
$(RISCV_GCC) -o $@ -T $^ $(LDFLAGS)
$(bld_dir)/%.hex: $(bld_dir)/%.elf
- $(RISCV_OBJCOPY) $^ $@
+ $(RISCV_ROM_OBJCOPY) $^ $@
+ $(RISCV_RAM_OBJCOPY) $^ $@.ram
$(bld_dir)/%.dump: $(bld_dir)/%.elf
$(RISCV_OBJDUMP) $^ > $@
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/link.ld b/verilog/rtl/syntacore/scr1/sim/tests/common/link.ld
index 790e858..31653f1 100644
--- a/verilog/rtl/syntacore/scr1/sim/tests/common/link.ld
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/link.ld
@@ -1,3 +1,4 @@
+/*
//////////////////////////////////////////////////////////////////////////////
// SPDX-FileCopyrightText: Syntacore LLC © 2016-2021
//
@@ -15,7 +16,9 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileContributor: Syntacore LLC
// //////////////////////////////////////////////////////////////////////////
+**/
/*
+* Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details
* @file <link.ld>
* @brief bare metal tests' linker script
*/
@@ -24,7 +27,8 @@
ENTRY(_start)
MEMORY {
- RAM (rwx) : ORIGIN = 0x0, LENGTH = 64K
+ ROM (rxx) : ORIGIN = 0x0, LENGTH = 64K
+ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
}
STACK_SIZE = 1024;
@@ -45,7 +49,7 @@
. = 0x100;
PROVIDE(__TEXT_START__ = .);
*(.text.init)
- } >RAM
+ } >ROM
.text : {
*crt.o(.text .text.*)
@@ -53,7 +57,7 @@
*(sc_test_section)
. = ALIGN(CL_SIZE);
PROVIDE(__TEXT_END__ = .);
- } >RAM
+ } >ROM
/* data segment */
.data : {
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/link_tcm.ld b/verilog/rtl/syntacore/scr1/sim/tests/common/link_tcm.ld
index 1580b36..d907410 100644
--- a/verilog/rtl/syntacore/scr1/sim/tests/common/link_tcm.ld
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/link_tcm.ld
@@ -26,8 +26,9 @@
ENTRY(_start)
MEMORY {
- RAM (rwx) : ORIGIN = 0x0, LENGTH = 64K
- TCM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
+ ROM (rxx) : ORIGIN = 0x0, LENGTH = 64K
+ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
+ TCM (rwx) : ORIGIN = 0x20010000, LENGTH = 64K
}
STACK_SIZE = 1024;
@@ -37,7 +38,7 @@
SECTIONS {
/* code segment */
- .text.init ORIGIN(RAM) : {
+ .text.init ORIGIN(ROM) : {
FILL(0);
. = 0x100 - 12;
SIM_EXIT = .;
@@ -49,7 +50,7 @@
*crt_tcm.o(.text .text.*)
*(.text.init)
. = ALIGN(CL_SIZE);
- } >RAM
+ } >ROM
__reloc_start = .;
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/hello/Makefile b/verilog/rtl/syntacore/scr1/sim/tests/hello/Makefile
new file mode 100644
index 0000000..0f55d60
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/hello/Makefile
@@ -0,0 +1,13 @@
+src_dir := $(dir $(lastword $(MAKEFILE_LIST)))
+
+c_src := sc_print.c hello.c
+
+include $(inc_dir)/common.mk
+
+default: log_requested_tgt $(bld_dir)/hello.elf $(bld_dir)/hello.hex $(bld_dir)/hello.dump
+
+log_requested_tgt:
+ echo hello.hex>> $(bld_dir)/test_info
+
+clean:
+ $(RM) $(c_objs) $(asm_objs) $(bld_dir)/hello.elf $(bld_dir)/hello.hex $(bld_dir)/hello.dump
\ No newline at end of file
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/hello/hello.c b/verilog/rtl/syntacore/scr1/sim/tests/hello/hello.c
new file mode 100644
index 0000000..52cf1bc
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/hello/hello.c
@@ -0,0 +1,7 @@
+#include "sc_print.h"
+
+int main()
+{
+ sc_printf("Hello from SCR1!\n");
+ return 0;
+}
\ No newline at end of file
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/isr_sample/Makefile b/verilog/rtl/syntacore/scr1/sim/tests/isr_sample/Makefile
new file mode 100644
index 0000000..1c95e74
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/isr_sample/Makefile
@@ -0,0 +1,26 @@
+src_dir := $(dir $(lastword $(MAKEFILE_LIST)))
+
+LDFLAGS := -nostartfiles -nostdlib -march=rv32$(ARCH) -mabi=$(ABI)
+ADD_ASM_MACRO := -DASM
+
+ifeq ($(IPIC) ,1)
+ ADD_ASM_MACRO += -DIPIC_ENABLED
+endif
+
+ifeq ($(VECT_IRQ) ,1)
+ ADD_ASM_MACRO += -DVECT_IRQ_ENABLED
+endif
+asm_src := isr_sample.S
+
+# override ld script
+ld_script := $(inc_dir)/link.ld
+
+include $(inc_dir)/common.mk
+
+default: log_requested_tgt $(bld_dir)/isr_sample.elf $(bld_dir)/isr_sample.hex $(bld_dir)/isr_sample.dump
+
+log_requested_tgt:
+ echo isr_sample.hex >> $(bld_dir)/test_info
+
+clean:
+ $(RM)$(asm_objs) $(bld_dir)/isr_sample.elf $(bld_dir)/isr_sample.hex $(bld_dir)/isr_sample.dump
\ No newline at end of file
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/isr_sample/isr_sample.S b/verilog/rtl/syntacore/scr1/sim/tests/isr_sample/isr_sample.S
new file mode 100644
index 0000000..6855370
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/isr_sample/isr_sample.S
@@ -0,0 +1,291 @@
+#include "riscv_macros.h"
+#include "sc_test.h"
+
+.altmacro
+// global interrupt bit
+#define MSIE (1 << IRQ_M_SOFT) //machine software interrupt enable
+#define MTIE (1 << IRQ_M_TIMER) //machine timer interrupt enable
+#define MEIE (1 << IRQ_M_EXT) //machine external interrupt enable
+#define MCAUSE_EXT_IRQ (1 << 31 | IRQ_M_EXT)
+#define MCAUSE_SOFT_IRQ (1 << 31 | IRQ_M_SOFT)
+#define MCAUSE_TMR_IRQ (1 << 31 | IRQ_M_TIMER)
+
+// IPIC
+#define IRQ_LINES_ADDR 0xF0000100 // simulation
+#define TRIG_EXT_IRQ_ADDR 0xF0000100 // external irq is triggered when tb memory is set to non-zero
+#define TRIG_SW_IRQ_ADDR 0xF0000200 // software irq is triggered when tb memory is set to non-zero
+
+#define IPIC_EOI 0xBF4 // end of interrupt
+#define IPIC_SOI 0xBF5 // start of interrupt
+#define IPIC_IDX 0xBF6 // index register
+#define IPIC_ICSR 0xBF7 // interrupt control status register
+
+// IPIC Interrupt Constrol Status Register
+#define IPIC_ICSR_IP (1 << 0) // interrupt pending
+#define IPIC_ICSR_IE (1 << 1) // interrupt enable
+#define IPIC_ICSR_IM (1 << 2) // interrupt mode (0/1: level/edge)
+#define IPIC_ICSR_INV (1 << 3) // line inversion
+#define IPIC_ICSR_IS (1 << 4) // in service
+
+// Interrupt lines in use
+#define IPIC_IRQ_LINE9 9
+#define EXT_IRQ_LINE_COMMON 0
+
+#include "timer.h"
+#include "reloc.h"
+
+.macro jmp_sc_exit
+ la t0, sc_exit
+ jr t0
+.endm
+
+ .section .text.init
+ .option norvc
+ .globl _start
+// -----------------------------------------------------------------
+// Trap handlers
+// 0xXXXXXX00
+ .option norvc
+.org (64*3)
+
+//0xXXXXXXC0
+ .balign 64
+machine_trap_entry:
+vec_usr_soft:
+#ifdef VECT_IRQ_ENABLED
+ trap_entry:
+ j _trap_fail
+ vec_supervisor_soft:
+ j _trap_fail
+ vec_reserved1:
+ j _trap_fail
+ vec_machine_soft:
+ j vec_machine_soft_handler
+ vec_usr_tmr:
+ j _trap_fail
+ vec_supervisor_tmr:
+ j _trap_fail
+ vec_reserved2:
+ j _trap_fail
+ vec_machine_tmr:
+ j vec_machine_tmr_handler
+ vec_usr_ext:
+ j _trap_fail
+ vec_supervisor_ext:
+ j _trap_fail
+ vec_reserved3:
+ j _trap_fail
+ vec_machine_ext:
+ j vec_machine_ext_handler
+ vec_reserved4:
+ j _trap_fail
+ j _trap_fail
+ j _trap_fail
+ j _trap_fail
+#else
+ trap_entry:
+ j direct_irq_handler
+ vec_supervisor_soft:
+ j _trap_fail
+ vec_reserved1:
+ j _trap_fail
+ vec_machine_soft:
+ j _trap_fail
+ vec_usr_tmr:
+ j _trap_fail
+ vec_supervisor_tmr:
+ j _trap_fail
+ vec_reserved2:
+ j _trap_fail
+ vec_machine_tmr:
+ j _trap_fail
+ vec_usr_ext:
+ j _trap_fail
+ vec_supervisor_ext:
+ j _trap_fail
+ vec_reserved3:
+ j _trap_fail
+ vec_machine_ext:
+ j _trap_fail
+ vec_reserved4:
+ j _trap_fail
+ j _trap_fail
+ j _trap_fail
+ j _trap_fail
+
+#endif // ifdef VECT_IRQ_ENABLED
+
+
+ .balign 64
+_start:
+ la t0, machine_trap_entry
+ csrw mtvec, t0
+
+ la t0, test_start
+ jr (t0)
+
+// -----------------------------------------------------------------
+ .option norvc
+ .balign 64
+test_start:
+
+ la t0, trap_entry
+ csrw mtvec, t0 // set mtvec to trap_entry
+ #ifdef VECT_IRQ_ENABLED
+ csrsi mtvec, 1 // set vectored mode
+ #else
+ csrsi mtvec, 0 // set direct mode
+ #endif
+
+ /// configuring timer interrupt ///
+ _reset_mtimecmp; // reset timer
+ _run_timer; // run timer
+ csrs mstatus, MSTATUS_MIE // enable global interrupt
+ li a0, MTIE
+ csrs mie, a0 // enable timer interrupt
+ li t2, 0 // reset timer counter = 0 (updated in isr)
+ _read_mtime s1 // read timer value
+ addi s1, s1, 256
+ _write_mtimecmp_32 s1
+ wfi
+
+
+ /// configuring external interrupt ///
+ csrw mie, zero // disable all interrupts
+ li t0, IRQ_LINES_ADDR
+ sh zero, (t0) // set all exterinal interrupt lines low
+ #ifdef IPIC_ENABLED
+ li t0, IPIC_IRQ_LINE9
+ csrw IPIC_IDX, t0 // set IPIC to expect interupt on line 9...
+ li t0, (IPIC_ICSR_IE | IPIC_ICSR_IM)
+ csrw IPIC_ICSR, t0 // ....enable interrupt,set edge interrupt mode
+ #endif
+ li t0, MEIE
+ csrs mie, t0 // enable external interrupt
+ li t0, TRIG_EXT_IRQ_ADDR
+ #ifdef IPIC_ENABLED
+ li t1, (1 << IPIC_IRQ_LINE9)
+ #else
+ li t1, (1 << EXT_IRQ_LINE_COMMON)
+ #endif
+ sh t1, (t0) //send command to generate external interrupt on line 9 to testbench
+ nop
+ nop
+ nop
+ nop //wait for external interrupt
+
+
+ /// configuring software interrupt ///
+ csrw mie, zero // disable all interrupts
+ li t0, TRIG_SW_IRQ_ADDR
+ li t1, 0x00000001
+ sh t1, (t0) //send command to generate software interrupt
+ li t0, MSIE
+ csrs mie, t0 // enable software interrupt
+ nop
+ nop
+ nop
+ nop //wait for software interrupt
+
+ li s1, 3
+ li a0, 0
+ beq t2, s1, 1f
+ li a0, -1
+1:
+ jmp_sc_exit
+
+
+#ifndef VECT_IRQ_ENABLED
+
+direct_irq_handler:
+ csrr a1, mcause
+ li a5, MCAUSE_TMR_IRQ //0x80000007 -- mcause = tmr.irq
+ beq a1, a5, vec_machine_tmr_handler
+ li a5, MCAUSE_SOFT_IRQ //0x80000003 -- mcause = soft.irq
+ beq a1, a5, vec_machine_soft_handler
+ li a5, MCAUSE_EXT_IRQ //0x8000000B -- mcause = ext.irq
+ beq a1, a5, vec_machine_ext_handler
+ mret
+#endif
+
+vec_machine_tmr_handler:
+ csrr a1, mcause
+ li a5, MCAUSE_TMR_IRQ //0x80000007 -- mcause = tmr.irq
+ li a0, -1
+ bne a1, a5, check_fail
+ csrr t1, mip
+ li t0, MIP_MTIP
+ and t0, t1, t0
+ beqz t0, check_fail
+#ifdef IPIC_ENABLED
+ csrw IPIC_SOI, zero
+ csrw IPIC_EOI, zero
+#endif
+ _reset_mtimecmp
+ csrr t1, mip
+ andi t1, t1, MIP_MTIP
+ bne t1, zero, check_fail
+ addi t2, t2, 1 // tmr irq counter update
+ mret
+
+vec_machine_ext_handler:
+
+ csrr a1, mcause
+ li a5, MCAUSE_EXT_IRQ //0x8000000B -- mcause = ext.irq
+ li a0, -1
+ bne a1, a5, check_fail
+ csrr t1, mip
+ li t0, MIP_MEIP
+ and t0, t1, t0
+ beqz t0, check_fail
+#ifdef IPIC_ENABLED
+ csrw IPIC_SOI, zero
+ csrw IPIC_EOI, zero
+#endif
+ li t0, MEIE
+ csrc mie, t0 // disable software interrupt
+
+ li t0, TRIG_EXT_IRQ_ADDR
+ li t1, EXT_IRQ_LINE_COMMON
+ sh t1, (t0) // send command to disable external interrupt
+
+ csrr t1, mip
+ li t0, MIP_MEIP
+ bne t1, zero, check_fail
+ addi t2, t2, 1 // ext irq counter update
+ mret
+
+vec_machine_soft_handler:
+ csrr a1, mcause
+ li a5, MCAUSE_SOFT_IRQ //0x80000003 -- mcause = soft.irq
+ li a0, -1
+ bne a1, a5, check_fail
+ csrr t1, mip
+ li t0, MIP_MSIP
+ and t0, t1, t0
+ beqz t0, check_fail
+ #ifdef IPIC_ENABLED
+ csrw IPIC_SOI, zero
+ csrw IPIC_EOI, zero
+ #endif
+ li t0, MSIE
+ csrc mie, t0 // disable software interrupt
+ li t0, TRIG_SW_IRQ_ADDR
+ li t1, 0x00000000
+ sh t1, (t0) // send command to stop generating software interrupt
+ li t0, MIP_MSIP
+ csrc mip, t0
+ csrr t1, mip
+ li t0, MIP_MSIP
+ and t1, t1, t0
+ bne t1, zero, check_fail
+ addi t2, t2, 1 // ext irq counter update
+ mret
+
+check_fail:
+ la t0, sc_exit
+ jr t0
+
+_trap_fail:
+ li a0, -1
+ j check_fail
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/isr_sample/timer.h b/verilog/rtl/syntacore/scr1/sim/tests/isr_sample/timer.h
new file mode 100644
index 0000000..b81bcc8
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/isr_sample/timer.h
@@ -0,0 +1,97 @@
+#ifndef __TIMER__H
+#define __TIMER__H
+
+
+
+#define MEM_MTIME_MASK 0xF0000000
+#define MEM_MTIME_CTRL 0x00490000
+#define MEM_MTIME_DIV 0x00490004
+#define MEM_MTIME 0x00490008
+#define MEM_MTIMEH 0x0049000C
+#define MEM_MTIMECMP 0x00490010
+#define MEM_MTIMECMPH 0x00490014
+
+#define TMP t0
+#define TMP2 t1
+#define TMP3 t2
+
+// Reset
+.macro _reset_mtime
+ li TMP, MEM_MTIME
+ sw zero, 0(TMP)
+ sw zero, 4(TMP)
+.endm
+
+.macro _reset_mtimecmp
+ li TMP, MEM_MTIMECMP
+ not TMP2, zero
+ sw TMP2, 0(TMP)
+ sw TMP2, 4(TMP)
+.endm
+
+// Write
+.macro _write_mtime_ctrl reg
+ li TMP, MEM_MTIME_CTRL
+ sw \reg, 0(TMP)
+.endm
+
+.macro _write_mtime_div reg
+ li TMP, MEM_MTIME_DIV
+ sw \reg, 0(TMP)
+.endm
+
+.macro _write_mtimecmp_32 reg
+ li TMP, MEM_MTIMECMP
+ li TMP2, -1
+ sw TMP2, 0(TMP)
+ sw zero, 4(TMP)
+ sw \reg, 0(TMP)
+.endm
+
+.macro _write_mtime reg
+ li TMP, MEM_MTIME
+ sw \reg, 0(TMP)
+.endm
+
+.macro _read_mtime reg
+ li TMP, MEM_MTIME
+ lw \reg, 0(TMP)
+.endm
+
+// Read
+.macro _read_mtimecmp reg
+ li TMP, MEM_MTIMECMP
+ lw \reg, 0(TMP)
+.endm
+
+.macro _read_mtime_ctrl reg
+ li TMP, MEM_MTIME_CTRL
+ lw \reg, 0(TMP)
+.endm
+
+.macro _read_mtime_div reg
+ li TMP, MEM_MTIME_DIV
+ lw \reg, 0(TMP)
+.endm
+
+// Misc
+.macro _run_timer
+ li TMP, MEM_MTIME_CTRL
+ lw TMP2, 0(TMP)
+ li TMP3, (1 << SCR1_MTIME_CTRL_EN)
+ or TMP2, TMP2, TMP3
+ sw TMP2, 0(TMP)
+.endm
+
+.macro _stop_timer
+ li TMP, MEM_MTIME_CTRL
+ lw TMP2, 0(TMP)
+ li TMP3, (1 << SCR1_MTIME_CTRL_EN)
+ not TMP3, TMP3
+ and TMP2, TMP2, TMP3
+ sw TMP2, 0(TMP)
+.endm
+
+
+
+#endif // #ifndef __TIMER__H
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/Makefile b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/Makefile
new file mode 100644
index 0000000..d2b210b
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/Makefile
@@ -0,0 +1,202 @@
+## @file
+## Syntacore SCR* tests
+##
+## @copyright 2015-2018 Syntacore. All rights reserved.
+## RISCV-Compliance
+##
+
+ARCH ?=im
+override ARCH:=rv32$(ARCH)
+
+src_dir := $(CURDIR)
+RISCV_COMPLIANCE_TESTS := $(src_dir)/../../../dependencies/riscv-compliance/
+
+#I IM IMC IC
+#EM EMC EC
+
+ifeq (rv32e,$(findstring rv32e,$(ARCH)))
+ $(info >>> RV32E - no compliance tests)
+else ## ifdef SCR_BASE_RVE_EXT
+ #ifeq (rv32i,$(findstring rv32i,$(ARCH)))
+ ifeq ($(ARCH),$(filter $(ARCH),rv32i rv32im rv32imc rv32ic))
+ $(info >>> I32 TESTS)
+ included_i += $(filter %.S,\
+ $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32i/src/*))
+ included_i += $(filter %.S,\
+ $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32Zicsr/src/*))
+ included_i += $(filter %.S,\
+ $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32Zifencei/src/*))
+ compliance_set += $(included_i)
+ endif
+
+ #$(if or ifeq(rv32im,$(findstring rv32im,$(ARCH))), (rv32imc,$(findstring rv32imc,$(ARCH))))
+ ifeq ($(ARCH),$(filter $(ARCH), rv32im rv32imc))
+ $(info >>> IM32 TESTS)
+ included_im += $(filter %.S,\
+ $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32im/src/*))
+ compliance_set += $(included_im)
+ endif ##
+
+ ifeq (rv32imc,$(findstring rv32imc,$(ARCH)))
+ $(info >>> IMC32 TESTS)
+ included_imc += $(filter %.S,\
+ $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32imc/src/*))
+ compliance_set += $(included_imc)
+ endif ## ifeq (rv32imc,$(findstring rv32imc,$(ARCH)))
+ ifeq (rv32ic,$(findstring rv32ic,$(ARCH)))
+ endif
+endif ##
+
+
+$(info >>>$(ARCH) set included)
+
+ifeq ($(compliance_set),)
+$(info >>> No compliance tests included)
+endif
+
+$(info >>>>> compliance set: $(compliance_set))
+
+dst_dir := $(bld_dir)
+test_name := riscv_compliance
+bld_dir := $(addprefix $(dst_dir)/, $(test_name))
+obj_dir := $(bld_dir)/riscv_compliance_objs
+
+#cut_list += scall csr shamt simple
+cut_list += I-MISALIGN_JMP-01 I-MISALIGN_LDST-01 I-EBREAK-01 I-ECALL-01
+reference_src += $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32i*/*/*.reference_output)
+reference_src += $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32Zi*/*/*.reference_output)
+testnames := $(basename $(notdir $(compliance_set)))
+filtered := $(filter-out $(cut_list),$(testnames))
+objs := $(addprefix $(bld_dir)/,$(filtered:%=%.o))
+test_elf := $(addprefix $(dst_dir)/compliance_,$(filtered:%=%.elf))
+test_hex := $(addprefix $(dst_dir)/compliance_,$(filtered:%=%.hex))
+test_dump := $(addprefix $(bld_dir)/compliance_,$(filtered:%=%.dump))
+
+compliance_macros_file := $(root_dir)/tests/riscv_compliance/compliance_io.h
+compliance_output ?= true
+
+testnames_i := $(basename $(notdir $(included_i)))
+testnames_im := $(basename $(notdir $(included_im)))
+testnames_imc := $(basename $(notdir $(included_imc)))
+filtered_i := $(filter-out $(cut_list),$(testnames_i))
+filtered_im := $(filter-out $(cut_list),$(testnames_im))
+filtered_imc := $(filter-out $(cut_list),$(testnames_imc))
+
+# ARCH_FLAGS := -Wa,-march=rv32im -march=rv32im
+# ARCH_FLAGS_C := -Wa,-march=rv32imc -march=rv32imc
+CFLAGS := -I$(inc_dir) -I$(src_dir) -DASM -mabi=ilp32 -D__riscv_xlen=32 -w
+LDFLAGS := -static -fvisibility=hidden -nostdlib -nostartfiles -T$(inc_dir)/link.ld -march=$(ARCH) -mabi=ilp32
+GCCVERSIONGT7 := $(shell expr `$(RISCV_GCC) -dumpfullversion | cut -f1 -d'.'` \> 7)
+ifeq "$(GCCVERSIONGT7)" "1"
+ LDFLAGS += -mno-relax
+endif
+VPATH += $(src_dir) $(bld_dir) $(obj_dir) $(asm_path) $(ref_path) $(RISCV_COMPLIANCE_TESTS)
+
+ifeq ($(compliance_output), true)
+CFLAGS += -D_COMPLIANCE_OUTPUT
+endif
+
+default: clean log_requested_tgt check_version cp_asm ref_data $(test_elf) $(test_hex) $(test_dump)
+
+define compile_template
+$(obj_dir)/$(1).o: $(obj_dir) cp_asm
+ $(RISCV_GCC) -c $$(bld_dir)/compliance_asm/$(1).S $$(CFLAGS) -Wa,$(2) $(2) -o $$@
+endef
+
+define preprocessing
+for test_asm in $(1); do \
+march_tmp=$$test_asm ; \
+march_tmp=$${march_tmp%/src*} ; \
+march_tmp=$$(basename $$march_tmp) ; \
+file_name="$$(basename $${test_asm})" ; \
+$(RISCV_GCC) $(CFLAGS) -Wa,$(2) $(2) -E $$test_asm \
+-o $(bld_dir)/compliance_asm/$$file_name ; \
+done
+endef
+
+$(foreach SRC,$(filtered_i),$(eval $(call compile_template,$(SRC),-march=rv32i)))
+$(foreach SRC,$(filtered_im),$(eval $(call compile_template,$(SRC),-march=rv32im)))
+$(foreach SRC,$(filtered_imc),$(eval $(call compile_template,$(SRC),-march=rv32imc)))
+
+
+log_requested_tgt: $(bld_dir)
+ $(foreach test_name, $(filtered), $(eval $(shell echo compliance_$(test_name).hex >> $(bld_dir)/../test_info)))
+
+$(bld_dir) :
+ mkdir -p $(bld_dir)
+
+$(obj_dir) : | ref_data
+ mkdir -p $(obj_dir)
+
+$(dst_dir)/compliance_%.elf: $(obj_dir)/%.o | $(dep_files)
+ $(RISCV_GCC) $^ $(LDFLAGS) -o $@ -g
+
+$(dst_dir)/compliance_%.hex: $(dst_dir)/compliance_%.elf
+ $(RISCV_ROM_OBJCOPY) $^ $@
+ $(RISCV_RAM_OBJCOPY) $^ $@.ram
+ #assign 0x2000_0xxx to 0x0000_0xxx to map to sdram
+ sed -i 's/@20000/@00000/g' $@.ram
+
+$(bld_dir)/compliance_%.dump: $(dst_dir)/compliance_%.elf
+ $(RISCV_OBJDUMP) -D -w -x -S $^ > $@
+
+ref_data:
+ mkdir -p $(bld_dir)/ref_data
+ for files in $(reference_src) ; do \
+ sed_input=$$files ; \
+ sed_output=$$(basename $${files%.*}) ; \
+ sed "s/\r$$//; \
+ s/\(........\)/\1,/g; \
+ s/.$$//; s/\(.*\),\(.*\),\(.*\),\(.*\)/\4,\3,\2,\1/; \
+ s/\(.........\)/\10x/g; s/^/0x/; s/$$/,/; $$ s/.$$//" $$sed_input > $(bld_dir)/ref_data/$$sed_output; \
+ done
+
+cp_asm:
+ mkdir -p $(bld_dir)/compliance_asm
+ $(call preprocessing,$(included_i),-march=rv32i)
+ $(call preprocessing,$(included_im),-march=rv32im)
+ $(call preprocessing,$(included_imc),-march=rv32imc)
+
+
+riscv_compliance_tests_dir := $(if $(RISCV_COMPLIANCE_TESTS), $(RISCV_COMPLIANCE_TESTS), ./undefined)
+riscv_tests_commit := d51259b2a949be3af02e776c39e135402675ac9b
+## commit hash readed from local copy of https://github.com/riscv/riscv-compliance
+tmp_commit = $(shell cd $(riscv_compliance_tests_dir) 2>/dev/null && git log -1 | grep "commit" | cut -f2 -d ' ')
+is_commit_good = $(if $(subst $(riscv_tests_commit),,$(tmp_commit)),false,true)
+
+# Color
+RED=\033[0;31m
+NC=\033[0m
+
+check_version : $(riscv_compliance_tests_dir)
+ @if [ ! -d $(riscv_compliance_tests_dir) ]; then \
+ echo -e "$(RED)==========================================================================" &&\
+ echo " Error! Environment variable RISCV_COMPLIANCE_TESTS='$(riscv_compliance_tests_dir)' " &&\
+ echo " directory not exist!" && \
+ echo "==========================================================================$(NC)" ; \
+ fi
+ifneq ($(is_commit_good),true)
+ @echo -e "$(RED)=========================================================================="
+ @echo " Warning! Execution of test code is not guaranteed "
+ @echo " while using the current commit of repository located at : $(riscv_compliance_tests_dir) ."
+ @echo " "
+ @echo " riscv_compliance repository must point to commit $(riscv_tests_commit)!"
+ @echo -e "==========================================================================$(NC)"
+endif
+
+$(riscv_compliance_tests_dir) :.
+ifndef RISCV_COMPLIANCE_TESTS
+ @echo -e "$(RED)=========================================================================="
+ @echo " Error! Environment variable RISCV_COMPLIANCE_TESTS not set!"
+ @echo " You must set the environment variable RISCV_COMPLIANCE_TESTS"
+ @echo " The variable should point to the local copy of the"
+ @echo " repository https://github.com/riscv/riscv-compliance"
+ @echo " with the commit $(riscv_tests_commit)"
+ @echo -e "==========================================================================$(NC)"
+ exit 1
+endif
+
+clean:
+ $(RM) -R $(test_elf) $(test_hex) $(bld_dir)
+
+.PHONY: check_version clean ref_data cp_asm default
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/aw_test_macros.h b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/aw_test_macros.h
new file mode 100644
index 0000000..3e052a1
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/aw_test_macros.h
@@ -0,0 +1,683 @@
+/*
+ COPY OF /riscv-compliance/riscv-test-env/aw_test_macros.h
+ */
+
+// See LICENSE for license details.
+
+#ifndef __TEST_MACROS_SCALAR_H
+#define __TEST_MACROS_SCALAR_H
+
+
+#-----------------------------------------------------------------------
+# Helper macros
+#-----------------------------------------------------------------------
+
+#define MASK_XLEN(x) ((x) & ((1 << (__riscv_xlen - 1) << 1) - 1))
+
+#define CHECK_XLEN li a0, 1; slli a0, a0, 31; bltz a0, 1f; RVTEST_PASS; 1: srli a0, a0, 31; la t0, begin_signature; sw a0, 0(t0)
+
+#define TESTNUM gp
+
+#define SWSIG( testnum, testreg ) \
+ la x28, test_res; \
+ sw testreg, (testnum<<2)(x28); \
+
+#
+# Address = base+(testnum<<2)
+# sw testreg, (testnum<<2)(basereg)
+#
+#define TEST_CASE( testnum, testreg, correctval, code... ) \
+test_ ## testnum: \
+ code; \
+ li x29, MASK_XLEN(correctval); \
+ li TESTNUM, testnum; \
+ SWSIG(testnum,testreg); \
+ bne testreg, x29, fail;
+
+# We use a macro hack to simpify code generation for various numbers
+# of bubble cycles.
+
+#define TEST_INSERT_NOPS_0
+#define TEST_INSERT_NOPS_1 nop; TEST_INSERT_NOPS_0
+#define TEST_INSERT_NOPS_2 nop; TEST_INSERT_NOPS_1
+#define TEST_INSERT_NOPS_3 nop; TEST_INSERT_NOPS_2
+#define TEST_INSERT_NOPS_4 nop; TEST_INSERT_NOPS_3
+#define TEST_INSERT_NOPS_5 nop; TEST_INSERT_NOPS_4
+#define TEST_INSERT_NOPS_6 nop; TEST_INSERT_NOPS_5
+#define TEST_INSERT_NOPS_7 nop; TEST_INSERT_NOPS_6
+#define TEST_INSERT_NOPS_8 nop; TEST_INSERT_NOPS_7
+#define TEST_INSERT_NOPS_9 nop; TEST_INSERT_NOPS_8
+#define TEST_INSERT_NOPS_10 nop; TEST_INSERT_NOPS_9
+
+
+#-----------------------------------------------------------------------
+# RV64UI MACROS
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# Tests for instructions with immediate operand
+#-----------------------------------------------------------------------
+
+#define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11))
+
+#define TEST_IMM_OP( testnum, inst, result, val1, imm ) \
+ TEST_CASE( testnum, x30, result, \
+ li x1, MASK_XLEN(val1); \
+ inst x30, x1, SEXT_IMM(imm); \
+ )
+
+#define TEST_IMM_SRC1_EQ_DEST( testnum, inst, result, val1, imm ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, MASK_XLEN(val1); \
+ inst x1, x1, SEXT_IMM(imm); \
+ )
+
+#define TEST_IMM_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \
+ TEST_CASE( testnum, x6, result, \
+ li x4, 0; \
+1: li x1, MASK_XLEN(val1); \
+ inst x30, x1, SEXT_IMM(imm); \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ addi x6, x30, 0; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+ )
+
+#define TEST_IMM_SRC1_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \
+ TEST_CASE( testnum, x30, result, \
+ li x4, 0; \
+1: li x1, MASK_XLEN(val1); \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ inst x30, x1, SEXT_IMM(imm); \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+ )
+
+#define TEST_IMM_ZEROSRC1( testnum, inst, result, imm ) \
+ TEST_CASE( testnum, x1, result, \
+ inst x1, x0, SEXT_IMM(imm); \
+ )
+
+#define TEST_IMM_ZERODEST( testnum, inst, val1, imm ) \
+ TEST_CASE( testnum, x0, 0, \
+ li x1, MASK_XLEN(val1); \
+ inst x0, x1, SEXT_IMM(imm); \
+ )
+
+#-----------------------------------------------------------------------
+# Tests for an instruction with register operands
+#-----------------------------------------------------------------------
+
+#define TEST_R_OP( testnum, inst, result, val1 ) \
+ TEST_CASE( testnum, x30, result, \
+ li x1, val1; \
+ inst x30, x1; \
+ )
+
+#define TEST_R_SRC1_EQ_DEST( testnum, inst, result, val1 ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, val1; \
+ inst x1, x1; \
+ )
+
+#define TEST_R_DEST_BYPASS( testnum, nop_cycles, inst, result, val1 ) \
+ TEST_CASE( testnum, x6, result, \
+ li x4, 0; \
+1: li x1, val1; \
+ inst x30, x1; \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ addi x6, x30, 0; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+ )
+
+#-----------------------------------------------------------------------
+# Tests for an instruction with register-register operands
+#-----------------------------------------------------------------------
+
+#define TEST_RR_OP( testnum, inst, result, val1, val2 ) \
+ TEST_CASE( testnum, x30, result, \
+ li x1, MASK_XLEN(val1); \
+ li x2, MASK_XLEN(val2); \
+ inst x30, x1, x2; \
+ )
+
+#define TEST_RR_SRC1_EQ_DEST( testnum, inst, result, val1, val2 ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, MASK_XLEN(val1); \
+ li x2, MASK_XLEN(val2); \
+ inst x1, x1, x2; \
+ )
+
+#define TEST_RR_SRC2_EQ_DEST( testnum, inst, result, val1, val2 ) \
+ TEST_CASE( testnum, x2, result, \
+ li x1, MASK_XLEN(val1); \
+ li x2, MASK_XLEN(val2); \
+ inst x2, x1, x2; \
+ )
+
+#define TEST_RR_SRC12_EQ_DEST( testnum, inst, result, val1 ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, MASK_XLEN(val1); \
+ inst x1, x1, x1; \
+ )
+
+#define TEST_RR_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, val2 ) \
+ TEST_CASE( testnum, x6, result, \
+ li x4, 0; \
+1: li x1, MASK_XLEN(val1); \
+ li x2, MASK_XLEN(val2); \
+ inst x30, x1, x2; \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ addi x6, x30, 0; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+ )
+
+#define TEST_RR_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \
+ TEST_CASE( testnum, x30, result, \
+ li x4, 0; \
+1: li x1, MASK_XLEN(val1); \
+ TEST_INSERT_NOPS_ ## src1_nops \
+ li x2, MASK_XLEN(val2); \
+ TEST_INSERT_NOPS_ ## src2_nops \
+ inst x30, x1, x2; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+ )
+
+#define TEST_RR_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \
+ TEST_CASE( testnum, x30, result, \
+ li x4, 0; \
+1: li x2, MASK_XLEN(val2); \
+ TEST_INSERT_NOPS_ ## src1_nops \
+ li x1, MASK_XLEN(val1); \
+ TEST_INSERT_NOPS_ ## src2_nops \
+ inst x30, x1, x2; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+ )
+
+#define TEST_RR_ZEROSRC1( testnum, inst, result, val ) \
+ TEST_CASE( testnum, x2, result, \
+ li x1, MASK_XLEN(val); \
+ inst x2, x0, x1; \
+ )
+
+#define TEST_RR_ZEROSRC2( testnum, inst, result, val ) \
+ TEST_CASE( testnum, x2, result, \
+ li x1, MASK_XLEN(val); \
+ inst x2, x1, x0; \
+ )
+
+#define TEST_RR_ZEROSRC12( testnum, inst, result ) \
+ TEST_CASE( testnum, x1, result, \
+ inst x1, x0, x0; \
+ )
+
+#define TEST_RR_ZERODEST( testnum, inst, val1, val2 ) \
+ TEST_CASE( testnum, x0, 0, \
+ li x1, MASK_XLEN(val1); \
+ li x2, MASK_XLEN(val2); \
+ inst x0, x1, x2; \
+ )
+
+#-----------------------------------------------------------------------
+# Test memory instructions
+#-----------------------------------------------------------------------
+
+#define TEST_LD_OP( testnum, inst, result, offset, base ) \
+ TEST_CASE( testnum, x30, result, \
+ la x1, base; \
+ inst x30, offset(x1); \
+ )
+
+#define TEST_ST_OP( testnum, load_inst, store_inst, result, offset, base ) \
+ TEST_CASE( testnum, x30, result, \
+ la x1, base; \
+ li x2, result; \
+ store_inst x2, offset(x1); \
+ load_inst x30, offset(x1); \
+ )
+
+#define TEST_LD_DEST_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ li x4, 0; \
+1: la x1, base; \
+ inst x30, offset(x1); \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ addi x6, x30, 0; \
+ li x29, result; \
+ bne x6, x29, fail; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b; \
+
+#define TEST_LD_SRC1_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ li x4, 0; \
+1: la x1, base; \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ inst x30, offset(x1); \
+ li x29, result; \
+ bne x30, x29, fail; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+
+#define TEST_ST_SRC12_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ li x4, 0; \
+1: li x1, result; \
+ TEST_INSERT_NOPS_ ## src1_nops \
+ la x2, base; \
+ TEST_INSERT_NOPS_ ## src2_nops \
+ store_inst x1, offset(x2); \
+ load_inst x30, offset(x2); \
+ li x29, result; \
+ bne x30, x29, fail; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+
+#define TEST_ST_SRC21_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ li x4, 0; \
+1: la x2, base; \
+ TEST_INSERT_NOPS_ ## src1_nops \
+ li x1, result; \
+ TEST_INSERT_NOPS_ ## src2_nops \
+ store_inst x1, offset(x2); \
+ load_inst x30, offset(x2); \
+ li x29, result; \
+ bne x30, x29, fail; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+
+#define TEST_BR2_OP_TAKEN( testnum, inst, val1, val2 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ li x1, val1; \
+ li x2, val2; \
+ inst x1, x2, 2f; \
+ bne x0, TESTNUM, fail; \
+1: bne x0, TESTNUM, 3f; \
+2: inst x1, x2, 1b; \
+ bne x0, TESTNUM, fail; \
+3:
+
+#define TEST_BR2_OP_NOTTAKEN( testnum, inst, val1, val2 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ li x1, val1; \
+ li x2, val2; \
+ inst x1, x2, 1f; \
+ bne x0, TESTNUM, 2f; \
+1: bne x0, TESTNUM, fail; \
+2: inst x1, x2, 1b; \
+3:
+
+#define TEST_BR2_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ li x4, 0; \
+1: li x1, val1; \
+ TEST_INSERT_NOPS_ ## src1_nops \
+ li x2, val2; \
+ TEST_INSERT_NOPS_ ## src2_nops \
+ inst x1, x2, fail; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+
+#define TEST_BR2_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ li x4, 0; \
+1: li x2, val2; \
+ TEST_INSERT_NOPS_ ## src1_nops \
+ li x1, val1; \
+ TEST_INSERT_NOPS_ ## src2_nops \
+ inst x1, x2, fail; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+
+#-----------------------------------------------------------------------
+# Test jump instructions
+#-----------------------------------------------------------------------
+
+#define TEST_JR_SRC1_BYPASS( testnum, nop_cycles, inst ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ li x4, 0; \
+1: la x6, 2f; \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ inst x6; \
+ bne x0, TESTNUM, fail; \
+2: addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+
+#define TEST_JALR_SRC1_BYPASS( testnum, nop_cycles, inst ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ li x4, 0; \
+1: la x6, 2f; \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ inst x19, x6, 0; \
+ bne x0, TESTNUM, fail; \
+2: addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+
+
+#-----------------------------------------------------------------------
+# RV64UF MACROS
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# Tests floating-point instructions
+#-----------------------------------------------------------------------
+
+#define qNaNf 0f:7fc00000
+#define sNaNf 0f:7f800001
+#define qNaN 0d:7ff8000000000000
+#define sNaN 0d:7ff0000000000001
+
+#define TEST_FP_OP_S_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ la a0, test_ ## testnum ## _data ;\
+ flw f0, 0(a0); \
+ flw f1, 4(a0); \
+ flw f2, 8(a0); \
+ lw a3, 12(a0); \
+ code; \
+ fsflags a1, x0; \
+ li a2, flags; \
+ bne a0, a3, fail; \
+ bne a1, a2, fail; \
+ .pushsection .data; \
+ .align 2; \
+ test_ ## testnum ## _data: \
+ .float val1; \
+ .float val2; \
+ .float val3; \
+ .result; \
+ .popsection
+
+#define TEST_FP_OP_D_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ la a0, test_ ## testnum ## _data ;\
+ fld f0, 0(a0); \
+ fld f1, 8(a0); \
+ fld f2, 16(a0); \
+ ld a3, 24(a0); \
+ code; \
+ fsflags a1, x0; \
+ li a2, flags; \
+ bne a0, a3, fail; \
+ bne a1, a2, fail; \
+ .pushsection .data; \
+ .align 3; \
+ test_ ## testnum ## _data: \
+ .double val1; \
+ .double val2; \
+ .double val3; \
+ .result; \
+ .popsection
+
+// TODO: assign a separate mem location for the comparison address?
+#define TEST_FP_OP_D32_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ la a0, test_ ## testnum ## _data ;\
+ fld f0, 0(a0); \
+ fld f1, 8(a0); \
+ fld f2, 16(a0); \
+ lw a3, 24(a0); \
+ lw t1, 28(a0); \
+ code; \
+ fsflags a1, x0; \
+ li a2, flags; \
+ bne a0, a3, fail; \
+ bne t1, t2, fail; \
+ bne a1, a2, fail; \
+ .pushsection .data; \
+ .align 3; \
+ test_ ## testnum ## _data: \
+ .double val1; \
+ .double val2; \
+ .double val3; \
+ .result; \
+ .popsection
+
+#define TEST_FCVT_S_D32( testnum, result, val1 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \
+ fcvt.s.d f3, f0; fcvt.d.s f3, f3; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
+#define TEST_FCVT_S_D( testnum, result, val1 ) \
+ TEST_FP_OP_D_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \
+ fcvt.s.d f3, f0; fcvt.d.s f3, f3; fmv.x.d a0, f3)
+
+#define TEST_FCVT_D_S( testnum, result, val1 ) \
+ TEST_FP_OP_S_INTERNAL( testnum, 0, float result, val1, 0.0, 0.0, \
+ fcvt.d.s f3, f0; fcvt.s.d f3, f3; fmv.x.s a0, f3)
+
+#define TEST_FP_OP1_S( testnum, inst, flags, result, val1 ) \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, 0.0, 0.0, \
+ inst f3, f0; fmv.x.s a0, f3)
+
+#define TEST_FP_OP1_D32( testnum, inst, flags, result, val1 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \
+ inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+// ^: store computation result in address from a0, load high-word into t2
+
+#define TEST_FP_OP1_D( testnum, inst, flags, result, val1 ) \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \
+ inst f3, f0; fmv.x.d a0, f3)
+
+#define TEST_FP_OP1_S_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+ inst f3, f0; fmv.x.s a0, f3)
+
+#define TEST_FP_OP1_D32_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+ inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+// ^: store computation result in address from a0, load high-word into t2
+
+#define TEST_FP_OP1_D_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+ inst f3, f0; fmv.x.d a0, f3)
+
+#define TEST_FP_OP2_S( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, 0.0, \
+ inst f3, f0, f1; fmv.x.s a0, f3)
+
+#define TEST_FP_OP2_D32( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
+ inst f3, f0, f1; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+// ^: store computation result in address from a0, load high-word into t2
+
+#define TEST_FP_OP2_D( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
+ inst f3, f0, f1; fmv.x.d a0, f3)
+
+#define TEST_FP_OP3_S( testnum, inst, flags, result, val1, val2, val3 ) \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, val3, \
+ inst f3, f0, f1, f2; fmv.x.s a0, f3)
+
+#define TEST_FP_OP3_D32( testnum, inst, flags, result, val1, val2, val3 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, val3, \
+ inst f3, f0, f1, f2; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+// ^: store computation result in address from a0, load high-word into t2
+
+#define TEST_FP_OP3_D( testnum, inst, flags, result, val1, val2, val3 ) \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, val2, val3, \
+ inst f3, f0, f1, f2; fmv.x.d a0, f3)
+
+#define TEST_FP_INT_OP_S( testnum, inst, flags, result, val1, rm ) \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, 0.0, 0.0, \
+ inst a0, f0, rm)
+
+#define TEST_FP_INT_OP_D32( testnum, inst, flags, result, val1, rm ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+ inst a0, f0, f1; li t2, 0)
+
+#define TEST_FP_INT_OP_D( testnum, inst, flags, result, val1, rm ) \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+ inst a0, f0, rm)
+
+#define TEST_FP_CMP_OP_S( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, val2, 0.0, \
+ inst a0, f0, f1)
+
+#define TEST_FP_CMP_OP_D32( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \
+ inst a0, f0, f1; li t2, 0)
+
+#define TEST_FP_CMP_OP_D( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \
+ inst a0, f0, f1)
+
+#define TEST_FCLASS_S(testnum, correct, input) \
+ TEST_CASE(testnum, a0, correct, li a0, input; fmv.s.x fa0, a0; \
+ fclass.s a0, fa0)
+
+#define TEST_FCLASS_D32(testnum, correct, input) \
+ TEST_CASE(testnum, a0, correct, \
+ la a0, test_ ## testnum ## _data ;\
+ fld fa0, 0(a0); \
+ fclass.d a0, fa0) \
+ .pushsection .data; \
+ .align 3; \
+ test_ ## testnum ## _data: \
+ .dword input; \
+ .popsection
+
+#define TEST_FCLASS_D(testnum, correct, input) \
+ TEST_CASE(testnum, a0, correct, li a0, input; fmv.d.x fa0, a0; \
+ fclass.d a0, fa0)
+
+#define TEST_INT_FP_OP_S( testnum, inst, result, val1 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ la a0, test_ ## testnum ## _data ;\
+ lw a3, 0(a0); \
+ li a0, val1; \
+ inst f0, a0; \
+ fsflags x0; \
+ fmv.x.s a0, f0; \
+ bne a0, a3, fail; \
+ .pushsection .data; \
+ .align 2; \
+ test_ ## testnum ## _data: \
+ .float result; \
+ .popsection
+
+#define TEST_INT_FP_OP_D32( testnum, inst, result, val1 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ la a0, test_ ## testnum ## _data ;\
+ lw a3, 0(a0); \
+ lw a4, 4(a0); \
+ li a1, val1; \
+ inst f0, a1; \
+ \
+ fsd f0, 0(a0); \
+ lw a1, 4(a0); \
+ lw a0, 0(a0); \
+ \
+ fsflags x0; \
+ bne a0, a3, fail; \
+ bne a1, a4, fail; \
+ .pushsection .data; \
+ .align 3; \
+ test_ ## testnum ## _data: \
+ .double result; \
+ .popsection
+
+#define TEST_INT_FP_OP_D( testnum, inst, result, val1 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ la a0, test_ ## testnum ## _data ;\
+ ld a3, 0(a0); \
+ li a0, val1; \
+ inst f0, a0; \
+ fsflags x0; \
+ fmv.x.d a0, f0; \
+ bne a0, a3, fail; \
+ .pushsection .data; \
+ .align 3; \
+ test_ ## testnum ## _data: \
+ .double result; \
+ .popsection
+
+// We need some special handling here to allow 64-bit comparison in 32-bit arch
+// TODO: find a better name and clean up when intended for general usage?
+#define TEST_CASE_D32( testnum, testreg1, testreg2, correctval, code... ) \
+test_ ## testnum: \
+ code; \
+ la x31, test_ ## testnum ## _data ; \
+ lw x29, 0(x31); \
+ lw x31, 4(x31); \
+ li TESTNUM, testnum; \
+ SWSIG (testnum, TESTNUM);\
+ bne testreg1, x29, fail;\
+ bne testreg2, x31, fail;\
+ .pushsection .data; \
+ .align 3; \
+ test_ ## testnum ## _data: \
+ .dword correctval; \
+ .popsection
+
+// ^ x30 is used in some other macros, to avoid issues we use x31 for upper word
+
+#-----------------------------------------------------------------------
+# Pass and fail code (assumes test num is in TESTNUM)
+#-----------------------------------------------------------------------
+
+#define TEST_PASSFAIL \
+ bne x0, TESTNUM, pass; \
+fail: \
+ RVTEST_FAIL; \
+pass: \
+ RVTEST_PASS \
+
+
+#-----------------------------------------------------------------------
+# Test data section
+#-----------------------------------------------------------------------
+
+#define TEST_DATA
+
+#endif
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/compliance_io.h b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/compliance_io.h
new file mode 100644
index 0000000..5b7ca54
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/compliance_io.h
@@ -0,0 +1,70 @@
+// RISC-V Compliance IO Test Header File
+
+/*
+ * Copyright (c) 2005-2018 Imperas Software Ltd., www.imperas.com
+ *
+ * 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.
+ *
+ */
+
+#ifndef _COMPLIANCE_IO_H
+#define _COMPLIANCE_IO_H
+
+//-----------------------------------------------------------------------
+// RV IO Macros (Non functional)
+//-----------------------------------------------------------------------
+#ifdef _COMPLIANCE_OUTPUT
+
+#define RVTEST_IO_PUSH(_SP) \
+la _SP, begin_regstate; \
+sw x3, 0(_SP); \
+sw x4, 4(_SP); \
+sw x5, 8(_SP);
+
+#define RVTEST_IO_POP(_SP) \
+la _SP, begin_regstate; \
+lw x3, 0(_SP); \
+lw x4, 4(_SP); \
+lw x5, 8(_SP);
+
+#define RVTEST_IO_WRITE_STR(_SP, _STR) \
+ .section .data.string; \
+20001: \
+ .string _STR; \
+ .section .text; \
+ RVTEST_IO_PUSH(_SP) \
+ li x3, 0xF0000000; \
+ la x4, 20001b; \
+2: lb x5, 0(x4); \
+ sb x5, 0(x3); \
+ beq x5, zero, 1f; \
+ add x4, x4, 1; \
+ j 2b; \
+1: RVTEST_IO_POP(_SP)
+
+#else // #ifdef _COMPLIANCE_OUTPUT
+
+#define RVTEST_IO_WRITE_STR(_SP, _STR)
+
+#endif // #end #ifdef _COMPLIANCE_OUTPUT
+
+#define RVTEST_IO_INIT
+#define RVTEST_IO_CHECK()
+#define RVTEST_IO_ASSERT_GPR_EQ(_SP, _R, _I)
+#define RVTEST_IO_ASSERT_SFPR_EQ(_F, _R, _I)
+#define RVTEST_IO_ASSERT_DFPR_EQ(_D, _R, _I)
+#define RVTEST_IO_ASSERT_EQ(_R, _I)
+
+#endif // _COMPLIANCE_IO_H
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/compliance_test.h b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/compliance_test.h
new file mode 100644
index 0000000..0c7e7f9
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/compliance_test.h
@@ -0,0 +1,31 @@
+// RISC-V Compliance Test Header File
+// Copyright (c) 2017, Codasip Ltd. All Rights Reserved.
+// See LICENSE for license details.
+//
+// Description: Common header file for RV32I tests
+
+#ifndef _COMPLIANCE_TEST_H
+#define _COMPLIANCE_TEST_H
+
+//-----------------------------------------------------------------------
+// RV Compliance Macros
+//-----------------------------------------------------------------------
+
+#define RV_COMPLIANCE_HALT \
+
+#define RV_COMPLIANCE_RV32M \
+ RVTEST_RV32M \
+
+#define RV_COMPLIANCE_CODE_BEGIN \
+ RVTEST_CODE_BEGIN \
+
+#define RV_COMPLIANCE_CODE_END \
+ RVTEST_CODE_END \
+
+#define RV_COMPLIANCE_DATA_BEGIN \
+ RVTEST_DATA_BEGIN \
+
+#define RV_COMPLIANCE_DATA_END \
+ RVTEST_DATA_END \
+
+#endif
\ No newline at end of file
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/riscv_test.h b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/riscv_test.h
new file mode 100644
index 0000000..fdc6156
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/riscv_test.h
@@ -0,0 +1,7 @@
+
+#ifndef _RISCV_TEST_H
+#define _RISCV_TEST_H
+
+#include "test_macros.h"
+
+#endif
\ No newline at end of file
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/riscv_test_macros.h b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/riscv_test_macros.h
new file mode 100644
index 0000000..6717bd4
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/riscv_test_macros.h
@@ -0,0 +1,463 @@
+// RISC-V Compliance IO Test Header File
+
+/*
+ * Copyright (c) 2005-2018 Imperas Software Ltd., www.imperas.com
+ *
+ * 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 "riscv_macros.h"
+
+//
+// In general the following registers are reserved
+// ra, a0, t0, t1
+// Additionally on an assertion violation, t1, t2 are overwritten
+// x1, x10, x5, x6, x7 respectively
+// Floating registers reserved
+// f5
+//
+
+#define MASK_XLEN(x) ((x) & ((1 << (__riscv_xlen - 1) << 1) - 1))
+
+#define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11))
+
+// Base function for integer operations
+#define TEST_CASE(testreg, destreg, correctval, swreg, offset, code... ) \
+ code; \
+ sw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) \
+
+// Base functions for single precision floating point operations
+#define TEST_CASE_FP(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ flw reg1, 0(a0); \
+ flw reg2, 4(a0); \
+ lw t1, 8(a0); \
+ code; \
+ fsw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_SFPR_EQ(destreg, t1, correctval) \
+ .pushsection .data; \
+ .align 3; \
+ test_ ## test_num ## _data: \
+ .float val1; \
+ .float val2; \
+ .word correctval; \
+ .popsection
+
+#define TEST_CASE_FP_I(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ lw t1, 0(a0); \
+ code; \
+ fsw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_SFPR_EQ(destreg, t1, correctval) \
+ .pushsection .data; \
+ .align 1; \
+ test_ ## test_num ## _data: \
+ .word correctval; \
+ .popsection
+
+#define TEST_CASE_FP_I2(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ flw reg, 0(a0); \
+ lw t1, 4(a0); \
+ code; \
+ sw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+ .pushsection .data; \
+ .align 2; \
+ test_ ## test_num ## _data: \
+ .float val; \
+ .word correctval; \
+ .popsection
+
+#define TEST_CASE_FP_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ flw reg1, 0(a0); \
+ flw reg2, 4(a0); \
+ flw reg3, 8(a0); \
+ lw t1, 12(a0); \
+ code; \
+ fsw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_SFPR_EQ(destreg, t1, correctval) \
+ .pushsection .data; \
+ .align 4; \
+ test_ ## test_num ## _data: \
+ .float val1; \
+ .float val2; \
+ .float val3; \
+ .word correctval; \
+ .popsection
+
+#define TEST_CASE_FP_FMVXS(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ flw reg, 0(a0); \
+ code; \
+ sw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+ .pushsection .data; \
+ .align 1; \
+ test_ ## test_num ## _data: \
+ .float val; \
+ .popsection
+
+#define TEST_CASE_FP_FMVSX(test_num, destreg, reg, correctval, val, swreg, offset, code...) \
+ la a0, test_ ## test_num ## _data; \
+ li reg, val; \
+ code; \
+ fsw destreg, offset(swreg); \
+ lw a1, 0(a0); \
+ RVTEST_IO_ASSERT_SFPR_EQ(destreg, a1, correctval) \
+ .pushsection .data; \
+ .align 1; \
+ test_ ## test_num ## _data: \
+ .word correctval; \
+ .popsection
+
+// Base functions for double precision floating point operations - rv32d
+#define TEST_CASE_FPD(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ fld reg1, 0(a0); \
+ fld reg2, 8(a0); \
+ code; \
+ fsd destreg, offset(swreg); \
+ lw t1, 16(a0); \
+ lw t2, 20(a0); \
+ la a0, store_ ## test_num ## _data; \
+ fsd destreg, 0(a0); \
+ lw a1, 0(a0); \
+ lw a2, 4(a0); \
+ RVTEST_IO_ASSERT_DFPR_EQ(destreg, t2, t1, a2, a1, correctval) \
+ .pushsection .data; \
+ .align 3; \
+ test_ ## test_num ## _data: \
+ .double val1; \
+ .double val2; \
+ .dword correctval; \
+ .popsection; \
+ .pushsection .data; \
+ store_ ## test_num ## _data: \
+ .fill 1, 8, -1; \
+ .popsection
+
+#define TEST_CASE_FPD_I(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ code; \
+ fsd destreg, offset(swreg); \
+ lw t1, 0(a0); \
+ lw t2, 4(a0); \
+ la a0, store_ ## test_num ## _data; \
+ fsd destreg, 0(a0); \
+ lw a1, 0(a0); \
+ lw a2, 4(a0); \
+ RVTEST_IO_ASSERT_DFPR_EQ(destreg, t2, t1, a2, a1, correctval) \
+ .pushsection .data; \
+ .align 1; \
+ test_ ## test_num ## _data: \
+ .dword correctval; \
+ .popsection; \
+ store_ ## test_num ## _data: \
+ .fill 1, 8, -1; \
+ .popsection
+
+#define TEST_CASE_FPD_I2(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ fld reg, 0(a0); \
+ lw t1, 8(a0); \
+ code; \
+ sw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+ .pushsection .data; \
+ .align 2; \
+ test_ ## test_num ## _data: \
+ .double val; \
+ .word correctval; \
+ .popsection
+
+#define TEST_CASE_FPD_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ fld reg1, 0(a0); \
+ fld reg2, 8(a0); \
+ fld reg3, 16(a0); \
+ code; \
+ fsd destreg, offset(swreg); \
+ lw t1, 24(a0); \
+ lw t2, 28(a0); \
+ la a0, store_ ## test_num ## _data; \
+ fsd destreg, 0(a0); \
+ lw a1, 0(a0); \
+ lw a2, 4(a0); \
+ RVTEST_IO_ASSERT_DFPR_EQ(destreg, t2, t1, a2, a1, correctval) \
+ .pushsection .data; \
+ .align 4; \
+ test_ ## test_num ## _data: \
+ .double val1; \
+ .double val2; \
+ .double val3; \
+ .dword correctval; \
+ .popsection; \
+ .pushsection .data; \
+ store_ ## test_num ## _data: \
+ .fill 1, 8, -1; \
+ .popsection
+
+//Tests for a instructions with register-register operand
+#define TEST_RR_OP(inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ li reg1, MASK_XLEN(val1); \
+ li reg2, MASK_XLEN(val2); \
+ inst destreg, reg1, reg2; \
+ )
+
+#define TEST_RR_SRC1( inst, destreg, reg, correctval, val1, val2, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ li destreg, MASK_XLEN(val1); \
+ li reg, MASK_XLEN(val2); \
+ inst destreg, destreg, reg; \
+ )
+
+#define TEST_RR_SRC2( inst, destreg, reg, correctval, val1, val2, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ li reg, MASK_XLEN(val1); \
+ li destreg, MASK_XLEN(val2); \
+ inst destreg, reg, destreg; \
+ )
+
+#define TEST_RR_SRC12( inst, destreg, correctval, val, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ li destreg, MASK_XLEN(val1); \
+ inst destreg, destreg, destreg; \
+ )
+
+#define TEST_RR_ZERO1( inst, destreg, reg, correctval, val, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ li reg, MASK_XLEN(val); \
+ inst destreg, x0, reg; \
+ )
+
+#define TEST_RR_ZERO2( inst, destreg, reg, correctval, val, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ li reg, MASK_XLEN(val); \
+ inst destreg, reg, x0; \
+ )
+
+#define TEST_RR_ZERO12( inst, destreg, correctval, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ inst destreg, x0, x0; \
+ )
+
+#define TEST_RR_ZERODEST( inst, reg1, reg2, val1, val2, swreg, offset, testreg) \
+ TEST_CASE(testreg, x0, 0, swreg, offset, \
+ li reg1, MASK_XLEN(val1); \
+ li reg2, MASK_XLEN(val2); \
+ inst x0, reg1, reg2; \
+ )
+
+//Tests for a instructions with register-immediate operand
+#define TEST_IMM_OP( inst, destreg, reg, correctval, val, imm, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ li reg, MASK_XLEN(val); \
+ inst destreg, reg, SEXT_IMM(imm); \
+ )
+
+#define TEST_IMM_SRC( inst, destreg, correctval, val, imm, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ li destreg, MASK_XLEN(val); \
+ inst destreg, destreg, SEXT_IMM(imm); \
+ )
+
+#define TEST_IMM_ZEROSRC( inst, destreg, correctval, imm, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ inst destreg, x0, SEXT_IMM(imm); \
+ )
+
+#define TEST_IMM_ZERODEST( inst, reg, val, imm, swreg, offset, testreg) \
+ TEST_CASE(testreg, x0, 0, swreg, offset, \
+ li reg, MASK_XLEN(val); \
+ inst x0, reg, SEXT_IMM(imm); \
+ )
+
+#define TEST_IMM_ONEREG( inst, destreg, correctval, imm, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ inst destreg, SEXT_IMM(imm); \
+ )
+
+#define TEST_AUIPC(inst, destreg, correctval, imm, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ 1: \
+ inst destreg, imm; \
+ la swreg, 1b; \
+ sub destreg, destreg, swreg; \
+ )
+
+//Tests for a compressed instruction
+#define TEST_CR_OP( inst, destreg, reg, correctval, val1, val2, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ li reg, MASK_XLEN(val1); \
+ li destreg, MASK_XLEN(val2); \
+ inst destreg, reg; \
+ )
+
+#define TEST_CI_OP( inst, destreg, correctval, val, imm, swreg, offset, testreg) \
+ TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+ li destreg, MASK_XLEN(val); \
+ inst destreg, imm; \
+ )
+
+#define TEST_CI_OP_NOREG(inst, correctval, imm, swreg, offset, testreg) \
+ TEST_CASE(testreg,x0, correctval, swreg, offset, \
+ inst imm; \
+ )
+
+//Tests for floating point instructions - single precision
+#define TEST_FP_OP(test_num, inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset) \
+ TEST_CASE_FP(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, \
+ inst destreg, reg1, reg2; \
+ )
+
+#define TEST_FP_ONEREG(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FP(test_num, destreg, reg, reg, correctval, val, val, swreg, offset, \
+ inst destreg, reg; \
+ )
+
+#define TEST_FP_4REG(test_num, inst, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset) \
+ TEST_CASE_FP_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, \
+ inst destreg, reg1, reg2, reg3; \
+ )
+
+#define TEST_FP_I(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FP_I(test_num, destreg, reg, correctval, val, swreg, offset, \
+ li reg, MASK_XLEN(val); \
+ inst destreg, reg; \
+ )
+
+#define TEST_FP_I2(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FP_I2(test_num, destreg, reg, correctval, val, swreg, offset, \
+ inst destreg, reg; \
+ )
+
+//Tests for floating point instructions - double precision
+#define TEST_FPD_OP(test_num, inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset) \
+ TEST_CASE_FPD(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, \
+ inst destreg, reg1, reg2; \
+ )
+
+#define TEST_FPD_ONEREG(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FPD(test_num, destreg, reg, reg, correctval, val, val, swreg, offset, \
+ inst destreg, reg; \
+ )
+
+#define TEST_FPD_4REG(test_num, inst, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset) \
+ TEST_CASE_FPD_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, \
+ inst destreg, reg1, reg2, reg3; \
+ )
+
+#define TEST_FPD_I(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FPD_I(test_num, destreg, reg, correctval, val, swreg, offset, \
+ li reg, MASK_XLEN(val); \
+ inst destreg, reg; \
+ )
+
+#define TEST_FPD_I2(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FPD_I2(test_num, destreg, reg, correctval, val, swreg, offset, \
+ inst destreg, reg; \
+ )
+
+#define TEST_CADDI16SP(correctval, imm, swreg, offset, testreg) \
+ TEST_CASE(testreg,x2, correctval, swreg, offset, \
+ c.addi16sp x2, imm; \
+ )
+
+#define TEST_CADDI4SPN(destreg, correctval, imm, swreg, offset, testreg) \
+ TEST_CASE(testreg,destreg, correctval, swreg, offset, \
+ c.addi4spn destreg, x2, SEXT_IMM(imm); \
+ )
+
+#define TEST_CJL(inst, reg, val, swreg, offset) \
+ li x10, val; \
+ la reg, 1f; \
+ inst reg; \
+ li x10, 0x123ab; \
+1: \
+ sw x10, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, x10, val); \
+
+#define ABS(x) ((x >> 11) ^ x) - (x >> 11)
+
+#define TEST_CJ(inst, reg, val, swreg, offset) \
+ li reg, val; \
+ inst 1f; \
+ li reg, 0x123ab; \
+1: \
+ sw reg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, reg, val); \
+
+#define TEST_CL(inst, reg, imm, swreg, offset) \
+ la reg, test_data; \
+ inst reg, imm(reg); \
+ sw reg, offset(swreg); \
+
+// lw reg, imm(x2)
+// c.lwsp reg, imm(x2)
+#define TEST_CLWSP(reg, imm, swreg, offset) \
+ la x2, test_data; \
+ c.lwsp reg, imm(x2); \
+ sw reg, offset(swreg); \
+
+#define TEST_CSW(test_data, inst, reg1, reg2, val, imm, swreg, offset) \
+ li reg1, val; \
+ la reg2, test_data; \
+ inst reg1, imm(reg2); \
+ lw reg1, imm(reg2); \
+ sw reg1, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, reg1, val); \
+
+#define TEST_CSWSP(test_data, reg, val, imm, swreg, offset) \
+ la x2, test_data; \
+ li reg, val; \
+ c.swsp reg, imm(x2); \
+ lw reg, imm(x2); \
+ sw reg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, reg, val); \
+
+#define TEST_CBEQZ(reg, val, swreg, offset) \
+ li reg, val; \
+ c.sub reg, reg; \
+ c.beqz reg, 3f; \
+ li reg, 0x123ab; \
+3: \
+ sw reg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, reg, 0x0); \
+
+#define TEST_CBNEZ(reg, val, swreg, offset) \
+ li reg, val; \
+ c.bnez reg, 4f; \
+ li reg, 0x0; \
+4: \
+ sw reg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, reg, val); \
+
+#define TEST_FMVXS(test_num, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FP_FMVXS(test_num, destreg, reg, correctval, val, swreg, offset, \
+ fmv.x.s destreg, reg; \
+ )
+
+#define TEST_FMVSX(test_num, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FP_FMVSX(test_num, destreg, reg, correctval, val, swreg, offset, \
+ fmv.s.x destreg, reg; \
+ )
+
+#define SWSIG(a,b)
+
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/test_macros.h b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/test_macros.h
new file mode 100644
index 0000000..b2c610e
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/riscv_compliance/test_macros.h
@@ -0,0 +1,593 @@
+
+// RISC-V Compliance Test Header File
+// Copyright (c) 2017, Codasip Ltd. All Rights Reserved.
+// See LICENSE for license details.
+//
+// Description: Common header file for RV32I tests
+
+#ifndef _TEST_MACROS_H
+#define _TEST_MACROS_H
+
+#include "riscv_macros.h"
+
+// RISC-V Compliance IO Test Header File
+
+/*
+ * Copyright (c) 2005-2018 Imperas Software Ltd., www.imperas.com
+ *
+ * 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.
+ *
+ */
+
+
+//
+// In general the following registers are reserved
+// ra, a0, t0, t1
+// Additionally on an assertion violation, t1, t2 are overwritten
+// x1, x10, x5, x6, x7 respectively
+// Floating registers reserved
+// f5
+//
+
+#define MASK_XLEN(x) ((x) & ((1 << (__riscv_xlen - 1) << 1) - 1))
+
+#define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11))
+
+// Base function for integer operations
+#define TEST_CASE(destreg, correctval, swreg, offset, code... ) \
+ code; \
+ sw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+
+// Base functions for single precision floating point operations
+#define TEST_CASE_FP(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ flw reg1, 0(a0); \
+ flw reg2, 4(a0); \
+ lw t1, 8(a0); \
+ code; \
+ fsw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_SFPR_EQ(destreg, t1, correctval) \
+ .pushsection .data; \
+ .balign 8; \
+ test_ ## test_num ## _data: \
+ .float val1; \
+ .float val2; \
+ .word correctval; \
+ .popsection
+
+#define TEST_CASE_FP_I(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ lw t1, 0(a0); \
+ code; \
+ fsw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_SFPR_EQ(destreg, t1, correctval) \
+ .pushsection .data; \
+ .balign 2; \
+ test_ ## test_num ## _data: \
+ .word correctval; \
+ .popsection
+
+#define TEST_CASE_FP_I2(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ flw reg, 0(a0); \
+ lw t1, 4(a0); \
+ code; \
+ sw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+ .pushsection .data; \
+ .balign 4; \
+ test_ ## test_num ## _data: \
+ .float val; \
+ .word correctval; \
+ .popsection
+
+#define TEST_CASE_FP_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ flw reg1, 0(a0); \
+ flw reg2, 4(a0); \
+ flw reg3, 8(a0); \
+ lw t1, 12(a0); \
+ code; \
+ fsw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_SFPR_EQ(destreg, t1, correctval) \
+ .pushsection .data; \
+ .balign 16; \
+ test_ ## test_num ## _data: \
+ .float val1; \
+ .float val2; \
+ .float val3; \
+ .word correctval; \
+ .popsection
+
+#define TEST_CASE_FP_FMVXS(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ flw reg, 0(a0); \
+ code; \
+ sw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+ .pushsection .data; \
+ .balign 2; \
+ test_ ## test_num ## _data: \
+ .float val; \
+ .popsection
+
+#define TEST_CASE_FP_FMVSX(test_num, destreg, reg, correctval, val, swreg, offset, code...) \
+ la a0, test_ ## test_num ## _data; \
+ li reg, val; \
+ code; \
+ fsw destreg, offset(swreg); \
+ lw a1, 0(a0); \
+ RVTEST_IO_ASSERT_SFPR_EQ(destreg, a1, correctval) \
+ .pushsection .data; \
+ .balign 2; \
+ test_ ## test_num ## _data: \
+ .word correctval; \
+ .popsection
+
+// Base functions for double precision floating point operations - rv32d
+#define TEST_CASE_FPD(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ fld reg1, 0(a0); \
+ fld reg2, 8(a0); \
+ code; \
+ fsd destreg, offset(swreg); \
+ lw t1, 16(a0); \
+ lw t2, 20(a0); \
+ la a0, store_ ## test_num ## _data; \
+ fsd destreg, 0(a0); \
+ lw a1, 0(a0); \
+ lw a2, 4(a0); \
+ RVTEST_IO_ASSERT_DFPR_EQ(destreg, t2, t1, a2, a1, correctval) \
+ .pushsection .data; \
+ .balign 8; \
+ test_ ## test_num ## _data: \
+ .double val1; \
+ .double val2; \
+ .dword correctval; \
+ .popsection; \
+ .pushsection .data; \
+ store_ ## test_num ## _data: \
+ .fill 1, 8, -1; \
+ .popsection
+
+#define TEST_CASE_FPD_I(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ code; \
+ fsd destreg, offset(swreg); \
+ lw t1, 0(a0); \
+ lw t2, 4(a0); \
+ la a0, store_ ## test_num ## _data; \
+ fsd destreg, 0(a0); \
+ lw a1, 0(a0); \
+ lw a2, 4(a0); \
+ RVTEST_IO_ASSERT_DFPR_EQ(destreg, t2, t1, a2, a1, correctval) \
+ .pushsection .data; \
+ .balign 2; \
+ test_ ## test_num ## _data: \
+ .dword correctval; \
+ .popsection; \
+ store_ ## test_num ## _data: \
+ .fill 1, 8, -1; \
+ .popsection
+
+#define TEST_CASE_FPD_I2(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ fld reg, 0(a0); \
+ lw t1, 8(a0); \
+ code; \
+ sw destreg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+ .pushsection .data; \
+ .balign 4; \
+ test_ ## test_num ## _data: \
+ .double val; \
+ .word correctval; \
+ .popsection
+
+#define TEST_CASE_FPD_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, code... ) \
+ la a0, test_ ## test_num ## _data; \
+ fld reg1, 0(a0); \
+ fld reg2, 8(a0); \
+ fld reg3, 16(a0); \
+ code; \
+ fsd destreg, offset(swreg); \
+ lw t1, 24(a0); \
+ lw t2, 28(a0); \
+ la a0, store_ ## test_num ## _data; \
+ fsd destreg, 0(a0); \
+ lw a1, 0(a0); \
+ lw a2, 4(a0); \
+ RVTEST_IO_ASSERT_DFPR_EQ(destreg, t2, t1, a2, a1, correctval) \
+ .pushsection .data; \
+ .balign 16; \
+ test_ ## test_num ## _data: \
+ .double val1; \
+ .double val2; \
+ .double val3; \
+ .dword correctval; \
+ .popsection; \
+ .pushsection .data; \
+ store_ ## test_num ## _data: \
+ .fill 1, 8, -1; \
+ .popsection
+
+//Tests for a instructions with register-register operand
+#define TEST_RR_OP(inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset) \
+ TEST_CASE( destreg, correctval, swreg, offset, \
+ li reg1, MASK_XLEN(val1); \
+ li reg2, MASK_XLEN(val2); \
+ inst destreg, reg1, reg2; \
+ )
+
+#define TEST_RR_SRC1( inst, destreg, reg, correctval, val1, val2, swreg, offset) \
+ TEST_CASE( destreg, correctval, swreg, offset, \
+ li destreg, MASK_XLEN(val1); \
+ li reg, MASK_XLEN(val2); \
+ inst destreg, destreg, reg; \
+ )
+
+#define TEST_RR_SRC2( inst, destreg, reg, correctval, val1, val2, swreg, offset) \
+ TEST_CASE( destreg, correctval, swreg, offset, \
+ li reg, MASK_XLEN(val1); \
+ li destreg, MASK_XLEN(val2); \
+ inst destreg, reg, destreg; \
+ )
+
+#define TEST_RR_SRC12( inst, destreg, correctval, val, swreg, offset) \
+ TEST_CASE( destreg, correctval, swreg, offset, \
+ li destreg, MASK_XLEN(val1); \
+ inst destreg, destreg, destreg; \
+ )
+
+#define TEST_RR_ZERO1( inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE( destreg, correctval, swreg, offset, \
+ li reg, MASK_XLEN(val); \
+ inst destreg, x0, reg; \
+ )
+
+#define TEST_RR_ZERO2( inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE( destreg, correctval, swreg, offset, \
+ li reg, MASK_XLEN(val); \
+ inst destreg, reg, x0; \
+ )
+
+#define TEST_RR_ZERO12( inst, destreg, correctval, swreg, offset) \
+ TEST_CASE( destreg, correctval, swreg, offset, \
+ inst destreg, x0, x0; \
+ )
+
+#define TEST_RR_ZERODEST( inst, reg1, reg2, val1, val2, swreg, offset) \
+ TEST_CASE( x0, 0, swreg, offset, \
+ li reg1, MASK_XLEN(val1); \
+ li reg2, MASK_XLEN(val2); \
+ inst x0, reg1, reg2; \
+ )
+
+//Tests for a instructions with register-immediate operand
+#define TEST_IMM_OP( inst, destreg, reg, correctval, val, imm, swreg, offset) \
+ TEST_CASE ( destreg, correctval, swreg, offset, \
+ li reg, MASK_XLEN(val); \
+ inst destreg, reg, SEXT_IMM(imm); \
+ )
+
+#define TEST_IMM_SRC( inst, destreg, correctval, val, imm, swreg, offset) \
+ TEST_CASE ( destreg, correctval, swreg, offset, \
+ li destreg, MASK_XLEN(val); \
+ inst destreg, destreg, SEXT_IMM(imm); \
+ )
+
+#define TEST_IMM_ZEROSRC( inst, destreg, correctval, imm, swreg, offset) \
+ TEST_CASE ( destreg, correctval, swreg, offset, \
+ inst destreg, x0, SEXT_IMM(imm); \
+ )
+
+#define TEST_IMM_ZERODEST( inst, reg, val, imm, swreg, offset) \
+ TEST_CASE ( x0, 0, swreg, offset, \
+ li reg, MASK_XLEN(val); \
+ inst x0, reg, SEXT_IMM(imm); \
+ )
+
+#define TEST_IMM_ONEREG( inst, destreg, correctval, imm, swreg, offset) \
+ TEST_CASE ( destreg, correctval, swreg, offset, \
+ inst destreg, SEXT_IMM(imm); \
+ )
+
+#define TEST_AUIPC(inst, destreg, correctval, imm, swreg, offset) \
+ TEST_CASE ( destreg, correctval, swreg, offset, \
+ 1: \
+ inst destreg, SEXT_IMM(imm); \
+ la swreg, 1b; \
+ sub destreg, destreg, swreg; \
+ )
+
+//Tests for a compressed instruction
+#define TEST_CR_OP( inst, destreg, reg, correctval, val1, val2, swreg, offset) \
+ TEST_CASE ( destreg, correctval, swreg, offset, \
+ li reg, MASK_XLEN(val1); \
+ li destreg, MASK_XLEN(val2); \
+ inst destreg, reg; \
+ )
+
+#define TEST_CI_OP( inst, destreg, correctval, val, imm, swreg, offset) \
+ TEST_CASE( destreg, correctval, swreg, offset, \
+ li destreg, MASK_XLEN(val); \
+ inst destreg, imm; \
+ )
+
+#define TEST_CI_OP_NOREG(inst, correctval, imm, swreg, offset) \
+ TEST_CASE (x0, correctval, swreg, offset, \
+ inst imm; \
+ )
+
+//Tests for floating point instructions - single precision
+#define TEST_FP_OP(test_num, inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset) \
+ TEST_CASE_FP(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, \
+ inst destreg, reg1, reg2; \
+ )
+
+#define TEST_FP_ONEREG(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FP(test_num, destreg, reg, reg, correctval, val, val, swreg, offset, \
+ inst destreg, reg; \
+ )
+
+#define TEST_FP_4REG(test_num, inst, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset) \
+ TEST_CASE_FP_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, \
+ inst destreg, reg1, reg2, reg3; \
+ )
+
+#define TEST_FP_I(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FP_I(test_num, destreg, reg, correctval, val, swreg, offset, \
+ li reg, MASK_XLEN(val); \
+ inst destreg, reg; \
+ )
+
+#define TEST_FP_I2(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FP_I2(test_num, destreg, reg, correctval, val, swreg, offset, \
+ inst destreg, reg; \
+ )
+
+//Tests for floating point instructions - double precision
+#define TEST_FPD_OP(test_num, inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset) \
+ TEST_CASE_FPD(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, \
+ inst destreg, reg1, reg2; \
+ )
+
+#define TEST_FPD_ONEREG(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FPD(test_num, destreg, reg, reg, correctval, val, val, swreg, offset, \
+ inst destreg, reg; \
+ )
+
+#define TEST_FPD_4REG(test_num, inst, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset) \
+ TEST_CASE_FPD_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, \
+ inst destreg, reg1, reg2, reg3; \
+ )
+
+#define TEST_FPD_I(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FPD_I(test_num, destreg, reg, correctval, val, swreg, offset, \
+ li reg, MASK_XLEN(val); \
+ inst destreg, reg; \
+ )
+
+#define TEST_FPD_I2(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FPD_I2(test_num, destreg, reg, correctval, val, swreg, offset, \
+ inst destreg, reg; \
+ )
+
+#define TEST_CADDI16SP(correctval, imm, swreg, offset) \
+ TEST_CASE(x2, correctval, swreg, offset, \
+ c.addi16sp x2, imm; \
+ )
+
+#define TEST_CADDI4SPN(destreg, correctval, imm, swreg, offset) \
+ TEST_CASE(destreg, correctval, swreg, offset, \
+ c.addi4spn destreg, x2, SEXT_IMM(imm); \
+ )
+
+#define TEST_CJL(inst, reg, val, swreg, offset) \
+ li x10, val; \
+ la reg, 1f; \
+ inst reg; \
+ li x10, 0x123ab; \
+1: \
+ sw x10, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, x10, val); \
+
+#define ABS(x) ((x >> 11) ^ x) - (x >> 11)
+
+#define TEST_CJ(inst, reg, val, swreg, offset) \
+ li reg, val; \
+ inst 1f; \
+ li reg, 0x123ab; \
+1: \
+ sw reg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, reg, val); \
+
+#define TEST_CL(inst, reg, imm, swreg, offset) \
+ la reg, test_data; \
+ inst reg, imm(reg); \
+ sw reg, offset(swreg); \
+
+// lw reg, imm(x2)
+// c.lwsp reg, imm(x2)
+#define TEST_CLWSP(reg, imm, swreg, offset) \
+ la x2, test_data; \
+ c.lwsp reg, imm(x2); \
+ sw reg, offset(swreg); \
+
+#define TEST_CSW(test_data, inst, reg1, reg2, val, imm, swreg, offset) \
+ li reg1, val; \
+ la reg2, test_data; \
+ inst reg1, imm(reg2); \
+ lw reg1, imm(reg2); \
+ sw reg1, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, reg1, val); \
+
+#define TEST_CSWSP(test_data, reg, val, imm, swreg, offset) \
+ la x2, test_data; \
+ li reg, val; \
+ c.swsp reg, imm(x2); \
+ lw reg, imm(x2); \
+ sw reg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, reg, val); \
+
+#define TEST_CBEQZ(reg, val, swreg, offset) \
+ li reg, val; \
+ c.sub reg, reg; \
+ c.beqz reg, 3f; \
+ li reg, 0x123ab; \
+3: \
+ sw reg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, reg, 0x0); \
+
+#define TEST_CBNEZ(reg, val, swreg, offset) \
+ li reg, val; \
+ c.bnez reg, 4f; \
+ li reg, 0x0; \
+4: \
+ sw reg, offset(swreg); \
+ RVTEST_IO_ASSERT_GPR_EQ(x31, reg, val); \
+
+#define TEST_FMVXS(test_num, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FP_FMVXS(test_num, destreg, reg, correctval, val, swreg, offset, \
+ fmv.x.s destreg, reg; \
+ )
+
+#define TEST_FMVSX(test_num, destreg, reg, correctval, val, swreg, offset) \
+ TEST_CASE_FP_FMVSX(test_num, destreg, reg, correctval, val, swreg, offset, \
+ fmv.s.x destreg, reg; \
+ )
+
+#define SWSIG(a,b)
+
+
+#if __riscv_xlen == 64
+#define SATP_MODE SATP64_MODE
+#else
+#define SATP_MODE SATP32_MODE
+#endif
+
+#define SATP32_MODE 0x80000000
+#define SATP32_ASID 0x7FC00000
+#define SATP32_PPN 0x003FFFFF
+#define SATP64_MODE 0xF000000000000000
+#define SATP64_ASID 0x0FFFF00000000000
+#define SATP64_PPN 0x00000FFFFFFFFFFF
+
+#define SATP_MODE_OFF 0
+#define SATP_MODE_SV32 1
+#define SATP_MODE_SV39 8
+#define SATP_MODE_SV48 9
+#define SATP_MODE_SV57 10
+#define SATP_MODE_SV64 11
+
+#define TEST_FP_OP2_D32( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
+ inst f3, f0, f1; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
+#define TEST_CASE_D32( testnum, testreg1, testreg2, correctval, code... ) \
+test_ ## testnum: \
+ code; \
+ la x31, test_ ## testnum ## _data ; \
+ lw x29, 0(x31); \
+ lw x31, 4(x31); \
+ li TESTNUM, testnum; \
+ bne testreg1, x29, fail;\
+ bne testreg2, x31, fail;\
+ .pushsection .data; \
+ .balign 8; \
+ test_ ## testnum ## _data: \
+ .dword correctval; \
+ .popsection
+
+#define TEST_FP_OP_D32_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ la a0, test_ ## testnum ## _data ;\
+ fld f0, 0(a0); \
+ fld f1, 8(a0); \
+ fld f2, 16(a0); \
+ lw a3, 24(a0); \
+ lw t1, 28(a0); \
+ code; \
+ fsflags a1, x0; \
+ li a2, flags; \
+ bne a0, a3, fail; \
+ bne t1, t2, fail; \
+ bne a1, a2, fail; \
+ .pushsection .data; \
+ .balign 8; \
+ test_ ## testnum ## _data: \
+ .double val1; \
+ .double val2; \
+ .double val3; \
+ .result; \
+ .popsection
+
+#define TEST_FP_OP1_D32( testnum, inst, flags, result, val1 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \
+ inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
+#define TEST_FCLASS_D32(testnum, correct, input) \
+ TEST_CASE(testnum, a0, correct, \
+ la a0, test_ ## testnum ## _data ;\
+ fld fa0, 0(a0); \
+ fclass.d a0, fa0) \
+ .pushsection .data; \
+ .balign 8; \
+ test_ ## testnum ## _data: \
+ .dword input; \
+ .popsection
+
+#define TEST_FP_CMP_OP_D32( testnum, inst, flags, result, val1, val2 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \
+ inst a0, f0, f1; li t2, 0)
+
+#define TEST_INT_FP_OP_D32( testnum, inst, result, val1 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ la a0, test_ ## testnum ## _data ;\
+ lw a3, 0(a0); \
+ lw a4, 4(a0); \
+ li a1, val1; \
+ inst f0, a1; \
+ \
+ fsd f0, 0(a0); \
+ lw a1, 4(a0); \
+ lw a0, 0(a0); \
+ \
+ fsflags x0; \
+ bne a0, a3, fail; \
+ bne a1, a4, fail; \
+ .pushsection .data; \
+ .balign 8; \
+ test_ ## testnum ## _data: \
+ .double result; \
+ .popsection
+
+#define TEST_FCVT_S_D32( testnum, result, val1 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \
+ fcvt.s.d f3, f0; fcvt.d.s f3, f3; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
+#define TEST_FP_OP3_D32( testnum, inst, flags, result, val1, val2, val3 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, val3, \
+ inst f3, f0, f1, f2; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
+#define TEST_FP_OP1_D32_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
+ TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+ inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
+
+#endif
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/riscv_isa/Makefile b/verilog/rtl/syntacore/scr1/sim/tests/riscv_isa/Makefile
new file mode 100644
index 0000000..945519c
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/riscv_isa/Makefile
@@ -0,0 +1,96 @@
+
+include rv32_tests.inc
+
+ARCH_tmp := imf
+
+ifneq (,$(findstring c,$(ARCH_lowercase)))
+ ARCH_tmp := $(ARCH_tmp)c
+endif
+
+override ARCH := $(ARCH_tmp)
+
+src_dir := $(CURDIR)
+obj_dir := $(bld_dir)/riscv_objs
+test_list := $(patsubst %.S, %, $(notdir $(rv32_isa_tests)))
+objs := $(addprefix $(obj_dir)/,$(test_list:%=%.o))
+test_elf := $(addprefix $(bld_dir)/,$(test_list:%=%.elf))
+test_hex := $(addprefix $(bld_dir)/,$(test_list:%=%.hex))
+test_dump := $(addprefix $(bld_dir)/,$(test_list:%=%.dump))
+
+CFLAGS := -I$(inc_dir) -I$(src_dir) -DASM -Wa,-march=rv32$(ARCH) -march=rv32$(ARCH) -mabi=ilp32f -D__riscv_xlen=32
+LDFLAGS := -static -fvisibility=hidden -nostdlib -nostartfiles -T$(inc_dir)/link.ld -march=rv32$(ARCH) -mabi=ilp32f
+RISCV_TESTS := $(src_dir)/../../../dependencies/riscv-tests/
+
+VPATH += $(src_dir) $(bld_dir) $(obj_dir) $(RISCV_TESTS)
+
+default: log_requested_tgt check_riscv_tests $(test_elf) $(test_hex) $(test_dump)
+
+define compile_template
+$(obj_dir)/$$(basename $(notdir $(SRC))).o: $$(SRC) | $(obj_dir)
+ $(RISCV_GCC) -c $$< $(CFLAGS) -o $$@
+ endef
+
+$(foreach SRC,$(rv32_isa_tests), $(eval $(compile_template)))
+
+log_requested_tgt:
+ $(foreach test_name, $(test_list), $(eval $(shell echo $(test_name).hex >> $(bld_dir)/test_info)))
+
+$(obj_dir) :
+ mkdir -p $(obj_dir)
+
+$(bld_dir)/%.elf: $(obj_dir)/%.o | $(obj_dir)
+ $(RISCV_GCC) $^ $(LDFLAGS) -o $@
+
+$(bld_dir)/%.hex: $(bld_dir)/%.elf
+ $(RISCV_ROM_OBJCOPY) $^ $@
+ $(RISCV_RAM_OBJCOPY) $^ $@.ram
+ #assign 0x2000_0xxx to 0x0000_0xxx to map to sdram
+ sed -i 's/@20000/@00000/g' $@.ram
+
+$(bld_dir)/%.dump: $(bld_dir)/%.elf
+ $(RISCV_OBJDUMP) $^ > $@
+
+clean:
+ $(RM) $(test_elf) $(test_hex) $(test_dump) $(objs)
+ $(RM) -R $(obj_dir)
+
+
+.PHONY: check_riscv_tests
+
+riscv_tests_dir := $(if $(RISCV_TESTS), $(RISCV_TESTS), ./undefined)
+riscv_tests_commit := 5f8a4918c6482e65c67a2b7decd5c2af3e3fe0e5
+## commit hash readed from local copy of https://github.com/riscv/riscv-tests
+tmp_commit = $(shell cd $(riscv_tests_dir) 2>/dev/null && git log -1 | grep "commit" | cut -f2 -d ' ')
+is_commit_good = $(if $(subst $(riscv_tests_commit),,$(tmp_commit)),false,true)
+
+# Color
+RED=\033[0;31m
+NC=\033[0m
+
+check_riscv_tests : $(riscv_tests_dir)
+ @if [ ! -d $(riscv_tests_dir) ]; then \
+ echo -e "$(RED)==========================================================================" &&\
+ echo " Error! Environment variable RISCV_TESTS='$(riscv_tests_dir)' " &&\
+ echo " directory not exist!" && \
+ echo "==========================================================================$(NC)" ; \
+ fi
+ifneq ($(is_commit_good),true)
+ @echo -e "$(RED)=========================================================================="
+ @echo " Warning! Execution of test code is not guaranteed "
+ @echo " while using the current commit of repositorylocated at : $(riscv_tests_dir) ."
+ @echo " "
+ @echo " Riscv-tests repository must point to commit $(riscv_tests_commit)!"
+ @echo -e "==========================================================================$(NC)"
+endif
+
+$(riscv_tests_dir) :.
+ifndef RISCV_TESTS
+ @echo -e "$(RED)=========================================================================="
+ @echo " Error! Environment variable RISCV_TESTS not set!"
+ @echo " You must set the environment variable RISCV_TESTS"
+ @echo " The variable should point to the local copy of the"
+ @echo " repository https://github.com/riscv/riscv-tests"
+ @echo " with the commit $(riscv_tests_commit)"
+ @echo -e "==========================================================================$(NC)"
+ exit 1
+endif
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/riscv_isa/riscv_test.h b/verilog/rtl/syntacore/scr1/sim/tests/riscv_isa/riscv_test.h
new file mode 100644
index 0000000..2b9ce0d
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/riscv_isa/riscv_test.h
@@ -0,0 +1,6 @@
+#ifndef __RISCV__TEST__H
+#define __RISCV__TEST__H
+
+#include "riscv_macros.h"
+
+#endif // #ifndef __RISCV__TEST__H
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/riscv_isa/rv32_tests.inc b/verilog/rtl/syntacore/scr1/sim/tests/riscv_isa/rv32_tests.inc
new file mode 100644
index 0000000..62e5012
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/riscv_isa/rv32_tests.inc
@@ -0,0 +1,66 @@
+
+ARCH_lowercase = $(shell echo $(ARCH) | tr A-Z a-z)
+
+
+rv32_isa_tests += isa/rv32ui/add.S \
+ isa/rv32ui/addi.S \
+ isa/rv32ui/and.S \
+ isa/rv32ui/andi.S \
+ isa/rv32ui/auipc.S \
+ isa/rv32ui/beq.S \
+ isa/rv32ui/bge.S \
+ isa/rv32ui/bgeu.S \
+ isa/rv32ui/blt.S \
+ isa/rv32ui/bltu.S \
+ isa/rv32ui/bne.S \
+ isa/rv32mi/csr.S \
+ isa/rv32ui/fence_i.S \
+ isa/rv32mi/illegal.S \
+ isa/rv32ui/jal.S \
+ isa/rv32ui/jalr.S \
+ isa/rv32ui/lb.S \
+ isa/rv32ui/lbu.S \
+ isa/rv32ui/lh.S \
+ isa/rv32ui/lhu.S \
+ isa/rv32ui/lui.S \
+ isa/rv32ui/lw.S \
+ isa/rv32mi/ma_addr.S \
+ isa/rv32mi/ma_fetch.S \
+ isa/rv32mi/mcsr.S \
+ isa/rv32ui/or.S \
+ isa/rv32ui/ori.S \
+ isa/rv32ui/sb.S \
+ isa/rv32mi/sbreak.S \
+ isa/rv32mi/scall.S \
+ isa/rv32ui/sh.S \
+ isa/rv32mi/shamt.S \
+ isa/rv32ui/simple.S \
+ isa/rv32ui/sll.S \
+ isa/rv32ui/slli.S \
+ isa/rv32ui/slt.S \
+ isa/rv32ui/slti.S \
+ isa/rv32ui/sltiu.S \
+ isa/rv32ui/sltu.S \
+ isa/rv32ui/sra.S \
+ isa/rv32ui/srai.S \
+ isa/rv32ui/srl.S \
+ isa/rv32ui/srli.S \
+ isa/rv32ui/sub.S \
+ isa/rv32ui/sw.S \
+ isa/rv32ui/xor.S \
+ isa/rv32ui/xori.S
+
+ifneq (,$(findstring m,$(ARCH_lowercase)))
+rv32_isa_tests += isa/rv32um/div.S \
+ isa/rv32um/divu.S \
+ isa/rv32um/mul.S \
+ isa/rv32um/mulh.S \
+ isa/rv32um/mulhsu.S \
+ isa/rv32um/mulhu.S \
+ isa/rv32um/rem.S \
+ isa/rv32um/remu.S
+endif ## ifeq (m,$(findstring m,$(ARCH_lowercase)))
+
+ifneq (,$(findstring c,$(ARCH_lowercase)))
+rv32_isa_tests += isa/rv32uc/rvc.S
+endif ## ifeq (m,$(findstring c,$(ARCH_lowercase)))
\ No newline at end of file
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/riscv_isa/test_macros.h b/verilog/rtl/syntacore/scr1/sim/tests/riscv_isa/test_macros.h
new file mode 100644
index 0000000..743918d
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/riscv_isa/test_macros.h
@@ -0,0 +1,5 @@
+#ifndef __TEST__MACROS__H
+#define __TEST__MACROS__H
+
+
+#endif