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