test bench update
diff --git a/verilog/dv/Makefile b/verilog/dv/Makefile
index d87238f..5028dd6 100644
--- a/verilog/dv/Makefile
+++ b/verilog/dv/Makefile
@@ -19,7 +19,7 @@
.SUFFIXES:
.SILENT: clean all
-PATTERNS = io_ports la_test1 la_test2 wb_port mprj_stimulus
+PATTERNS = io_ports la_test1 la_test2 wb_port mprj_stimulus risc_boot user_risc_boot
all: ${PATTERNS}
for i in ${PATTERNS}; do \
diff --git a/verilog/dv/io_ports/Makefile b/verilog/dv/io_ports/Makefile
index 0ef079e..baeb372 100644
--- a/verilog/dv/io_ports/Makefile
+++ b/verilog/dv/io_ports/Makefile
@@ -25,7 +25,9 @@
## User Project Pointers
UPRJ_VERILOG_PATH ?= ../../../verilog
UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl
-UPRJ_BEHAVIOURAL_MODELS = ../
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
## RISCV GCC
GCC_PATH?=/ef/apps/bin
@@ -43,11 +45,14 @@
hex: ${PATTERN:=.hex}
+vvp: ${PATTERN:=.vvp}
+
%.vvp: %_tb.v %.hex
ifeq ($(SIM),RTL)
- iverilog -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+ 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_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) \
$< -o $@
else
iverilog -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
diff --git a/verilog/dv/io_ports/io_ports_tb.v b/verilog/dv/io_ports/io_ports_tb.v
index f7628bc..5cca0c8 100644
--- a/verilog/dv/io_ports/io_ports_tb.v
+++ b/verilog/dv/io_ports/io_ports_tb.v
@@ -49,8 +49,10 @@
end
initial begin
- $dumpfile("io_ports.vcd");
- $dumpvars(0, io_ports_tb);
+ `ifdef WFDUMP
+ $dumpfile("io_ports.vcd");
+ $dumpvars(0, io_ports_tb);
+ `endif
// Repeat cycles of 1000 clock edges as needed to complete testbench
repeat (25) begin
diff --git a/verilog/dv/io_ports/mgmt_core.sv b/verilog/dv/io_ports/mgmt_core.sv
new file mode 100644
index 0000000..debedf0
--- /dev/null
+++ b/verilog/dv/io_ports/mgmt_core.sv
@@ -0,0 +1,153 @@
+// 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
+
+`default_nettype none
+module mgmt_core (
+`ifdef USE_POWER_PINS
+ inout VPWR,
+ inout VGND,
+`endif
+ // GPIO (dedicated pad)
+ output gpio_out_pad, // Connect to out on gpio pad
+ input gpio_in_pad, // Connect to in on gpio pad
+ output gpio_mode0_pad, // Connect to dm[0] on gpio pad
+ output gpio_mode1_pad, // Connect to dm[2] on gpio pad
+ output gpio_outenb_pad, // Connect to oe_n on gpio pad
+ output gpio_inenb_pad, // Connect to inp_dis on gpio pad
+ // Flash memory control (SPI master)
+ output flash_csb,
+ output flash_clk,
+ output flash_csb_oeb,
+ output flash_clk_oeb,
+ output flash_io0_oeb,
+ output flash_io1_oeb,
+ output flash_io2_oeb, // through GPIO 36
+ output flash_io3_oeb, // through GPIO 37
+ output flash_csb_ieb,
+ output flash_clk_ieb,
+ output flash_io0_ieb,
+ output flash_io1_ieb,
+ output flash_io0_do,
+ output flash_io1_do,
+ output flash_io2_do, // through GPIO 36
+ output flash_io3_do, // through GPIO 37
+ input flash_io0_di,
+ input flash_io1_di,
+ // Master reset
+ input resetb,
+ input porb,
+ // Clocking
+ input clock,
+ // LA signals
+ input [127:0] la_input, // From User Project to cpu
+ output [127:0] la_output, // From CPU to User Project
+ output [127:0] la_oenb, // LA output enable
+ output [127:0] la_iena, // LA input enable
+ // Housekeeping SPI
+ output sdo_out,
+ output sdo_outenb,
+ // JTAG
+ output jtag_out,
+ output jtag_outenb,
+ // User Project Control Signals
+ input [`MPRJ_IO_PADS-1:0] mgmt_in_data,
+ output [`MPRJ_IO_PADS-1:0] mgmt_out_data,
+ output [`MPRJ_PWR_PADS-1:0] pwr_ctrl_out,
+ input mprj_vcc_pwrgood,
+ input mprj2_vcc_pwrgood,
+ input mprj_vdd_pwrgood,
+ input mprj2_vdd_pwrgood,
+ output mprj_io_loader_resetn,
+ output mprj_io_loader_clock,
+ output mprj_io_loader_data_1,
+ output mprj_io_loader_data_2,
+ // WB MI A (User project)
+ input mprj_ack_i,
+ input [31:0] mprj_dat_i,
+ output mprj_cyc_o,
+ output mprj_stb_o,
+ output mprj_we_o,
+ output [3:0] mprj_sel_o,
+ output [31:0] mprj_adr_o,
+ output [31:0] mprj_dat_o,
+
+ output core_clk,
+ output user_clk,
+ output core_rstn,
+ input [2:0] user_irq,
+ output [2:0] user_irq_ena,
+
+ // Metal programmed user ID / mask revision vector
+ input [31:0] mask_rev,
+
+ // MGMT area R/W interface for mgmt RAM
+ output [`RAM_BLOCKS-1:0] mgmt_ena,
+ output [(`RAM_BLOCKS*4)-1:0] mgmt_wen_mask,
+ output [`RAM_BLOCKS-1:0] mgmt_wen,
+ output [7:0] mgmt_addr,
+ output [31:0] mgmt_wdata,
+ input [(`RAM_BLOCKS*32)-1:0] mgmt_rdata,
+
+ // MGMT area RO interface for user RAM
+ output mgmt_ena_ro,
+ output [7:0] mgmt_addr_ro,
+ input [31:0] mgmt_rdata_ro
+);
+ wire ext_clk_sel;
+ wire pll_clk, pll_clk90;
+ wire ext_reset;
+ wire hk_connect;
+ wire trap;
+ wire irq_spi;
+
+ // JTAG (to be implemented)
+ wire jtag_out;
+ wire jtag_out_pre = 1'b0;
+ wire jtag_outenb = 1'b1;
+ wire jtag_oenb_state;
+
+ // SDO
+ wire sdo_out;
+ wire sdo_out_pre;
+ wire sdo_oenb_state;
+
+ // Housekeeping SPI vectors
+ wire [4:0] spi_pll_div;
+ wire [2:0] spi_pll_sel;
+ wire [2:0] spi_pll90_sel;
+ wire [25:0] spi_pll_trim;
+
+ // Override default function for SDO and JTAG outputs if purposely
+ // set for override by the management SoC.
+ assign sdo_out = (sdo_oenb_state == 1'b0) ? mgmt_out_data[1] : sdo_out_pre;
+ assign jtag_out = (jtag_oenb_state == 1'b0) ? mgmt_out_data[0] : jtag_out_pre;
+
+ caravel_clocking clocking1(
+ .ext_clk_sel(ext_clk_sel),
+ .ext_clk(clock),
+ .pll_clk(pll_clk),
+ .pll_clk90(pll_clk90),
+ .resetb(resetb),
+ .sel(spi_pll_sel),
+ .sel2(spi_pll90_sel),
+ .ext_reset(ext_reset), // From housekeeping SPI
+ .core_clk(core_clk),
+ .user_clk(user_clk),
+ .resetb_sync(core_rstn)
+ );
+
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/la_test1/Makefile b/verilog/dv/la_test1/Makefile
index b23075d..8971518 100644
--- a/verilog/dv/la_test1/Makefile
+++ b/verilog/dv/la_test1/Makefile
@@ -25,7 +25,9 @@
## User Project Pointers
UPRJ_VERILOG_PATH ?= ../../../verilog
UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl
-UPRJ_BEHAVIOURAL_MODELS = ../
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
## RISCV GCC
GCC_PATH?=/ef/apps/bin
@@ -43,11 +45,14 @@
hex: ${PATTERN:=.hex}
+vvp: ${PATTERN:=.vvp}
+
%.vvp: %_tb.v %.hex
ifeq ($(SIM),RTL)
- iverilog -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+ 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_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) \
$< -o $@
else
iverilog -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
diff --git a/verilog/dv/la_test2/Makefile b/verilog/dv/la_test2/Makefile
index 14e48fc..5b1e6dd 100644
--- a/verilog/dv/la_test2/Makefile
+++ b/verilog/dv/la_test2/Makefile
@@ -25,7 +25,9 @@
## User Project Pointers
UPRJ_VERILOG_PATH ?= ../../../verilog
UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl
-UPRJ_BEHAVIOURAL_MODELS = ../
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
## RISCV GCC
GCC_PATH?=/ef/apps/bin
@@ -43,11 +45,14 @@
hex: ${PATTERN:=.hex}
+vvp: ${PATTERN:=.vvp}
+
%.vvp: %_tb.v %.hex
ifeq ($(SIM),RTL)
- iverilog -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+ 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_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) \
$< -o $@
else
iverilog -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
diff --git a/verilog/dv/model/mt48lc8m8a2.v b/verilog/dv/model/mt48lc8m8a2.v
new file mode 100755
index 0000000..add1c36
--- /dev/null
+++ b/verilog/dv/model/mt48lc8m8a2.v
@@ -0,0 +1,964 @@
+/****************************************************************************************
+*
+* File Name: MT48LC8M8A2.V
+* Version: 0.0f
+* Date: July 8th, 1999
+* Model: BUS Functional
+* Simulator: Model Technology (PC version 5.2e PE)
+*
+* Dependencies: None
+*
+* Author: Son P. Huynh
+* Email: sphuynh@micron.com
+* Phone: (208) 368-3825
+* Company: Micron Technology, Inc.
+* Model: MT48LC8M16A2 (2Meg x 8 x 4 Banks)
+*
+* Description: Micron 128Mb SDRAM Verilog model
+*
+* Limitation: - Doesn't check for 4096 cycle refresh
+*
+* Note: - Set simulator resolution to "ps" accuracy
+* - Set Debug = 0 to disable $display messages
+*
+* Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY
+* WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY
+* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
+* A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
+*
+* Copyright © 1998 Micron Semiconductor Products, Inc.
+* All rights researved
+*
+* Rev Author Phone Date Changes
+* ---- ---------------------------- ---------- ---------------------------------------
+* 0.0f Son Huynh 208-368-3825 07/08/1999 - Fix tWR = 1 Clk + 7.5 ns (Auto)
+* Micron Technology Inc. - Fix tWR = 15 ns (Manual)
+* - Fix tRP (Autoprecharge to AutoRefresh)
+*
+* 0.0a Son Huynh 208-368-3825 05/13/1998 - First Release (from 64Mb rev 0.0e)
+* Micron Technology Inc.
+****************************************************************************************/
+
+`timescale 1ns / 100ps
+
+module mt48lc8m8a2 (Dq, Addr, Ba, Clk, Cke, Cs_n, Ras_n, Cas_n, We_n, Dqm);
+
+ parameter addr_bits = 12;
+ parameter data_bits = 8;
+ parameter col_bits = 9;
+ parameter mem_sizes = 2097151; // 2 Meg
+
+ inout [data_bits - 1 : 0] Dq;
+ input [addr_bits - 1 : 0] Addr;
+ input [1 : 0] Ba;
+ input Clk;
+ input Cke;
+ input Cs_n;
+ input Ras_n;
+ input Cas_n;
+ input We_n;
+ input [0 : 0] Dqm;
+
+ reg [data_bits - 1 : 0] Bank0 [0 : mem_sizes];
+ reg [data_bits - 1 : 0] Bank1 [0 : mem_sizes];
+ reg [data_bits - 1 : 0] Bank2 [0 : mem_sizes];
+ reg [data_bits - 1 : 0] Bank3 [0 : mem_sizes];
+
+ reg [1 : 0] Bank_addr [0 : 3]; // Bank Address Pipeline
+ reg [col_bits - 1 : 0] Col_addr [0 : 3]; // Column Address Pipeline
+ reg [3 : 0] Command [0 : 3]; // Command Operation Pipeline
+ reg [0 : 0] Dqm_reg0, Dqm_reg1; // DQM Operation Pipeline
+ reg [addr_bits - 1 : 0] B0_row_addr, B1_row_addr, B2_row_addr, B3_row_addr;
+
+ reg [addr_bits - 1 : 0] Mode_reg;
+ reg [data_bits - 1 : 0] Dq_reg, Dq_dqm;
+ reg [col_bits - 1 : 0] Col_temp, Burst_counter;
+
+ reg Act_b0, Act_b1, Act_b2, Act_b3; // Bank Activate
+ reg Pc_b0, Pc_b1, Pc_b2, Pc_b3; // Bank Precharge
+
+ reg [1 : 0] Bank_precharge [0 : 3]; // Precharge Command
+ reg A10_precharge [0 : 3]; // Addr[10] = 1 (All banks)
+ reg Auto_precharge [0 : 3]; // RW AutoPrecharge (Bank)
+ reg Read_precharge [0 : 3]; // R AutoPrecharge
+ reg Write_precharge [0 : 3]; // W AutoPrecharge
+ integer Count_precharge [0 : 3]; // RW AutoPrecharge (Counter)
+ reg RW_interrupt_read [0 : 3]; // RW Interrupt Read with Auto Precharge
+ reg RW_interrupt_write [0 : 3]; // RW Interrupt Write with Auto Precharge
+
+ reg Data_in_enable;
+ reg Data_out_enable;
+
+ reg [1 : 0] Bank, Previous_bank;
+ reg [addr_bits - 1 : 0] Row;
+ reg [col_bits - 1 : 0] Col, Col_brst;
+
+ // Internal system clock
+ reg CkeZ, Sys_clk;
+
+ // Commands Decode
+ wire Active_enable = ~Cs_n & ~Ras_n & Cas_n & We_n;
+ wire Aref_enable = ~Cs_n & ~Ras_n & ~Cas_n & We_n;
+ wire Burst_term = ~Cs_n & Ras_n & Cas_n & ~We_n;
+ wire Mode_reg_enable = ~Cs_n & ~Ras_n & ~Cas_n & ~We_n;
+ wire Prech_enable = ~Cs_n & ~Ras_n & Cas_n & ~We_n;
+ wire Read_enable = ~Cs_n & Ras_n & ~Cas_n & We_n;
+ wire Write_enable = ~Cs_n & Ras_n & ~Cas_n & ~We_n;
+
+ // Burst Length Decode
+ wire Burst_length_1 = ~Mode_reg[2] & ~Mode_reg[1] & ~Mode_reg[0];
+ wire Burst_length_2 = ~Mode_reg[2] & ~Mode_reg[1] & Mode_reg[0];
+ wire Burst_length_4 = ~Mode_reg[2] & Mode_reg[1] & ~Mode_reg[0];
+ wire Burst_length_8 = ~Mode_reg[2] & Mode_reg[1] & Mode_reg[0];
+
+ // CAS Latency Decode
+ wire Cas_latency_2 = ~Mode_reg[6] & Mode_reg[5] & ~Mode_reg[4];
+ wire Cas_latency_3 = ~Mode_reg[6] & Mode_reg[5] & Mode_reg[4];
+
+`ifdef VERBOSE
+ wire Debug = 1'b1; // Debug messages : 1 = On
+`else
+ wire Debug = 1'b0; // Debug messages : 1 = On
+`endif
+ // Write Burst Mode
+ wire Write_burst_mode = Mode_reg[9];
+
+ wire Dq_chk = Sys_clk & Data_in_enable; // Check setup/hold time for DQ
+
+ assign Dq = Dq_reg; // DQ buffer
+
+ // Commands Operation
+ `define ACT 0
+ `define NOP 1
+ `define READ 2
+ `define READ_A 3
+ `define SDRAM_WRITE 4
+ `define WRITE_A 5
+ `define SDRAM_PRECH 6
+ `define SDRAM_A_REF 7
+ `define SDRAM_BST 8
+ `define SDRAM_LMR 9
+
+ // Timing Parameters for -75 (PC133) and CAS Latency = 2
+ parameter tAC = 6.0;
+ parameter tHZ = 7.0;
+ parameter tOH = 2.7;
+ parameter tMRD = 2.0; // 2 Clk Cycles
+ parameter tRAS = 44.0;
+ parameter tRC = 66.0;
+ parameter tRCD = 20.0;
+ parameter tRP = 20.0;
+ parameter tRRD = 15.0;
+ parameter tWRa = 7.5; // A2 Version - Auto precharge mode only (1 Clk + 7.5 ns)
+ parameter tWRp = 15.0; // A2 Version - Precharge mode only (15 ns)
+
+ // Timing Check variable
+ integer MRD_chk;
+ integer WR_counter [0 : 3];
+ time WR_chk [0 : 3];
+ time RC_chk, RRD_chk;
+ time RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3;
+ time RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3;
+ time RP_chk0, RP_chk1, RP_chk2, RP_chk3;
+
+ initial begin
+
+ Dq_reg = {data_bits{1'bz}};
+ {Data_in_enable, Data_out_enable} = 0;
+ {Act_b0, Act_b1, Act_b2, Act_b3} = 4'b0000;
+ {Pc_b0, Pc_b1, Pc_b2, Pc_b3} = 4'b0000;
+ {WR_chk[0], WR_chk[1], WR_chk[2], WR_chk[3]} = 0;
+ {WR_counter[0], WR_counter[1], WR_counter[2], WR_counter[3]} = 0;
+ {RW_interrupt_read[0], RW_interrupt_read[1], RW_interrupt_read[2], RW_interrupt_read[3]} = 0;
+ {RW_interrupt_write[0], RW_interrupt_write[1], RW_interrupt_write[2], RW_interrupt_write[3]} = 0;
+ {MRD_chk, RC_chk, RRD_chk} = 0;
+ {RAS_chk0, RAS_chk1, RAS_chk2, RAS_chk3} = 0;
+ {RCD_chk0, RCD_chk1, RCD_chk2, RCD_chk3} = 0;
+ {RP_chk0, RP_chk1, RP_chk2, RP_chk3} = 0;
+ $timeformat (-9, 0, " ns", 12);
+ //$readmemh("bank0.txt", Bank0);
+ //$readmemh("bank1.txt", Bank1);
+ //$readmemh("bank2.txt", Bank2);
+ //$readmemh("bank3.txt", Bank3);
+ end
+
+ // System clock generator
+ always begin
+ @ (posedge Clk) begin
+ Sys_clk = CkeZ;
+ CkeZ = Cke;
+ end
+ @ (negedge Clk) begin
+ Sys_clk = 1'b0;
+ end
+ end
+
+ always @ (posedge Sys_clk) begin
+ // Internal Commamd Pipelined
+ Command[0] = Command[1];
+ Command[1] = Command[2];
+ Command[2] = Command[3];
+ Command[3] = `NOP;
+
+ Col_addr[0] = Col_addr[1];
+ Col_addr[1] = Col_addr[2];
+ Col_addr[2] = Col_addr[3];
+ Col_addr[3] = {col_bits{1'b0}};
+
+ Bank_addr[0] = Bank_addr[1];
+ Bank_addr[1] = Bank_addr[2];
+ Bank_addr[2] = Bank_addr[3];
+ Bank_addr[3] = 2'b0;
+
+ Bank_precharge[0] = Bank_precharge[1];
+ Bank_precharge[1] = Bank_precharge[2];
+ Bank_precharge[2] = Bank_precharge[3];
+ Bank_precharge[3] = 2'b0;
+
+ A10_precharge[0] = A10_precharge[1];
+ A10_precharge[1] = A10_precharge[2];
+ A10_precharge[2] = A10_precharge[3];
+ A10_precharge[3] = 1'b0;
+
+ // Dqm pipeline for Read
+ Dqm_reg0 = Dqm_reg1;
+ Dqm_reg1 = Dqm;
+
+ // Read or Write with Auto Precharge Counter
+ if (Auto_precharge[0] == 1'b1) begin
+ Count_precharge[0] = Count_precharge[0] + 1;
+ end
+ if (Auto_precharge[1] == 1'b1) begin
+ Count_precharge[1] = Count_precharge[1] + 1;
+ end
+ if (Auto_precharge[2] == 1'b1) begin
+ Count_precharge[2] = Count_precharge[2] + 1;
+ end
+ if (Auto_precharge[3] == 1'b1) begin
+ Count_precharge[3] = Count_precharge[3] + 1;
+ end
+
+ // tMRD Counter
+ MRD_chk = MRD_chk + 1;
+
+ // tWR Counter for Write
+ WR_counter[0] = WR_counter[0] + 1;
+ WR_counter[1] = WR_counter[1] + 1;
+ WR_counter[2] = WR_counter[2] + 1;
+ WR_counter[3] = WR_counter[3] + 1;
+
+ // Auto Refresh
+ if (Aref_enable == 1'b1) begin
+ if (Debug) $display ("at time %t AREF : Auto Refresh", $time);
+ // Auto Refresh to Auto Refresh
+ if ($time - RC_chk < tRC) begin
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRC violation during Auto Refresh", $time);
+ end
+ // Precharge to Auto Refresh
+ if ($time - RP_chk0 < tRP || $time - RP_chk1 < tRP || $time - RP_chk2 < tRP || $time - RP_chk3 < tRP) begin
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRP violation during Auto Refresh", $time);
+ end
+ // Precharge to Refresh
+ if (Pc_b0 == 1'b0 || Pc_b1 == 1'b0 || Pc_b2 == 1'b0 || Pc_b3 == 1'b0) begin
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: All banks must be Precharge before Auto Refresh", $time);
+ end
+ // Record Current tRC time
+ RC_chk = $time;
+ end
+
+ // Load Mode Register
+ if (Mode_reg_enable == 1'b1) begin
+ // Decode CAS Latency, Burst Length, Burst Type, and Write Burst Mode
+ if (Pc_b0 == 1'b1 && Pc_b1 == 1'b1 && Pc_b2 == 1'b1 && Pc_b3 == 1'b1) begin
+ Mode_reg = Addr;
+ if (Debug) begin
+ $display ("at time %t LMR : Load Mode Register", $time);
+ // CAS Latency
+ if (Addr[6 : 4] == 3'b010)
+ $display (" CAS Latency = 2");
+ else if (Addr[6 : 4] == 3'b011)
+ $display (" CAS Latency = 3");
+ else
+ $display (" CAS Latency = Reserved");
+ // Burst Length
+ if (Addr[2 : 0] == 3'b000)
+ $display (" Burst Length = 1");
+ else if (Addr[2 : 0] == 3'b001)
+ $display (" Burst Length = 2");
+ else if (Addr[2 : 0] == 3'b010)
+ $display (" Burst Length = 4");
+ else if (Addr[2 : 0] == 3'b011)
+ $display (" Burst Length = 8");
+ else if (Addr[3 : 0] == 4'b0111)
+ $display (" Burst Length = Full");
+ else
+ $display (" Burst Length = Reserved");
+ // Burst Type
+ if (Addr[3] == 1'b0)
+ $display (" Burst Type = Sequential");
+ else if (Addr[3] == 1'b1)
+ $display (" Burst Type = Interleaved");
+ else
+ $display (" Burst Type = Reserved");
+ // Write Burst Mode
+ if (Addr[9] == 1'b0)
+ $display (" Write Burst Mode = Programmed Burst Length");
+ else if (Addr[9] == 1'b1)
+ $display (" Write Burst Mode = Single Location Access");
+ else
+ $display (" Write Burst Mode = Reserved");
+ end
+ end else begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: all banks must be Precharge before Load Mode Register", $time);
+ end
+ // REF to LMR
+ if ($time - RC_chk < tRC) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRC violation during Load Mode Register", $time);
+ end
+ // LMR to LMR
+ if (MRD_chk < tMRD) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tMRD violation during Load Mode Register", $time);
+ end
+ MRD_chk = 0;
+ end
+
+ // Active Block (Latch Bank Address and Row Address)
+ if (Active_enable == 1'b1) begin
+ if (Ba == 2'b00 && Pc_b0 == 1'b1) begin
+ {Act_b0, Pc_b0} = 2'b10;
+ B0_row_addr = Addr [addr_bits - 1 : 0];
+ RCD_chk0 = $time;
+ RAS_chk0 = $time;
+ if (Debug) $display ("at time %t ACT : Bank = 0 Row = %d", $time, Addr);
+ // Precharge to Activate Bank 0
+ if ($time - RP_chk0 < tRP) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRP violation during Activate bank 0", $time);
+ end
+ end else if (Ba == 2'b01 && Pc_b1 == 1'b1) begin
+ {Act_b1, Pc_b1} = 2'b10;
+ B1_row_addr = Addr [addr_bits - 1 : 0];
+ RCD_chk1 = $time;
+ RAS_chk1 = $time;
+ if (Debug) $display ("at time %t ACT : Bank = 1 Row = %d", $time, Addr);
+ // Precharge to Activate Bank 1
+ if ($time - RP_chk1 < tRP) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRP violation during Activate bank 1", $time);
+ end
+ end else if (Ba == 2'b10 && Pc_b2 == 1'b1) begin
+ {Act_b2, Pc_b2} = 2'b10;
+ B2_row_addr = Addr [addr_bits - 1 : 0];
+ RCD_chk2 = $time;
+ RAS_chk2 = $time;
+ if (Debug) $display ("at time %t ACT : Bank = 2 Row = %d", $time, Addr);
+ // Precharge to Activate Bank 2
+ if ($time - RP_chk2 < tRP) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRP violation during Activate bank 2", $time);
+ end
+ end else if (Ba == 2'b11 && Pc_b3 == 1'b1) begin
+ {Act_b3, Pc_b3} = 2'b10;
+ B3_row_addr = Addr [addr_bits - 1 : 0];
+ RCD_chk3 = $time;
+ RAS_chk3 = $time;
+ if (Debug) $display ("at time %t ACT : Bank = 3 Row = %d", $time, Addr);
+ // Precharge to Activate Bank 3
+ if ($time - RP_chk3 < tRP) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRP violation during Activate bank 3", $time);
+ end
+ end else if (Ba == 2'b00 && Pc_b0 == 1'b0) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: Bank 0 is not Precharged.", $time);
+ end else if (Ba == 2'b01 && Pc_b1 == 1'b0) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: Bank 1 is not Precharged.", $time);
+ end else if (Ba == 2'b10 && Pc_b2 == 1'b0) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: Bank 2 is not Precharged.", $time);
+ end else if (Ba == 2'b11 && Pc_b3 == 1'b0) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: Bank 3 is not Precharged.", $time);
+ end
+ // Active Bank A to Active Bank B
+ if ((Previous_bank != Ba) && ($time - RRD_chk < tRRD)) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRRD violation during Activate bank = %d", $time, Ba);
+ end
+ // Load Mode Register to Active
+ if (MRD_chk < tMRD ) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tMRD violation during Activate bank = %d", $time, Ba);
+ end
+ // Auto Refresh to Activate
+ if ($time - RC_chk < tRC) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRC violation during Activate bank = %d", $time, Ba);
+ end
+ // Record variables for checking violation
+ RRD_chk = $time;
+ Previous_bank = Ba;
+ end
+
+ // Precharge Block
+ if (Prech_enable == 1'b1) begin
+ if (Addr[10] == 1'b1) begin
+ {Pc_b0, Pc_b1, Pc_b2, Pc_b3} = 4'b1111;
+ {Act_b0, Act_b1, Act_b2, Act_b3} = 4'b0000;
+ RP_chk0 = $time;
+ RP_chk1 = $time;
+ RP_chk2 = $time;
+ RP_chk3 = $time;
+ if (Debug) $display ("at time %t PRE : Bank = ALL",$time);
+ // Activate to Precharge all banks
+ if (($time - RAS_chk0 < tRAS) || ($time - RAS_chk1 < tRAS) ||
+ ($time - RAS_chk2 < tRAS) || ($time - RAS_chk3 < tRAS)) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRAS violation during Precharge all bank", $time);
+ end
+ // tWR violation check for write
+ if (($time - WR_chk[0] < tWRp) || ($time - WR_chk[1] < tWRp) ||
+ ($time - WR_chk[2] < tWRp) || ($time - WR_chk[3] < tWRp)) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tWR violation during Precharge all bank", $time);
+ end
+ end else if (Addr[10] == 1'b0) begin
+ if (Ba == 2'b00) begin
+ {Pc_b0, Act_b0} = 2'b10;
+ RP_chk0 = $time;
+ if (Debug) $display ("at time %t PRE : Bank = 0",$time);
+ // Activate to Precharge Bank 0
+ if ($time - RAS_chk0 < tRAS) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRAS violation during Precharge bank 0", $time);
+ end
+ end else if (Ba == 2'b01) begin
+ {Pc_b1, Act_b1} = 2'b10;
+ RP_chk1 = $time;
+ if (Debug) $display ("at time %t PRE : Bank = 1",$time);
+ // Activate to Precharge Bank 1
+ if ($time - RAS_chk1 < tRAS) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRAS violation during Precharge bank 1", $time);
+ end
+ end else if (Ba == 2'b10) begin
+ {Pc_b2, Act_b2} = 2'b10;
+ RP_chk2 = $time;
+ if (Debug) $display ("at time %t PRE : Bank = 2",$time);
+ // Activate to Precharge Bank 2
+ if ($time - RAS_chk2 < tRAS) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRAS violation during Precharge bank 2", $time);
+ end
+ end else if (Ba == 2'b11) begin
+ {Pc_b3, Act_b3} = 2'b10;
+ RP_chk3 = $time;
+ if (Debug) $display ("at time %t PRE : Bank = 3",$time);
+ // Activate to Precharge Bank 3
+ if ($time - RAS_chk3 < tRAS) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tRAS violation during Precharge bank 3", $time);
+ end
+ end
+ // tWR violation check for write
+ if ($time - WR_chk[Ba] < tWRp) begin
+
+ //->tb.test_control.error_detected;
+ $display ("at time %t ERROR: tWR violation during Precharge bank %d", $time, Ba);
+ end
+ end
+ // Terminate a Write Immediately (if same bank or all banks)
+ if (Data_in_enable == 1'b1 && (Bank == Ba || Addr[10] == 1'b1)) begin
+ Data_in_enable = 1'b0;
+ end
+ // Precharge Command Pipeline for Read
+ if (Cas_latency_3 == 1'b1) begin
+ Command[2] = `SDRAM_PRECH;
+ Bank_precharge[2] = Ba;
+ A10_precharge[2] = Addr[10];
+ end else if (Cas_latency_2 == 1'b1) begin
+ Command[1] = `SDRAM_PRECH;
+ Bank_precharge[1] = Ba;
+ A10_precharge[1] = Addr[10];
+ end
+ end
+
+ // Burst terminate
+ if (Burst_term == 1'b1) begin
+ // Terminate a Write Immediately
+ if (Data_in_enable == 1'b1) begin
+ Data_in_enable = 1'b0;
+ end
+ // Terminate a Read Depend on CAS Latency
+ if (Cas_latency_3 == 1'b1) begin
+ Command[2] = `SDRAM_BST;
+ end else if (Cas_latency_2 == 1'b1) begin
+ Command[1] = `SDRAM_BST;
+ end
+ if (Debug) $display ("at time %t BST : Burst Terminate",$time);
+ end
+
+ // Read, Write, Column Latch
+ if (Read_enable == 1'b1 || Write_enable == 1'b1) begin
+ // Check to see if bank is open (ACT)
+ if ((Ba == 2'b00 && Pc_b0 == 1'b1) || (Ba == 2'b01 && Pc_b1 == 1'b1) ||
+ (Ba == 2'b10 && Pc_b2 == 1'b1) || (Ba == 2'b11 && Pc_b3 == 1'b1)) begin
+
+ //->tb.test_control.error_detected;
+ $display("at time %t ERROR: Cannot Read or Write - Bank %d is not Activated", $time, Ba);
+ end
+ // Activate to Read or Write
+ if ((Ba == 2'b00) && ($time - RCD_chk0 < tRCD))
+ begin
+ //->tb.test_control.error_detected;
+ $display("at time %t ERROR: tRCD violation during Read or Write to Bank 0", $time);
+ end
+
+ if ((Ba == 2'b01) && ($time - RCD_chk1 < tRCD))
+ begin
+ //->tb.test_control.error_detected;
+ $display("at time %t ERROR: tRCD violation during Read or Write to Bank 1", $time);
+ end
+ if ((Ba == 2'b10) && ($time - RCD_chk2 < tRCD))
+ begin
+ //->tb.test_control.error_detected;
+ $display("at time %t ERROR: tRCD violation during Read or Write to Bank 2", $time);
+ end
+ if ((Ba == 2'b11) && ($time - RCD_chk3 < tRCD))
+ begin
+ //->tb.test_control.error_detected;
+ $display("at time %t ERROR: tRCD violation during Read or Write to Bank 3", $time);
+ end
+ // Read Command
+ if (Read_enable == 1'b1) begin
+ // CAS Latency pipeline
+ if (Cas_latency_3 == 1'b1) begin
+ if (Addr[10] == 1'b1) begin
+ Command[2] = `READ_A;
+ end else begin
+ Command[2] = `READ;
+ end
+ Col_addr[2] = Addr;
+ Bank_addr[2] = Ba;
+ end else if (Cas_latency_2 == 1'b1) begin
+ if (Addr[10] == 1'b1) begin
+ Command[1] = `READ_A;
+ end else begin
+ Command[1] = `READ;
+ end
+ Col_addr[1] = Addr;
+ Bank_addr[1] = Ba;
+ end
+
+ // Read interrupt Write (terminate Write immediately)
+ if (Data_in_enable == 1'b1) begin
+ Data_in_enable = 1'b0;
+ end
+
+ // Write Command
+ end else if (Write_enable == 1'b1) begin
+ if (Addr[10] == 1'b1) begin
+ Command[0] = `WRITE_A;
+ end else begin
+ Command[0] = `SDRAM_WRITE;
+ end
+ Col_addr[0] = Addr;
+ Bank_addr[0] = Ba;
+
+ // Write interrupt Write (terminate Write immediately)
+ if (Data_in_enable == 1'b1) begin
+ Data_in_enable = 1'b0;
+ end
+
+ // Write interrupt Read (terminate Read immediately)
+ if (Data_out_enable == 1'b1) begin
+ Data_out_enable = 1'b0;
+ end
+ end
+
+ // Interrupting a Write with Autoprecharge
+ if (Auto_precharge[Bank] == 1'b1 && Write_precharge[Bank] == 1'b1) begin
+ RW_interrupt_write[Bank] = 1'b1;
+ if (Debug) $display ("at time %t NOTE : Read/Write Bank %d interrupt Write Bank %d with Autoprecharge", $time, Ba, Bank);
+ end
+
+ // Interrupting a Read with Autoprecharge
+ if (Auto_precharge[Bank] == 1'b1 && Read_precharge[Bank] == 1'b1) begin
+ RW_interrupt_read[Bank] = 1'b1;
+ if (Debug) $display ("at time %t NOTE : Read/Write Bank %d interrupt Read Bank %d with Autoprecharge", $time, Ba, Bank);
+ end
+
+ // Read or Write with Auto Precharge
+ if (Addr[10] == 1'b1) begin
+ Auto_precharge[Ba] = 1'b1;
+ Count_precharge[Ba] = 0;
+ if (Read_enable == 1'b1) begin
+ Read_precharge[Ba] = 1'b1;
+ end else if (Write_enable == 1'b1) begin
+ Write_precharge[Ba] = 1'b1;
+ end
+ end
+ end
+
+ // Read with Auto Precharge Calculation
+ // The device start internal precharge:
+ // 1. CAS Latency - 1 cycles before last burst
+ // and 2. Meet minimum tRAS requirement
+ // or 3. Interrupt by a Read or Write (with or without AutoPrecharge)
+ if ((Auto_precharge[0] == 1'b1) && (Read_precharge[0] == 1'b1)) begin
+ if ((($time - RAS_chk0 >= tRAS) && // Case 2
+ ((Burst_length_1 == 1'b1 && Count_precharge[0] >= 1) || // Case 1
+ (Burst_length_2 == 1'b1 && Count_precharge[0] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge[0] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge[0] >= 8))) ||
+ (RW_interrupt_read[0] == 1'b1)) begin // Case 3
+ Pc_b0 = 1'b1;
+ Act_b0 = 1'b0;
+ RP_chk0 = $time;
+ Auto_precharge[0] = 1'b0;
+ Read_precharge[0] = 1'b0;
+ RW_interrupt_read[0] = 1'b0;
+ if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time);
+ end
+ end
+ if ((Auto_precharge[1] == 1'b1) && (Read_precharge[1] == 1'b1)) begin
+ if ((($time - RAS_chk1 >= tRAS) &&
+ ((Burst_length_1 == 1'b1 && Count_precharge[1] >= 1) ||
+ (Burst_length_2 == 1'b1 && Count_precharge[1] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge[1] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge[1] >= 8))) ||
+ (RW_interrupt_read[1] == 1'b1)) begin
+ Pc_b1 = 1'b1;
+ Act_b1 = 1'b0;
+ RP_chk1 = $time;
+ Auto_precharge[1] = 1'b0;
+ Read_precharge[1] = 1'b0;
+ RW_interrupt_read[1] = 1'b0;
+ if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time);
+ end
+ end
+ if ((Auto_precharge[2] == 1'b1) && (Read_precharge[2] == 1'b1)) begin
+ if ((($time - RAS_chk2 >= tRAS) &&
+ ((Burst_length_1 == 1'b1 && Count_precharge[2] >= 1) ||
+ (Burst_length_2 == 1'b1 && Count_precharge[2] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge[2] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge[2] >= 8))) ||
+ (RW_interrupt_read[2] == 1'b1)) begin
+ Pc_b2 = 1'b1;
+ Act_b2 = 1'b0;
+ RP_chk2 = $time;
+ Auto_precharge[2] = 1'b0;
+ Read_precharge[2] = 1'b0;
+ RW_interrupt_read[2] = 1'b0;
+ if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time);
+ end
+ end
+ if ((Auto_precharge[3] == 1'b1) && (Read_precharge[3] == 1'b1)) begin
+ if ((($time - RAS_chk3 >= tRAS) &&
+ ((Burst_length_1 == 1'b1 && Count_precharge[3] >= 1) ||
+ (Burst_length_2 == 1'b1 && Count_precharge[3] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge[3] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge[3] >= 8))) ||
+ (RW_interrupt_read[3] == 1'b1)) begin
+ Pc_b3 = 1'b1;
+ Act_b3 = 1'b0;
+ RP_chk3 = $time;
+ Auto_precharge[3] = 1'b0;
+ Read_precharge[3] = 1'b0;
+ RW_interrupt_read[3] = 1'b0;
+ if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time);
+ end
+ end
+
+ // Internal Precharge or Bst
+ if (Command[0] == `SDRAM_PRECH) begin // Precharge terminate a read with same bank or all banks
+ if (Bank_precharge[0] == Bank || A10_precharge[0] == 1'b1) begin
+ if (Data_out_enable == 1'b1) begin
+ Data_out_enable = 1'b0;
+ end
+ end
+ end else if (Command[0] == `SDRAM_BST) begin // BST terminate a read to current bank
+ if (Data_out_enable == 1'b1) begin
+ Data_out_enable = 1'b0;
+ end
+ end
+
+ if (Data_out_enable == 1'b0) begin
+ Dq_reg <= #tOH {data_bits{1'bz}};
+ end
+
+ // Detect Read or Write command
+ if (Command[0] == `READ || Command[0] == `READ_A) begin
+ Bank = Bank_addr[0];
+ Col = Col_addr[0];
+ Col_brst = Col_addr[0];
+ if (Bank_addr[0] == 2'b00) begin
+ Row = B0_row_addr;
+ end else if (Bank_addr[0] == 2'b01) begin
+ Row = B1_row_addr;
+ end else if (Bank_addr[0] == 2'b10) begin
+ Row = B2_row_addr;
+ end else if (Bank_addr[0] == 2'b11) begin
+ Row = B3_row_addr;
+ end
+ Burst_counter = 0;
+ Data_in_enable = 1'b0;
+ Data_out_enable = 1'b1;
+ end else if (Command[0] == `SDRAM_WRITE || Command[0] == `WRITE_A) begin
+ Bank = Bank_addr[0];
+ Col = Col_addr[0];
+ Col_brst = Col_addr[0];
+ if (Bank_addr[0] == 2'b00) begin
+ Row = B0_row_addr;
+ end else if (Bank_addr[0] == 2'b01) begin
+ Row = B1_row_addr;
+ end else if (Bank_addr[0] == 2'b10) begin
+ Row = B2_row_addr;
+ end else if (Bank_addr[0] == 2'b11) begin
+ Row = B3_row_addr;
+ end
+ Burst_counter = 0;
+ Data_in_enable = 1'b1;
+ Data_out_enable = 1'b0;
+ end
+
+ // DQ buffer (Driver/Receiver)
+ if (Data_in_enable == 1'b1) begin // Writing Data to Memory
+ // Array buffer
+ if (Bank == 2'b00) Dq_dqm [15 : 0] = Bank0 [{Row, Col}];
+ if (Bank == 2'b01) Dq_dqm [15 : 0] = Bank1 [{Row, Col}];
+ if (Bank == 2'b10) Dq_dqm [15 : 0] = Bank2 [{Row, Col}];
+ if (Bank == 2'b11) Dq_dqm [15 : 0] = Bank3 [{Row, Col}];
+ // Dqm operation
+ if (Dqm[0] == 1'b0) Dq_dqm [ 7 : 0] = Dq [ 7 : 0];
+ // Write to memory
+ if (Bank == 2'b00) Bank0 [{Row, Col}] = Dq_dqm [15 : 0];
+ if (Bank == 2'b01) Bank1 [{Row, Col}] = Dq_dqm [15 : 0];
+ if (Bank == 2'b10) Bank2 [{Row, Col}] = Dq_dqm [15 : 0];
+ if (Bank == 2'b11) Bank3 [{Row, Col}] = Dq_dqm [15 : 0];
+ // Output result
+ if (Dqm == 1'b1) begin
+ if (Debug) $display("at time %t WRITE: Bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $time, Bank, Row, Col);
+ end else begin
+ if (Debug) $display("at time %t WRITE: Bank = %d Row = %d, Col = %d, Data = %h, Dqm = %b", $time, Bank, Row, Col, Dq_dqm, Dqm);
+ // Record tWR time and reset counter
+ WR_chk [Bank] = $time;
+ WR_counter [Bank] = 0;
+ end
+ // Advance burst counter subroutine
+ #tHZ Burst;
+ end else if (Data_out_enable == 1'b1) begin // Reading Data from Memory
+ // Array buffer
+ if (Bank == 2'b00) Dq_dqm [15 : 0] = Bank0 [{Row, Col}];
+ if (Bank == 2'b01) Dq_dqm [15 : 0] = Bank1 [{Row, Col}];
+ if (Bank == 2'b10) Dq_dqm [15 : 0] = Bank2 [{Row, Col}];
+ if (Bank == 2'b11) Dq_dqm [15 : 0] = Bank3 [{Row, Col}];
+ // Dqm operation
+ if (Dqm_reg0[0] == 1'b1) Dq_dqm [ 7 : 0] = 8'bz;
+ // Display result
+ Dq_reg [15 : 0] = #tAC Dq_dqm [15 : 0];
+ if (Dqm_reg0 == 1'b1) begin
+ if (Debug) $display("at time %t READ : Bank = %d Row = %d, Col = %d, Data = Hi-Z due to DQM", $time, Bank, Row, Col);
+ end else begin
+ if (Debug) $display("at time %t READ : Bank = %d Row = %d, Col = %d, Data = %h, Dqm = %b", $time, Bank, Row, Col, Dq_reg, Dqm_reg0);
+ end
+ // Advance burst counter subroutine
+ Burst;
+ end
+ end
+
+ // Write with Auto Precharge Calculation
+ // The device start internal precharge:
+ // 1. tWR Clock after last burst
+ // and 2. Meet minimum tRAS requirement
+ // or 3. Interrupt by a Read or Write (with or without AutoPrecharge)
+ always @ (WR_counter[0]) begin
+ if ((Auto_precharge[0] == 1'b1) && (Write_precharge[0] == 1'b1)) begin
+ if ((($time - RAS_chk0 >= tRAS) && // Case 2
+ (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [0] >= 1) || // Case 1
+ (Burst_length_2 == 1'b1 && Count_precharge [0] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge [0] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge [0] >= 8))) ||
+ (RW_interrupt_write[0] == 1'b1 && WR_counter[0] >= 2)) begin // Case 3 (stop count when interrupt)
+ Auto_precharge[0] = 1'b0;
+ Write_precharge[0] = 1'b0;
+ RW_interrupt_write[0] = 1'b0;
+ #tWRa; // Wait for tWR
+ Pc_b0 = 1'b1;
+ Act_b0 = 1'b0;
+ RP_chk0 = $time;
+ if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 0", $time);
+ end
+ end
+ end
+ always @ (WR_counter[1]) begin
+ if ((Auto_precharge[1] == 1'b1) && (Write_precharge[1] == 1'b1)) begin
+ if ((($time - RAS_chk1 >= tRAS) &&
+ (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [1] >= 1) ||
+ (Burst_length_2 == 1'b1 && Count_precharge [1] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge [1] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge [1] >= 8))) ||
+ (RW_interrupt_write[1] == 1'b1 && WR_counter[1] >= 2)) begin
+ Auto_precharge[1] = 1'b0;
+ Write_precharge[1] = 1'b0;
+ RW_interrupt_write[1] = 1'b0;
+ #tWRa; // Wait for tWR
+ Pc_b1 = 1'b1;
+ Act_b1 = 1'b0;
+ RP_chk1 = $time;
+ if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 1", $time);
+ end
+ end
+ end
+ always @ (WR_counter[2]) begin
+ if ((Auto_precharge[2] == 1'b1) && (Write_precharge[2] == 1'b1)) begin
+ if ((($time - RAS_chk2 >= tRAS) &&
+ (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [2] >= 1) ||
+ (Burst_length_2 == 1'b1 && Count_precharge [2] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge [2] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge [2] >= 8))) ||
+ (RW_interrupt_write[2] == 1'b1 && WR_counter[2] >= 2)) begin
+ Auto_precharge[2] = 1'b0;
+ Write_precharge[2] = 1'b0;
+ RW_interrupt_write[2] = 1'b0;
+ #tWRa; // Wait for tWR
+ Pc_b2 = 1'b1;
+ Act_b2 = 1'b0;
+ RP_chk2 = $time;
+ if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 2", $time);
+ end
+ end
+ end
+ always @ (WR_counter[3]) begin
+ if ((Auto_precharge[3] == 1'b1) && (Write_precharge[3] == 1'b1)) begin
+ if ((($time - RAS_chk3 >= tRAS) &&
+ (((Burst_length_1 == 1'b1 || Write_burst_mode == 1'b1) && Count_precharge [3] >= 1) ||
+ (Burst_length_2 == 1'b1 && Count_precharge [3] >= 2) ||
+ (Burst_length_4 == 1'b1 && Count_precharge [3] >= 4) ||
+ (Burst_length_8 == 1'b1 && Count_precharge [3] >= 8))) ||
+ (RW_interrupt_write[3] == 1'b1 && WR_counter[3] >= 2)) begin
+ Auto_precharge[3] = 1'b0;
+ Write_precharge[3] = 1'b0;
+ RW_interrupt_write[3] = 1'b0;
+ #tWRa; // Wait for tWR
+ Pc_b3 = 1'b1;
+ Act_b3 = 1'b0;
+ RP_chk3 = $time;
+ if (Debug) $display ("at time %t NOTE : Start Internal Auto Precharge for Bank 3", $time);
+ end
+ end
+ end
+
+ task Burst;
+ begin
+ // Advance Burst Counter
+ Burst_counter = Burst_counter + 1;
+
+ // Burst Type
+ if (Mode_reg[3] == 1'b0) begin // Sequential Burst
+ Col_temp = Col + 1;
+ end else if (Mode_reg[3] == 1'b1) begin // Interleaved Burst
+ Col_temp[2] = Burst_counter[2] ^ Col_brst[2];
+ Col_temp[1] = Burst_counter[1] ^ Col_brst[1];
+ Col_temp[0] = Burst_counter[0] ^ Col_brst[0];
+ end
+
+ // Burst Length
+ if (Burst_length_2) begin // Burst Length = 2
+ Col [0] = Col_temp [0];
+ end else if (Burst_length_4) begin // Burst Length = 4
+ Col [1 : 0] = Col_temp [1 : 0];
+ end else if (Burst_length_8) begin // Burst Length = 8
+ Col [2 : 0] = Col_temp [2 : 0];
+ end else begin // Burst Length = FULL
+ Col = Col_temp;
+ end
+
+ // Burst Read Single Write
+ if (Write_burst_mode == 1'b1) begin
+ Data_in_enable = 1'b0;
+ end
+
+ // Data Counter
+ if (Burst_length_1 == 1'b1) begin
+ if (Burst_counter >= 1) begin
+ Data_in_enable = 1'b0;
+ Data_out_enable = 1'b0;
+ end
+ end else if (Burst_length_2 == 1'b1) begin
+ if (Burst_counter >= 2) begin
+ Data_in_enable = 1'b0;
+ Data_out_enable = 1'b0;
+ end
+ end else if (Burst_length_4 == 1'b1) begin
+ if (Burst_counter >= 4) begin
+ Data_in_enable = 1'b0;
+ Data_out_enable = 1'b0;
+ end
+ end else if (Burst_length_8 == 1'b1) begin
+ if (Burst_counter >= 8) begin
+ Data_in_enable = 1'b0;
+ Data_out_enable = 1'b0;
+ end
+ end
+ end
+ endtask
+
+ // Timing Parameters for -75 (PC133) and CAS Latency = 2
+ specify
+ specparam
+ tAH = 0.8, // Addr, Ba Hold Time
+ tAS = 1.5, // Addr, Ba Setup Time
+ tCH = 2.5, // Clock High-Level Width
+ tCL = 2.5, // Clock Low-Level Width
+ tCK = 10, // Clock Cycle Time
+ tDH = 0.8, // Data-in Hold Time
+ tDS = 1.5, // Data-in Setup Time
+ tCKH = 0.8, // CKE Hold Time
+ tCKS = 1.5, // CKE Setup Time
+ tCMH = 0.8, // CS#, RAS#, CAS#, WE#, DQM# Hold Time
+ tCMS = 1.5; // CS#, RAS#, CAS#, WE#, DQM# Setup Time
+ $width (posedge Clk, tCH);
+ $width (negedge Clk, tCL);
+ $period (negedge Clk, tCK);
+ $period (posedge Clk, tCK);
+ $setuphold(posedge Clk, Cke, tCKS, tCKH);
+ $setuphold(posedge Clk, Cs_n, tCMS, tCMH);
+ $setuphold(posedge Clk, Cas_n, tCMS, tCMH);
+ $setuphold(posedge Clk, Ras_n, tCMS, tCMH);
+ $setuphold(posedge Clk, We_n, tCMS, tCMH);
+ $setuphold(posedge Clk, Addr, tAS, tAH);
+ $setuphold(posedge Clk, Ba, tAS, tAH);
+ $setuphold(posedge Clk, Dqm, tCMS, tCMH);
+ $setuphold(posedge Dq_chk, Dq, tDS, tDH);
+ endspecify
+
+endmodule
+
diff --git a/verilog/dv/risc_boot/Makefile b/verilog/dv/risc_boot/Makefile
new file mode 100644
index 0000000..e987bbf
--- /dev/null
+++ b/verilog/dv/risc_boot/Makefile
@@ -0,0 +1,84 @@
+# 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
+
+## Caravel Pointers
+CARAVEL_ROOT ?= ../../../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 ?= ../../../verilog
+UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+
+## RISCV GCC
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+
+.SUFFIXES:
+
+PATTERN = risc_boot
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+vvp: ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v %.hex
+ifeq ($(SIM),RTL)
+ 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_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) \
+ $< -o $@
+else
+ iverilog -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+ -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+ -I $(UPRJ_BEHAVIOURAL_MODELS) -I$(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+ $< -o $@
+endif
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(CARAVEL_FIRMWARE_PATH)/sections.lds $(CARAVEL_FIRMWARE_PATH)/start.s
+ ${GCC_PATH}/${GCC_PREFIX}-gcc -I $(CARAVEL_PATH) -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(CARAVEL_FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(CARAVEL_FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PATH}/${GCC_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+ rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
diff --git a/verilog/dv/risc_boot/risc_boot.c b/verilog/dv/risc_boot/risc_boot.c
new file mode 100644
index 0000000..d042822
--- /dev/null
+++ b/verilog/dv/risc_boot/risc_boot.c
@@ -0,0 +1,213 @@
+/*
+ * 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
+ */
+
+// This include is relative to $CARAVEL_PATH (see Makefile)
+#include "verilog/dv/caravel/defs.h"
+#include "verilog/dv/caravel/stub.c"
+
+// User Project Slaves (0x3000_0000)
+#define reg_mprj_slave (*(volatile uint32_t*)0x30000000)
+
+#define reg_mprj_globl_reg0 (*(volatile uint32_t*)0x30000000)
+#define reg_mprj_globl_reg1 (*(volatile uint32_t*)0x30000004)
+#define reg_mprj_globl_reg2 (*(volatile uint32_t*)0x30000008)
+#define reg_mprj_globl_reg3 (*(volatile uint32_t*)0x3000000C)
+#define reg_mprj_globl_reg4 (*(volatile uint32_t*)0x30000010)
+#define reg_mprj_globl_reg5 (*(volatile uint32_t*)0x30000014)
+#define reg_mprj_globl_reg6 (*(volatile uint32_t*)0x30000018)
+#define reg_mprj_globl_reg7 (*(volatile uint32_t*)0x3000001C)
+#define reg_mprj_globl_reg8 (*(volatile uint32_t*)0x30000020)
+#define reg_mprj_globl_reg9 (*(volatile uint32_t*)0x30000024)
+#define reg_mprj_globl_reg10 (*(volatile uint32_t*)0x30000028)
+#define reg_mprj_globl_reg11 (*(volatile uint32_t*)0x3000002C)
+#define reg_mprj_globl_reg12 (*(volatile uint32_t*)0x30000030)
+#define reg_mprj_globl_reg13 (*(volatile uint32_t*)0x30000034)
+#define reg_mprj_globl_reg14 (*(volatile uint32_t*)0x30000038)
+#define reg_mprj_globl_reg15 (*(volatile uint32_t*)0x3000003C)
+
+
+#define GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP 0x1C00
+
+#define SC_SIM_OUTPORT (0xf0000000)
+
+/*
+ RiscV Hello World test.
+ - Wake up the Risc V
+ - Boot from SPI Flash
+ - Riscv Write Hello World to SDRAM,
+ - External Wishbone read back validation the data
+*/
+int i = 0;
+int clk = 0;
+
+void main()
+{
+
+ int bFail = 0;
+ /*
+ IO Control Registers
+ | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN |
+ | 3-bits | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit |
+ Output: 0000_0110_0000_1110 (0x1808) = GPIO_MODE_USER_STD_OUTPUT
+ | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN |
+ | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
+
+
+ Input: 0000_0001_0000_1111 (0x0402) = GPIO_MODE_USER_STD_INPUT_NOPULL
+ | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN |
+ | 001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
+
+ Input: 0000_0001_0000_1111 (0x1800) = GPIO_MODE_USER_STD_BIDIRECTIONAL
+ | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN |
+ | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+ */
+
+ /* Set up the housekeeping SPI to be connected internally so */
+ /* that external pin changes don't affect it. */
+
+ reg_spimaster_config = 0xa002; // Enable, prescaler = 2,
+ // connect to housekeeping SPI
+
+ // Connect the housekeeping SPI to the SPI master
+ // so that the CSB line is not left floating. This allows
+ // all of the GPIO pins to be used for user functions.
+ reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+
+ /* Apply configuration */
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+
+ reg_la2_oenb = reg_la2_iena = 0xFFFFFFFF; // [95:64]
+
+ // Flag start of the test
+ reg_mprj_datal = 0xAB600000;
+
+ //-----------------------------------------------------
+ // Start of User Functionality and take over the GPIO Pins
+ // ------------------------------------------------------
+ // User block decide on the GPIO function
+ reg_mprj_io_37 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_36 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_35 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_34 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_33 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_32 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_31 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_30 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_29 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_28 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_27 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_26 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_25 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_24 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_23 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_22 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_21 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_20 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_19 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_18 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_17 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_16 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_15 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_14 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_13 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_12 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_11 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_10 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_9 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_8 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_7 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_6 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_5 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_4 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_3 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_2 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_1 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+ reg_mprj_io_0 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP;
+
+ /* Apply configuration */
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+ // SDRAM Config-2
+ reg_mprj_globl_reg5 = 0x100019E;
+
+
+ // SDRAM Config-1
+ reg_mprj_globl_reg4 = 0x2F172242;
+
+ // Wake Up CPU Core
+ reg_mprj_globl_reg0 = 0x07;
+
+ // Add some delay for user core to boot
+ for(i = 0; i < 40; i ++);
+ for(i = 0; i < 40; i ++);
+
+ if(reg_mprj_globl_reg6 != 0x11223344) bFail = 1;
+ if(reg_mprj_globl_reg7 != 0x22334455) bFail = 1;
+ if(reg_mprj_globl_reg8 != 0x33445566) bFail = 1;
+ if(reg_mprj_globl_reg9 != 0x44556677) bFail = 1;
+ if(reg_mprj_globl_reg10 != 0x55667788) bFail = 1;
+ if(reg_mprj_globl_reg11 != 0x66778899) bFail = 1;
+
+
+ if(bFail == 0) {
+ reg_mprj_datal = 0xAB610000;
+ } else {
+ reg_mprj_datal = 0xAB600000;
+ }
+
+ // Connect the housekeeping SPI to the SPI master
+ // so that the CSB line is not left floating. This allows
+ // all of the GPIO pins to be used for user functions.
+ reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+
+ /* Apply configuration */
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1);
+}
diff --git a/verilog/dv/risc_boot/risc_boot_tb.v b/verilog/dv/risc_boot/risc_boot_tb.v
new file mode 100644
index 0000000..80c7d98
--- /dev/null
+++ b/verilog/dv/risc_boot/risc_boot_tb.v
@@ -0,0 +1,303 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// User Risc Core Boot Validation ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// 1. User Risc core is booted using compiled code of ////
+//// user_risc_boot.hex ////
+//// 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 - 12th June 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 none
+
+`timescale 1 ns / 1 ps
+
+`include "uprj_netlists.v"
+`include "caravel_netlists.v"
+`include "spiflash.v"
+`include "mt48lc8m8a2.v"
+
+module risc_boot_tb;
+ reg clock;
+ reg RSTB;
+ reg CSB;
+ reg power1, power2;
+ reg power3, power4;
+
+ wire gpio;
+ wire [37:0] mprj_io;
+ wire [7:0] mprj_io_0;
+ wire [15:0] checkbits;
+
+ assign checkbits = mprj_io[31:16];
+
+ assign mprj_io[3] = (CSB == 1'b1) ? 1'b1 : 1'bz;
+
+ // 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);
+
+ initial begin
+ clock = 0;
+ end
+
+ `ifdef WFDUMP
+ initial
+ begin
+ $dumpfile("simx.vcd");
+ $dumpvars(1,risc_boot_tb);
+ //$dumpvars(2,risc_boot_tb.uut);
+ $dumpvars(1,risc_boot_tb.uut.mprj.u_core);
+ //$dumpvars(0,risc_boot_tb.u_user_spiflash);
+ $display("Waveform Dump started");
+ end
+ `endif
+
+ initial begin
+
+ // Repeat cycles of 1000 clock edges as needed to complete testbench
+ repeat (600) begin
+ repeat (1000) @(posedge clock);
+ // $display("+1000 cycles");
+ end
+ $display("%c[1;31m",27);
+ `ifdef GL
+ $display ("Monitor: Timeout, Test user Risc Boot (GL) Failed");
+ `else
+ $display ("Monitor: Timeout, Test user Risc Boot (RTL) Failed");
+ `endif
+ $display("%c[0m",27);
+ $finish;
+ end
+
+ initial begin
+ wait(checkbits == 16'h AB60);
+ $display("Monitor: Test User Risc Boot Started");
+ wait(checkbits == 16'h AB61);
+ $display("#############################################");
+ `ifdef GL
+ $display("Monitor: Test User Risc Boot (GL) Passed");
+ `else
+ $display("Monitor: Test User Risc Boot (RTL) Passed");
+ `endif
+ $display("#############################################");
+ $finish;
+ end
+
+ initial begin
+ RSTB <= 1'b0;
+ CSB <= 1'b1; // Force CSB high
+ #2000;
+ RSTB <= 1'b1; // Release reset
+ #170000;
+ CSB = 1'b0; // CSB can be released
+ end
+
+ initial begin // Power-up sequence
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ power3 <= 1'b0;
+ power4 <= 1'b0;
+ #100;
+ power1 <= 1'b1;
+ #100;
+ power2 <= 1'b1;
+ #100;
+ power3 <= 1'b1;
+ #100;
+ power4 <= 1'b1;
+ end
+
+ //always @(mprj_io) begin
+ // #1 $display("MPRJ-IO state = %b ", mprj_io[7:0]);
+ //end
+
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+
+ wire VDD3V3 = power1;
+ wire VDD1V8 = power2;
+ wire USER_VDD3V3 = power3;
+ wire USER_VDD1V8 = power4;
+ wire VSS = 1'b0;
+
+ caravel uut (
+ .vddio (VDD3V3),
+ .vssio (VSS),
+ .vdda (VDD3V3),
+ .vssa (VSS),
+ .vccd (VDD1V8),
+ .vssd (VSS),
+ .vdda1 (USER_VDD3V3),
+ .vdda2 (USER_VDD3V3),
+ .vssa1 (VSS),
+ .vssa2 (VSS),
+ .vccd1 (USER_VDD1V8),
+ .vccd2 (USER_VDD1V8),
+ .vssd1 (VSS),
+ .vssd2 (VSS),
+ .clock (clock),
+ .gpio (gpio),
+ .mprj_io (mprj_io),
+ .flash_csb(flash_csb),
+ .flash_clk(flash_clk),
+ .flash_io0(flash_io0),
+ .flash_io1(flash_io1),
+ .resetb (RSTB)
+ );
+
+ spiflash #(
+ .FILENAME("risc_boot.hex")
+ ) spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(), // not used
+ .io3() // not used
+ );
+
+//-----------------------------------------
+// Connect Quad Flash to for usr Risc Core
+//-----------------------------------------
+
+ wire user_flash_clk = mprj_io[30];
+ wire user_flash_csb = mprj_io[31];
+ //tri user_flash_io0 = mprj_io[33];
+ //tri user_flash_io1 = mprj_io[34];
+ //tri user_flash_io2 = mprj_io[35];
+ //tri user_flash_io3 = mprj_io[36];
+
+ // Quard flash
+ spiflash #(
+ .FILENAME("user_risc_boot.hex")
+ ) u_user_spiflash (
+ .csb(user_flash_csb),
+ .clk(user_flash_clk),
+ .io0(mprj_io[32]),
+ .io1(mprj_io[33]),
+ .io2(mprj_io[34]),
+ .io3(mprj_io[35])
+ );
+
+
+//------------------------------------------------
+// Integrate the SDRAM 8 BIT Memory
+// -----------------------------------------------
+
+tri [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] = mprj_io [7:0];
+assign sdr_addr[12:0] = mprj_io [20:8] ;
+assign sdr_ba[1:0] = mprj_io [22:21] ;
+assign sdr_dqm[0] = mprj_io [23] ;
+assign sdr_we_n = mprj_io [24] ;
+assign sdr_cas_n = mprj_io [25] ;
+assign sdr_ras_n = mprj_io [26] ;
+assign sdr_cs_n = mprj_io [27] ;
+assign sdr_cke = mprj_io [28] ;
+assign sdram_clk = mprj_io [29] ;
+
+// to fix the sdram interface timing issue
+wire #(2.0) sdram_clk_d = sdram_clk;
+
+ // SDRAM 8bit
+mt48lc8m8a2 #(.data_bits(8)) u_sdram8 (
+ .Dq (mprj_io [7:0] ) ,
+ .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 )
+ );
+
+
+
+/**
+//-----------------------------------------------------------------------------
+// RISC IMEM amd DMEM Monitoring TASK
+//-----------------------------------------------------------------------------
+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 test_tb.uut.mprj.u_core.u_riscv_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
+*/
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/risc_boot/run_iverilog b/verilog/dv/risc_boot/run_iverilog
new file mode 100755
index 0000000..0cafcde
--- /dev/null
+++ b/verilog/dv/risc_boot/run_iverilog
@@ -0,0 +1,10 @@
+
+#add -DWFDUMP to enable waveform dump
+iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $PDK_PATH \
+-I $CARAVEL_ROOT/verilog/dv/caravel -I $CARAVEL_ROOT/verilog/rtl \
+-I ../model -I ../../../verilog/rtl \
+-I ../../../verilog/rtl/syntacore/scr1/src/includes -I ../../../verilog/rtl/sdram_ctrl/src/defs \
+risc_boot_tb.v -o risc_boot.vvp
+
+vvp risc_boot.vvp
+rm risc_boot.vvp
diff --git a/verilog/dv/risc_boot/user_risc_boot.hex b/verilog/dv/risc_boot/user_risc_boot.hex
new file mode 100755
index 0000000..1fdd96c
--- /dev/null
+++ b/verilog/dv/risc_boot/user_risc_boot.hex
@@ -0,0 +1,79 @@
+@00000000
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 13 00 00 00 6F 00 00 00 FF FF FF FF
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+6F 00 E0 18 13 00 00 00 13 00 00 00 13 00 00 00
+13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00
+13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00
+13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00
+93 00 00 00 13 01 00 00 93 01 00 00 13 02 00 00
+93 02 00 00 13 03 00 00 93 03 00 00 13 04 00 00
+93 04 00 00 13 05 00 00 93 05 00 00 13 06 00 00
+93 06 00 00 13 07 00 00 93 07 00 00 13 08 00 00
+93 08 00 00 13 09 00 00 93 09 00 00 13 0A 00 00
+93 0A 00 00 13 0B 00 00 93 0B 00 00 13 0C 00 00
+93 0C 00 00 13 0D 00 00 93 0D 00 00 13 0E 00 00
+93 0E 00 00 13 0F 00 00 93 0F 00 00 97 01 48 00
+93 81 41 62 13 05 00 40 97 05 48 00 93 85 85 D7
+17 06 48 00 13 06 06 E3 63 0D B5 00 29 A0 14 41
+94 C1 11 05 91 05 E3 9C C5 FE 17 06 48 00 13 06
+66 E1 97 05 48 00 93 85 E5 E0 21 A0 23 20 06 00
+11 06 E3 9D C5 FE 17 01 49 00 13 01 A1 D3 17 05
+48 00 13 05 25 DF 17 06 48 00 13 06 A6 DE B3 05
+A6 40 17 07 49 00 13 07 E7 91 33 02 B7 40 92 85
+17 06 48 00 13 06 06 DD 29 A0 14 41 94 C1 11 05
+91 05 E3 1C C5 FE 21 A0 23 A0 05 00 91 05 E3 9D
+E5 FE B7 02 49 00 05 43 23 A0 62 00 B7 02 49 00
+91 02 13 03 30 06 23 A0 62 00 B7 02 49 00 C1 02
+7D 53 23 A0 62 00 23 A2 62 00 01 45 81 45 97 02
+48 00 E7 80 22 CC 97 02 48 00 93 82 A2 D1 6D 71
+06 C2 0A C4 0E C6 12 C8 16 CA 1A CC 1E CE 22 D0
+26 D2 2A D4 2E D6 32 D8 36 DA 3A DC 3E DE C2 C0
+C6 C2 CA C4 CE C6 D2 C8 D6 CA DA CC DE CE E2 D0
+E6 D2 EA D4 EE D6 F2 D8 F6 DA FA DC FE DE 73 25
+20 34 F3 25 10 34 0A 86 EF 00 80 04 92 40 22 41
+B2 41 42 42 D2 42 62 43 F2 43 02 54 92 54 22 55
+B2 55 42 56 D2 56 62 57 F2 57 06 48 96 48 26 49
+B6 49 46 4A D6 4A 66 4B F6 4B 06 5C 96 5C 26 5D
+B6 5D 46 5E D6 5E 66 5F F6 5F 51 61 73 00 20 30
+6F F0 5F D1 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+@00000400
+37 37 22 11 B7 07 00 30 93 02 47 34 37 43 33 22
+23 AC 57 00 93 03 53 45 37 55 44 33 23 AE 77 00
+93 05 65 56 37 66 55 44 8C D3 93 06 76 67 37 78
+66 55 D4 D3 93 08 88 78 37 9E 77 66 23 A4 17 03
+93 0E 9E 89 23 A6 D7 03 01 A0 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+97 02 B8 FF 93 82 42 09 82 82 13 00 00 00 13 00
+00 00 13 00 00 00 13 00 00 00 13 00 00 00 01 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+@000004A0
+13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/verilog/dv/user_risc_boot/Makefile b/verilog/dv/user_risc_boot/Makefile
new file mode 100644
index 0000000..f7499c6
--- /dev/null
+++ b/verilog/dv/user_risc_boot/Makefile
@@ -0,0 +1,83 @@
+# 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
+
+## Caravel Pointers
+CARAVEL_ROOT ?= ../../../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 ?= ../../../verilog
+UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+
+## RISCV GCC
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv64-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+
+.SUFFIXES:
+
+PATTERN = user_risc_boot
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+vvp: ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v %.hex
+ifeq ($(SIM),RTL)
+ 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_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) \
+ $< -o $@
+else
+ iverilog -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+ -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+ -I $(UPRJ_BEHAVIOURAL_MODELS) -I$(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+ $< -o $@
+endif
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(CARAVEL_FIRMWARE_PATH)/sections.lds $(CARAVEL_FIRMWARE_PATH)/start.s
+ ${GCC_PREFIX}-gcc -I $(CARAVEL_PATH) -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(CARAVEL_FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(CARAVEL_FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+ rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
diff --git a/verilog/dv/user_risc_boot/run_iverilog b/verilog/dv/user_risc_boot/run_iverilog
new file mode 100755
index 0000000..1d8298d
--- /dev/null
+++ b/verilog/dv/user_risc_boot/run_iverilog
@@ -0,0 +1,20 @@
+riscv64-unknown-elf-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=1 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\" -c -I./ -I../../rtl/syntacore/scr1/sim/tests/common user_risc_boot.c -o user_risc_boot.o
+
+riscv64-unknown-elf-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=1 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\" -D__ASSEMBLY__=1 -c -I./ -I../../rtl/syntacore/scr1/sim/tests/common/ ../../rtl/syntacore/scr1/sim/tests/common/crt_tcm.S -o crt_tcm.o
+
+riscv64-unknown-elf-gcc -o user_risc_boot.elf -T ../../rtl/syntacore/scr1/sim/tests/common/link_tcm.ld user_risc_boot.o crt_tcm.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32
+
+riscv64-unknown-elf-objcopy -O verilog user_risc_boot.elf user_risc_boot.hex
+
+riscv64-unknown-elf-objdump -D user_risc_boot.elf > user_risc_boot.dump
+
+rm crt_tcm.o user_risc_boot.o
+
+#iverilog with waveform dump
+#iverilog -g2005-sv -DWFDUMP -I $PDK_PATH -I ../ -I ../../../verilog/rtl -I ../../../verilog/rtl/syntacore/scr1/src/includes -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $$CARAVEL_ROOT/verilog/dv/caravel -I ../model user_risc_boot_tb.v -o user_risc_boot_tb.vvp
+
+iverilog -g2005-sv -I $PDK_PATH -I ../ -I ../../../verilog/rtl -I ../../../verilog/rtl/syntacore/scr1/src/includes -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model user_risc_boot_tb.v -o user_risc_boot_tb.vvp
+
+vvp user_risc_boot_tb.vvp | tee test.log
+
+\rm -rf user_risc_boot_tb.vvp
diff --git a/verilog/dv/user_risc_boot/uprj_netlists.v b/verilog/dv/user_risc_boot/uprj_netlists.v
new file mode 100644
index 0000000..45af4a9
--- /dev/null
+++ b/verilog/dv/user_risc_boot/uprj_netlists.v
@@ -0,0 +1,74 @@
+// 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
+`define USE_POWER_PINS
+
+ `include "spi_master/src/spim_top.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 "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 "digital_core/src/digital_core.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_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_top_wb.sv"
+ `include "lib/sync_fifo.sv"
diff --git a/verilog/dv/user_risc_boot/user_risc_boot.c b/verilog/dv/user_risc_boot/user_risc_boot.c
new file mode 100644
index 0000000..3e9abeb
--- /dev/null
+++ b/verilog/dv/user_risc_boot/user_risc_boot.c
@@ -0,0 +1,45 @@
+
+#define SC_SIM_OUTPORT (0xf0000000)
+#define uint32_t long
+
+#define reg_mprj_globl_reg0 (*(volatile uint32_t*)0x30000000)
+#define reg_mprj_globl_reg1 (*(volatile uint32_t*)0x30000004)
+#define reg_mprj_globl_reg2 (*(volatile uint32_t*)0x30000008)
+#define reg_mprj_globl_reg3 (*(volatile uint32_t*)0x3000000C)
+#define reg_mprj_globl_reg4 (*(volatile uint32_t*)0x30000010)
+#define reg_mprj_globl_reg5 (*(volatile uint32_t*)0x30000014)
+#define reg_mprj_globl_reg6 (*(volatile uint32_t*)0x30000018)
+#define reg_mprj_globl_reg7 (*(volatile uint32_t*)0x3000001C)
+#define reg_mprj_globl_reg8 (*(volatile uint32_t*)0x30000020)
+#define reg_mprj_globl_reg9 (*(volatile uint32_t*)0x30000024)
+#define reg_mprj_globl_reg10 (*(volatile uint32_t*)0x30000028)
+#define reg_mprj_globl_reg11 (*(volatile uint32_t*)0x3000002C)
+#define reg_mprj_globl_reg12 (*(volatile uint32_t*)0x30000030)
+#define reg_mprj_globl_reg13 (*(volatile uint32_t*)0x30000034)
+#define reg_mprj_globl_reg14 (*(volatile uint32_t*)0x30000038)
+#define reg_mprj_globl_reg15 (*(volatile uint32_t*)0x3000003C)
+
+int main()
+{
+
+ //volatile long *out_ptr = (volatile long*)SC_SIM_OUTPORT;
+ //*out_ptr = 0xAABBCCDD;
+ //*out_ptr = 0xBBCCDDEE;
+ //*out_ptr = 0xCCDDEEFF;
+ //*out_ptr = 0xDDEEFF00;
+
+ // Write software Write & Read Register
+ reg_mprj_globl_reg6 = 0x11223344;
+ reg_mprj_globl_reg7 = 0x22334455;
+ reg_mprj_globl_reg8 = 0x33445566;
+ reg_mprj_globl_reg9 = 0x44556677;
+ reg_mprj_globl_reg10 = 0x55667788;
+ reg_mprj_globl_reg11 = 0x66778899;
+ //reg_mprj_globl_reg12 = 0x778899AA;
+ //reg_mprj_globl_reg13 = 0x8899AABB;
+ //reg_mprj_globl_reg14 = 0x99AABBCC;
+ //reg_mprj_globl_reg15 = 0xAABBCCDD;
+
+ while(1) {}
+ return 0;
+}
diff --git a/verilog/dv/user_risc_boot/user_risc_boot.hex b/verilog/dv/user_risc_boot/user_risc_boot.hex
new file mode 100755
index 0000000..1fdd96c
--- /dev/null
+++ b/verilog/dv/user_risc_boot/user_risc_boot.hex
@@ -0,0 +1,79 @@
+@00000000
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 13 00 00 00 6F 00 00 00 FF FF FF FF
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+6F 00 E0 18 13 00 00 00 13 00 00 00 13 00 00 00
+13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00
+13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00
+13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00
+93 00 00 00 13 01 00 00 93 01 00 00 13 02 00 00
+93 02 00 00 13 03 00 00 93 03 00 00 13 04 00 00
+93 04 00 00 13 05 00 00 93 05 00 00 13 06 00 00
+93 06 00 00 13 07 00 00 93 07 00 00 13 08 00 00
+93 08 00 00 13 09 00 00 93 09 00 00 13 0A 00 00
+93 0A 00 00 13 0B 00 00 93 0B 00 00 13 0C 00 00
+93 0C 00 00 13 0D 00 00 93 0D 00 00 13 0E 00 00
+93 0E 00 00 13 0F 00 00 93 0F 00 00 97 01 48 00
+93 81 41 62 13 05 00 40 97 05 48 00 93 85 85 D7
+17 06 48 00 13 06 06 E3 63 0D B5 00 29 A0 14 41
+94 C1 11 05 91 05 E3 9C C5 FE 17 06 48 00 13 06
+66 E1 97 05 48 00 93 85 E5 E0 21 A0 23 20 06 00
+11 06 E3 9D C5 FE 17 01 49 00 13 01 A1 D3 17 05
+48 00 13 05 25 DF 17 06 48 00 13 06 A6 DE B3 05
+A6 40 17 07 49 00 13 07 E7 91 33 02 B7 40 92 85
+17 06 48 00 13 06 06 DD 29 A0 14 41 94 C1 11 05
+91 05 E3 1C C5 FE 21 A0 23 A0 05 00 91 05 E3 9D
+E5 FE B7 02 49 00 05 43 23 A0 62 00 B7 02 49 00
+91 02 13 03 30 06 23 A0 62 00 B7 02 49 00 C1 02
+7D 53 23 A0 62 00 23 A2 62 00 01 45 81 45 97 02
+48 00 E7 80 22 CC 97 02 48 00 93 82 A2 D1 6D 71
+06 C2 0A C4 0E C6 12 C8 16 CA 1A CC 1E CE 22 D0
+26 D2 2A D4 2E D6 32 D8 36 DA 3A DC 3E DE C2 C0
+C6 C2 CA C4 CE C6 D2 C8 D6 CA DA CC DE CE E2 D0
+E6 D2 EA D4 EE D6 F2 D8 F6 DA FA DC FE DE 73 25
+20 34 F3 25 10 34 0A 86 EF 00 80 04 92 40 22 41
+B2 41 42 42 D2 42 62 43 F2 43 02 54 92 54 22 55
+B2 55 42 56 D2 56 62 57 F2 57 06 48 96 48 26 49
+B6 49 46 4A D6 4A 66 4B F6 4B 06 5C 96 5C 26 5D
+B6 5D 46 5E D6 5E 66 5F F6 5F 51 61 73 00 20 30
+6F F0 5F D1 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+@00000400
+37 37 22 11 B7 07 00 30 93 02 47 34 37 43 33 22
+23 AC 57 00 93 03 53 45 37 55 44 33 23 AE 77 00
+93 05 65 56 37 66 55 44 8C D3 93 06 76 67 37 78
+66 55 D4 D3 93 08 88 78 37 9E 77 66 23 A4 17 03
+93 0E 9E 89 23 A6 D7 03 01 A0 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+97 02 B8 FF 93 82 42 09 82 82 13 00 00 00 13 00
+00 00 13 00 00 00 13 00 00 00 13 00 00 00 01 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+@000004A0
+13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
diff --git a/verilog/dv/user_risc_boot/user_risc_boot_tb.v b/verilog/dv/user_risc_boot/user_risc_boot_tb.v
new file mode 100644
index 0000000..efab5eb
--- /dev/null
+++ b/verilog/dv/user_risc_boot/user_risc_boot_tb.v
@@ -0,0 +1,397 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Standalone User validation Test bench ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// 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 none
+
+`timescale 1 ns / 1 ps
+
+`include "uprj_netlists.v"
+`include "spiflash.v"
+`include "mt48lc8m8a2.v"
+
+module user_risc_boot_tb;
+ reg clock;
+ reg RSTB;
+ 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
+
+ // 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;
+
+
+
+ // 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);
+
+ 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("risc_boot.vcd");
+ $dumpvars(0, user_risc_boot_tb);
+ end
+ `endif
+
+ initial begin
+
+ #200; // Wait for reset removal
+ repeat (10) @(posedge clock);
+ $display("Monitor: Standalone User Risc Boot Test Started");
+
+ #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_2242);
+
+ repeat (2) @(posedge clock);
+ #1;
+ // Remove all the reset
+ wb_user_core_write('h3000_0000,'h7);
+
+
+ // Repeat cycles of 1000 clock edges as needed to complete testbench
+ repeat (30) begin
+ repeat (1000) @(posedge clock);
+ // $display("+1000 cycles");
+ end
+
+
+ $display("Monitor: Reading Back the expected value");
+ // User RISC core expect to write these value in global
+ // register, read back and decide on pass fail
+ // 0x30000018 = 0x11223344;
+ // 0x3000001C = 0x22334455;
+ // 0x30000020 = 0x33445566;
+ // 0x30000024 = 0x44556677;
+ // 0x30000028 = 0x55667788;
+ // 0x3000002C = 0x66778899;
+
+ test_fail = 0;
+ wb_user_core_read(32'h30000018,read_data);
+ if(read_data != 32'h11223344) test_fail = 1;
+
+ wb_user_core_read(32'h3000001C,read_data);
+ if(read_data != 32'h22334455) test_fail = 1;
+
+ wb_user_core_read(32'h30000020,read_data);
+ if(read_data != 32'h33445566) test_fail = 1;
+
+ wb_user_core_read(32'h30000024,read_data);
+ if(read_data!= 32'h44556677) test_fail = 1;
+
+ wb_user_core_read(32'h30000028,read_data);
+ if(read_data!= 32'h55667788) test_fail = 1;
+
+ wb_user_core_read(32'h3000002C,read_data) ;
+ if(read_data != 32'h66778899) test_fail = 1;
+
+
+ $display("###################################################");
+ if(test_fail == 0) begin
+ `ifdef GL
+ $display("Monitor: Standalone User Risc Boot (GL) Passed");
+ `else
+ $display("Monitor: Standalone User Risc Boot (RTL) Passed");
+ `endif
+ end else begin
+ `ifdef GL
+ $display("Monitor: Standalone User Risc Boot (GL) Failed");
+ `else
+ $display("Monitor: Standalone User Risc Boot (RTL) Failed");
+ `endif
+ end
+ $display("###################################################");
+ $finish;
+ end
+
+ initial begin
+ RSTB <= 1'b0;
+ #100;
+ RSTB <= 1'b1; // Release reset
+ end
+
+
+ digital_core u_core(
+`ifdef USE_POWER_PINS
+ .vdda1(), // User area 1 3.3V supply
+ .vdda2(), // User area 2 3.3V supply
+ .vssa1(), // User area 1 analog ground
+ .vssa2(), // User area 2 analog ground
+ .vccd1(), // User area 1 1.8V supply
+ .vccd2(), // User area 2 1.8v supply
+ .vssd1(), // User area 1 digital ground
+ .vssd2(), // User area 2 digital ground
+`endif
+ .clk (clock), // System clock
+ .rtc_clk (1'b1), // Real-time clock
+ .rst_n (RSTB), // Regular Reset signal
+
+ .wbd_ext_cyc_i (wbd_ext_cyc_i), // strobe/request
+ .wbd_ext_stb_i (wbd_ext_stb_i), // strobe/request
+ .wbd_ext_adr_i (wbd_ext_adr_i), // address
+ .wbd_ext_we_i (wbd_ext_we_i), // write
+ .wbd_ext_dat_i (wbd_ext_dat_i), // data output
+ .wbd_ext_sel_i (wbd_ext_sel_i), // byte enable
+
+ .wbd_ext_dat_o (wbd_ext_dat_o), // data input
+ .wbd_ext_ack_o (wbd_ext_ack_o), // acknowlegement
+ .wbd_ext_err_o (wbd_ext_err_o), // error
+
+
+ // 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) ,
+
+ .irq ()
+
+);
+
+//------------------------------------------------------
+// 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];
+ 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
+ spiflash #(
+ .FILENAME("user_risc_boot.hex")
+ ) u_user_spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(flash_io2),
+ .io3(flash_io3)
+ );
+
+
+//------------------------------------------------
+// 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);
+ 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);
+ 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);
+ 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);
+ 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
+
+
+
+
+////-----------------------------------------------------------------------------
+//// RISC IMEM amd DMEM Monitoring TASK
+////-----------------------------------------------------------------------------
+//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 user_risc_boot_tb.u_core.u_riscv_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
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/wb_port/Makefile b/verilog/dv/wb_port/Makefile
index 132a1cc..f1565bb 100644
--- a/verilog/dv/wb_port/Makefile
+++ b/verilog/dv/wb_port/Makefile
@@ -26,6 +26,8 @@
UPRJ_VERILOG_PATH ?= ../../../verilog
UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl
UPRJ_BEHAVIOURAL_MODELS = ../
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
## RISCV GCC
GCC_PATH?=/ef/apps/bin
@@ -43,11 +45,14 @@
hex: ${PATTERN:=.hex}
+vvp: ${PATTERN:=.vvp}
+
%.vvp: %_tb.v %.hex
ifeq ($(SIM),RTL)
- iverilog -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+ 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_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) \
$< -o $@
else
iverilog -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
diff --git a/verilog/dv/wb_port/wb_port.c b/verilog/dv/wb_port/wb_port.c
index 425c115..079d1ef 100644
--- a/verilog/dv/wb_port/wb_port.c
+++ b/verilog/dv/wb_port/wb_port.c
@@ -19,6 +19,27 @@
#include "verilog/dv/caravel/defs.h"
#include "verilog/dv/caravel/stub.c"
+// User Project Slaves (0x3000_0000)
+#define reg_mprj_slave (*(volatile uint32_t*)0x30000000)
+
+#define reg_mprj_globl_reg0 (*(volatile uint32_t*)0x30000000)
+#define reg_mprj_globl_reg1 (*(volatile uint32_t*)0x30000004)
+#define reg_mprj_globl_reg2 (*(volatile uint32_t*)0x30000008)
+#define reg_mprj_globl_reg3 (*(volatile uint32_t*)0x3000000C)
+#define reg_mprj_globl_reg4 (*(volatile uint32_t*)0x30000010)
+#define reg_mprj_globl_reg5 (*(volatile uint32_t*)0x30000014)
+#define reg_mprj_globl_reg6 (*(volatile uint32_t*)0x30000018)
+#define reg_mprj_globl_reg7 (*(volatile uint32_t*)0x3000001C)
+#define reg_mprj_globl_reg8 (*(volatile uint32_t*)0x30000020)
+#define reg_mprj_globl_reg9 (*(volatile uint32_t*)0x30000024)
+#define reg_mprj_globl_reg10 (*(volatile uint32_t*)0x30000028)
+#define reg_mprj_globl_reg11 (*(volatile uint32_t*)0x3000002C)
+#define reg_mprj_globl_reg12 (*(volatile uint32_t*)0x30000030)
+#define reg_mprj_globl_reg13 (*(volatile uint32_t*)0x30000034)
+#define reg_mprj_globl_reg14 (*(volatile uint32_t*)0x30000038)
+#define reg_mprj_globl_reg15 (*(volatile uint32_t*)0x3000003C)
+
+
/*
Wishbone Test:
- Configures MPRJ lower 8-IO pins as outputs
@@ -30,6 +51,7 @@
void main()
{
+ int bFail = 0;
/*
IO Control Registers
| DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN |
@@ -80,8 +102,34 @@
// Flag start of the test
reg_mprj_datal = 0xAB600000;
- reg_mprj_slave = 0x00002710;
- if (reg_mprj_slave == 0x2752) {
+ if (reg_mprj_globl_reg1 != 0xA55AA55A) bFail = 1;
+ if (reg_mprj_globl_reg2 != 0xAABBCCDD) bFail = 1;
+
+ // Write software Write & Read Register
+ reg_mprj_globl_reg6 = 0x11223344;
+ reg_mprj_globl_reg7 = 0x22334455;
+ reg_mprj_globl_reg8 = 0x33445566;
+ reg_mprj_globl_reg9 = 0x44556677;
+ reg_mprj_globl_reg10 = 0x55667788;
+ reg_mprj_globl_reg11 = 0x66778899;
+ reg_mprj_globl_reg12 = 0x778899AA;
+ reg_mprj_globl_reg13 = 0x8899AABB;
+ reg_mprj_globl_reg14 = 0x99AABBCC;
+ reg_mprj_globl_reg15 = 0xAABBCCDD;
+
+
+ if (reg_mprj_globl_reg6 != 0x11223344) bFail = 1;
+ if (reg_mprj_globl_reg7 != 0x22334455) bFail = 1;
+ if (reg_mprj_globl_reg8 != 0x33445566) bFail = 1;
+ if (reg_mprj_globl_reg9 != 0x44556677) bFail = 1;
+ if (reg_mprj_globl_reg10 != 0x55667788) bFail = 1;
+ if (reg_mprj_globl_reg11 != 0x66778899) bFail = 1;
+ if (reg_mprj_globl_reg12 != 0x778899AA) bFail = 1;
+ if (reg_mprj_globl_reg13 != 0x8899AABB) bFail = 1;
+ if (reg_mprj_globl_reg14 != 0x99AABBCC) bFail = 1;
+ if (reg_mprj_globl_reg15 != 0xAABBCCDD) bFail = 1;
+
+ if(bFail == 0) {
reg_mprj_datal = 0xAB610000;
} else {
reg_mprj_datal = 0xAB600000;
diff --git a/verilog/dv/wb_port/wb_port_tb.v b/verilog/dv/wb_port/wb_port_tb.v
index b32f900..2455069 100644
--- a/verilog/dv/wb_port/wb_port_tb.v
+++ b/verilog/dv/wb_port/wb_port_tb.v
@@ -47,9 +47,14 @@
clock = 0;
end
+ `ifdef WFDUMP
initial begin
$dumpfile("wb_port.vcd");
- $dumpvars(0, wb_port_tb);
+ $dumpvars(0, wb_port_tb.uut.mprj);
+ end
+ `endif
+
+ initial begin
// Repeat cycles of 1000 clock edges as needed to complete testbench
repeat (30) begin
@@ -57,11 +62,13 @@
// $display("+1000 cycles");
end
$display("%c[1;31m",27);
+ $display ("##########################################################");
`ifdef GL
$display ("Monitor: Timeout, Test Mega-Project WB Port (GL) Failed");
`else
$display ("Monitor: Timeout, Test Mega-Project WB Port (RTL) Failed");
`endif
+ $display ("##########################################################");
$display("%c[0m",27);
$finish;
end
@@ -70,11 +77,13 @@
wait(checkbits == 16'h AB60);
$display("Monitor: MPRJ-Logic WB Started");
wait(checkbits == 16'h AB61);
+ $display ("##########################################################");
`ifdef GL
$display("Monitor: Mega-Project WB (GL) Passed");
`else
$display("Monitor: Mega-Project WB (RTL) Passed");
`endif
+ $display ("##########################################################");
$finish;
end
@@ -102,9 +111,9 @@
power4 <= 1'b1;
end
- always @(mprj_io) begin
- #1 $display("MPRJ-IO state = %b ", mprj_io[7:0]);
- end
+ //always @(mprj_io) begin
+ // #1 $display("MPRJ-IO state = %b ", mprj_io[7:0]);
+ //end
wire flash_csb;
wire flash_clk;
@@ -154,4 +163,4 @@
);
endmodule
-`default_nettype wire
\ No newline at end of file
+`default_nettype wire
diff --git a/verilog/rtl/digital_core/src/glbl_cfg.sv b/verilog/rtl/digital_core/src/glbl_cfg.sv
new file mode 100644
index 0000000..c44e20c
--- /dev/null
+++ b/verilog/rtl/digital_core/src/glbl_cfg.sv
@@ -0,0 +1,1056 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Global confg register ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block generate all the global config and status ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 08 June 2021 Dinesh A ////
+//// Initial version ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module glbl_cfg (
+
+ input logic mclk,
+ input logic reset_n,
+ output logic [31:0] device_idcode,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [3:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ // SDRAM Clock
+
+ output logic sdram_clk,
+
+ // reset
+ output logic cpu_rst_n,
+ output logic spi_rst_n,
+ output logic sdram_rst_n,
+
+ // Risc configuration
+ output logic [31:0] fuse_mhartid,
+ output logic [15:0] irq_lines,
+ output logic soft_irq,
+
+ // SDRAM Config
+ input logic sdr_init_done , // Indicate SDRAM Initialisation Done
+ output logic [1:0] cfg_sdr_width , // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit
+ output logic [1:0] cfg_colbits , // 2'b00 - 8 Bit column address,
+ output logic [3:0] cfg_sdr_tras_d , // Active to precharge delay
+ output logic [3:0] cfg_sdr_trp_d , // Precharge to active delay
+ output logic [3:0] cfg_sdr_trcd_d , // Active to R/W delay
+ output logic cfg_sdr_en , // Enable SDRAM controller
+ output logic [1:0] cfg_req_depth , // Maximum Request accepted by SDRAM controller
+ output logic [12:0] cfg_sdr_mode_reg ,
+ output logic [2:0] cfg_sdr_cas , // SDRAM CAS Latency
+ output logic [3:0] cfg_sdr_trcar_d , // Auto-refresh period
+ output logic [3:0] cfg_sdr_twr_d , // Write recovery delay
+ output logic [11:0] cfg_sdr_rfsh ,
+ output logic [2:0] cfg_sdr_rfmax
+
+
+ );
+
+
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+logic sw_rd_en;
+logic sw_wr_en;
+logic [3:0] sw_addr ; // addressing 16 registers
+logic [3:0] wr_be ;
+logic [31:0] sw_reg_wdata;
+
+logic reg_cs_l ;
+logic reg_cs_2l ;
+logic cfg_sdram_clk_div;
+
+
+logic [31:0] reg_0; // Software_Reg_0
+logic [31:0] reg_1; // Software-Reg_1
+logic [31:0] reg_2; // Software-Reg_2
+logic [31:0] reg_3; // Software-Reg_3
+logic [31:0] reg_4; // Software-Reg_4
+logic [31:0] reg_5; // Software-Reg_5
+logic [31:0] reg_6; // Software-Reg_6
+logic [31:0] reg_7; // Software-Reg_7
+logic [31:0] reg_8; // Software-Reg_8
+logic [31:0] reg_9; // Software-Reg_9
+logic [31:0] reg_10; // Software-Reg_10
+logic [31:0] reg_11; // Software-Reg_11
+logic [31:0] reg_12; // Software-Reg_12
+logic [31:0] reg_13; // Software-Reg_13
+logic [31:0] reg_14; // Software-Reg_14
+logic [31:0] reg_15; // Software-Reg_15
+logic [31:0] reg_out;
+
+//-----------------------------------------------------------------------
+// Main code starts here
+//-----------------------------------------------------------------------
+
+//-----------------------------------------------------------------------
+// To avoid interface timing, all the content are registered
+//-----------------------------------------------------------------------
+always @ (posedge mclk or negedge reset_n)
+begin
+ if (reset_n == 1'b0)
+ begin
+ sw_addr <= '0;
+ sw_rd_en <= '0;
+ sw_wr_en <= '0;
+ sw_reg_wdata <= '0;
+ wr_be <= '0;
+ reg_cs_l <= '0;
+ reg_cs_2l <= '0;
+ end else begin
+ sw_addr <= reg_addr [3:0];
+ sw_rd_en <= reg_cs & !reg_wr;
+ sw_wr_en <= reg_cs & reg_wr;
+ sw_reg_wdata <= reg_wdata;
+ wr_be <= reg_be;
+ reg_cs_l <= reg_cs;
+ reg_cs_2l <= reg_cs_l;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// Read path mux
+//-----------------------------------------------------------------------
+
+always @ (posedge mclk or negedge reset_n)
+begin : preg_out_Seq
+ if (reset_n == 1'b0) begin
+ reg_rdata [31:0] <= 32'h0000_0000;
+ reg_ack <= 1'b0;
+ end else if (sw_rd_en && !reg_ack && !reg_cs_2l) begin
+ reg_rdata [31:0] <= reg_out [31:0];
+ reg_ack <= 1'b1;
+ end else if (sw_wr_en && !reg_ack && !reg_cs_2l) begin
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 4'h0);
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 4'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 4'h1);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 4'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 4'h2);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 4'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 4'h3);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 4'h3);
+wire sw_wr_en_4 = sw_wr_en & (sw_addr == 4'h4);
+wire sw_rd_en_4 = sw_rd_en & (sw_addr == 4'h4);
+wire sw_wr_en_5 = sw_wr_en & (sw_addr == 4'h5);
+wire sw_rd_en_5 = sw_rd_en & (sw_addr == 4'h5);
+wire sw_wr_en_6 = sw_wr_en & (sw_addr == 4'h6);
+wire sw_rd_en_6 = sw_rd_en & (sw_addr == 4'h6);
+wire sw_wr_en_7 = sw_wr_en & (sw_addr == 4'h7);
+wire sw_rd_en_7 = sw_rd_en & (sw_addr == 4'h7);
+wire sw_wr_en_8 = sw_wr_en & (sw_addr == 4'h8);
+wire sw_rd_en_8 = sw_rd_en & (sw_addr == 4'h8);
+wire sw_wr_en_9 = sw_wr_en & (sw_addr == 4'h9);
+wire sw_rd_en_9 = sw_rd_en & (sw_addr == 4'h9);
+wire sw_wr_en_10 = sw_wr_en & (sw_addr == 4'hA);
+wire sw_rd_en_10 = sw_rd_en & (sw_addr == 4'hA);
+wire sw_wr_en_11 = sw_wr_en & (sw_addr == 4'hB);
+wire sw_rd_en_11 = sw_rd_en & (sw_addr == 4'hB);
+wire sw_wr_en_12 = sw_wr_en & (sw_addr == 4'hC);
+wire sw_rd_en_12 = sw_rd_en & (sw_addr == 4'hC);
+wire sw_wr_en_13 = sw_wr_en & (sw_addr == 4'hD);
+wire sw_rd_en_13 = sw_rd_en & (sw_addr == 4'hD);
+wire sw_wr_en_14 = sw_wr_en & (sw_addr == 4'hE);
+wire sw_rd_en_14 = sw_rd_en & (sw_addr == 4'hE);
+wire sw_wr_en_15 = sw_wr_en & (sw_addr == 4'hF);
+wire sw_rd_en_15 = sw_rd_en & (sw_addr == 4'hF);
+
+
+always @( *)
+begin : preg_sel_Com
+
+ reg_out [31:0] = 32'd0;
+
+ case (sw_addr [3:0])
+ 4'b0000 : reg_out [31:0] = reg_0 [31:0];
+ 4'b0001 : reg_out [31:0] = reg_1 [31:0];
+ 4'b0010 : reg_out [31:0] = reg_2 [31:0];
+ 4'b0011 : reg_out [31:0] = reg_3 [31:0];
+ 4'b0100 : reg_out [31:0] = reg_4 [31:0];
+ 4'b0101 : reg_out [31:0] = reg_5 [31:0];
+ 4'b0110 : reg_out [31:0] = reg_6 [31:0];
+ 4'b0111 : reg_out [31:0] = reg_7 [31:0];
+ 4'b1000 : reg_out [31:0] = reg_8 [31:0];
+ 4'b1001 : reg_out [31:0] = reg_9 [31:0];
+ 4'b1010 : reg_out [31:0] = reg_10 [31:0];
+ 4'b1011 : reg_out [31:0] = reg_11 [31:0];
+ 4'b1100 : reg_out [31:0] = reg_12 [31:0];
+ 4'b1101 : reg_out [31:0] = reg_13 [31:0];
+ 4'b1110 : reg_out [31:0] = reg_14 [31:0];
+ 4'b1111 : reg_out [31:0] = reg_15 [31:0];
+ endcase
+end
+
+
+
+//-----------------------------------------------------------------------
+// Individual register assignments
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// reg-0
+// -----------------------------------------------------------------
+
+assign cpu_rst_n = reg_0[0];
+assign spi_rst_n = reg_0[1];
+assign sdram_rst_n = reg_0[2];
+assign cfg_sdram_clk_div = reg_0[3];
+
+
+
+generic_register #(8,0 ) u_reg0_be0 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg0_be1 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[15:8] )
+ );
+generic_register #(8,0 ) u_reg0_be2 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg0_be3 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[31:24] )
+ );
+
+
+
+//-----------------------------------------------------------------------
+// reg-1, reset value = 32'hA55A_A55A
+// -----------------------------------------------------------------
+assign device_idcode = reg_1[31:0];
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'h5A)) u_reg1_be0 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[7:0] )
+ );
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hA5) ) u_reg1_be1 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[15:8] )
+ );
+generic_register #(.WD(8),.RESET_DEFAULT(8'h5A) ) u_reg1_be2 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[23:16] )
+ );
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hA5) ) u_reg1_be3 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[31:24] )
+ );
+
+//-----------------------------------------------------------------------
+// reg-2, reset value = 32'hAABBCCDD
+//-----------------------------------------------------------------
+assign fuse_mhartid = reg_1[31:0];
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hDD) ) u_reg2_be0 (
+ .we ({8{sw_wr_en_2 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[7:0] )
+ );
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hCC) ) u_reg2_be1 (
+ .we ({8{sw_wr_en_2 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[15:8] )
+ );
+generic_register #(.WD(8),.RESET_DEFAULT(8'hBB) ) u_reg2_be2 (
+ .we ({8{sw_wr_en_2 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[23:16] )
+ );
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hAA) ) u_reg2_be3 (
+ .we ({8{sw_wr_en_2 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[31:24] )
+ );
+
+//-----------------------------------------------------------------------
+// reg-3
+//-----------------------------------------------------------------
+assign irq_lines = reg_3[15:0];
+assign soft_irq = reg_3[16];
+
+generic_register #(8,0 ) u_reg3_be0 (
+ .we ({8{sw_wr_en_3 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_3[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg3_be1 (
+ .we ({8{sw_wr_en_3 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_3[15:8] )
+ );
+generic_register #(1,0 ) u_reg3_be2 (
+ .we ({1{sw_wr_en_3 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_3[16] )
+ );
+
+assign reg_3[31:17] = '0;
+
+
+//-----------------------------------------------------------------------
+// reg-4
+// recommended Default value:
+// 1'b1,3'h3,2'h3,4'h1,4'h7',4'h2,4'h2,4'h4,2'b00,2'b10 = 32'h2F17_2242
+//-----------------------------------------------------------------
+assign cfg_sdr_width = reg_4[1:0] ; // 2'b10 // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit
+assign cfg_colbits = reg_4[3:2] ; // 2'b00 // 8 Bit column address,
+assign cfg_sdr_tras_d = reg_4[7:4] ; // 4'h4 // Active to precharge delay
+assign cfg_sdr_trp_d = reg_4[11:8]; // 4'h2 // Precharge to active delay
+assign cfg_sdr_trcd_d = reg_4[15:12]; // 4'h2 // Active to R/W delay
+assign cfg_sdr_trcar_d = reg_4[19:16]; // 4'h7 // Auto-refresh period
+assign cfg_sdr_twr_d = reg_4[23:20]; // 4'h1 // Write recovery delay
+assign cfg_req_depth = reg_4[25:24]; // 2'h3 // Maximum Request accepted by SDRAM controller
+assign cfg_sdr_cas = reg_4[28:26]; // 3'h3 // SDRAM CAS Latency
+assign cfg_sdr_en = reg_4[29] ; // 1'b1 // Enable SDRAM controller
+assign reg_4[30] = sdr_init_done ; // Indicate SDRAM Initialisation Done
+assign reg_4[31] = 1'b0;
+
+
+generic_register #(8,0 ) u_reg4_be0 (
+ .we ({8{sw_wr_en_4 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg4_be1 (
+ .we ({8{sw_wr_en_4 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[15:8] )
+ );
+generic_register #(8,0 ) u_reg4_be2 (
+ .we ({8{sw_wr_en_4 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[23:16] )
+ );
+
+generic_register #(6,0 ) u_reg4_be3 (
+ .we ({6{sw_wr_en_4 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[29:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[29:24] )
+ );
+//-----------------------------------------------------------------------
+// reg-5, recomended default value {12'h100,13'h33,3'h6} = 32'h100_019E
+//-----------------------------------------------------------------
+assign cfg_sdr_rfmax = reg_5[2:0] ; // 3'h6
+assign cfg_sdr_mode_reg = reg_5[15:3] ; // 13'h033
+assign cfg_sdr_rfsh = reg_5[27:16]; // 12'h100
+
+generic_register #(8,0 ) u_reg5_be0 (
+ .we ({8{sw_wr_en_5 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_5[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg5_be1 (
+ .we ({8{sw_wr_en_5 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_5[15:8] )
+ );
+generic_register #(8,0 ) u_reg5_be2 (
+ .we ({8{sw_wr_en_5 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_5[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg5_be3 (
+ .we ({8{sw_wr_en_5 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_5[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 6
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg6_be0 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg6_be1 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[15:8] )
+ );
+generic_register #(8,0 ) u_reg6_be2 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg6_be3 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 7
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg7_be0 (
+ .we ({8{sw_wr_en_7 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_7[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg7_be1 (
+ .we ({8{sw_wr_en_7 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_7[15:8] )
+ );
+generic_register #(8,0 ) u_reg7_be2 (
+ .we ({8{sw_wr_en_7 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_7[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg7_be3 (
+ .we ({8{sw_wr_en_7 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_7[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 8
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg8_be0 (
+ .we ({8{sw_wr_en_8 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_8[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg8_be1 (
+ .we ({8{sw_wr_en_8 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_8[15:8] )
+ );
+generic_register #(8,0 ) u_reg8_be2 (
+ .we ({8{sw_wr_en_8 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_8[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg8_be3 (
+ .we ({8{sw_wr_en_8 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_8[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 9
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg9_be0 (
+ .we ({8{sw_wr_en_9 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_9[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg9_be1 (
+ .we ({8{sw_wr_en_9 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_9[15:8] )
+ );
+generic_register #(8,0 ) u_reg9_be2 (
+ .we ({8{sw_wr_en_9 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_9[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg9_be3 (
+ .we ({8{sw_wr_en_9 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_9[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 10
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg10_be0 (
+ .we ({8{sw_wr_en_10 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_10[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg10_be1 (
+ .we ({8{sw_wr_en_10 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_10[15:8] )
+ );
+generic_register #(8,0 ) u_reg10_be2 (
+ .we ({8{sw_wr_en_10 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_10[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg10_be3 (
+ .we ({8{sw_wr_en_10 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_10[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 11
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg11_be0 (
+ .we ({8{sw_wr_en_11 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_11[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg11_be1 (
+ .we ({8{sw_wr_en_11 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_11[15:8] )
+ );
+generic_register #(8,0 ) u_reg11_be2 (
+ .we ({8{sw_wr_en_11 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_11[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg11_be3 (
+ .we ({8{sw_wr_en_11 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_11[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 12
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg12_be0 (
+ .we ({8{sw_wr_en_12 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_12[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg12_be1 (
+ .we ({8{sw_wr_en_12 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_12[15:8] )
+ );
+generic_register #(8,0 ) u_reg12_be2 (
+ .we ({8{sw_wr_en_12 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_12[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg12_be3 (
+ .we ({8{sw_wr_en_12 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_12[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 13
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg13_be0 (
+ .we ({8{sw_wr_en_13 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_13[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg13_be1 (
+ .we ({8{sw_wr_en_13 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_13[15:8] )
+ );
+generic_register #(8,0 ) u_reg13_be2 (
+ .we ({8{sw_wr_en_13 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_13[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg13_be3 (
+ .we ({8{sw_wr_en_13 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_13[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 14
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg14_be0 (
+ .we ({8{sw_wr_en_14 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_14[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg14_be1 (
+ .we ({8{sw_wr_en_14 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_14[15:8] )
+ );
+generic_register #(8,0 ) u_reg14_be2 (
+ .we ({8{sw_wr_en_14 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_14[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg14_be3 (
+ .we ({8{sw_wr_en_14 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_14[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 15
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg15_be0 (
+ .we ({8{sw_wr_en_15 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_15[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg15_be1 (
+ .we ({8{sw_wr_en_15 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_15[15:8] )
+ );
+generic_register #(8,0 ) u_reg15_be2 (
+ .we ({8{sw_wr_en_15 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_15[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg15_be3 (
+ .we ({8{sw_wr_en_15 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_15[31:24] )
+ );
+
+
+
+
+//----------------------------------
+// Generate SDRAM Div-2 Clock
+//----------------------------------
+wire sdram_clk_div2;
+
+assign sdram_clk = (cfg_sdram_clk_div) ? sdram_clk_div2 : mclk;
+
+
+clk_ctl #(1) u_sdramclk (
+ // Outputs
+ .clk_o (sdram_clk_div2),
+ // Inputs
+ .mclk (mclk),
+ .reset_n (reset_n),
+ .clk_div_ratio (2'b00)
+ );
+
+
+
+endmodule
diff --git a/verilog/rtl/lib/clk_ctl.v b/verilog/rtl/lib/clk_ctl.v
new file mode 100644
index 0000000..7f050c0
--- /dev/null
+++ b/verilog/rtl/lib/clk_ctl.v
@@ -0,0 +1,126 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Tubo 8051 cores common library Module ////
+//// ////
+//// This file is part of the Turbo 8051 cores project ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//// Description ////
+//// Turbo 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Mar 2, 2011 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+// #################################################################
+// Module: clk_ctl
+//
+// Description: Generic clock control logic , clk-out = mclk/(2+clk_div_ratio)
+//
+//
+// #################################################################
+
+
+module clk_ctl (
+ // Outputs
+ clk_o,
+ // Inputs
+ mclk,
+ reset_n,
+ clk_div_ratio
+ );
+
+//---------------------------------
+// CLOCK Default Divider value.
+// This value will be change from outside
+//---------------------------------
+parameter WD = 'h1;
+
+//---------------------------------------------
+// All the input to this block are declared here
+// --------------------------------------------
+ input mclk ;//
+ input reset_n ;// primary reset signal
+ input [WD:0] clk_div_ratio ;// primary clock divide ratio
+ // output clock = selected clock / (div_ratio+1)
+
+//---------------------------------------------
+// All the output to this block are declared here
+// --------------------------------------------
+ output clk_o ; // clock out
+
+
+
+//------------------------------------
+// Clock Divide func is done here
+//------------------------------------
+reg [WD-1:0] high_count ; // high level counter
+reg [WD-1:0] low_count ; // low level counter
+reg mclk_div ; // divided clock
+
+
+assign clk_o = mclk_div;
+
+always @ (posedge mclk or negedge reset_n)
+begin // {
+ if(reset_n == 1'b0)
+ begin
+ high_count <= 'h0;
+ low_count <= 'h0;
+ mclk_div <= 'b0;
+ end
+ else
+ begin
+ if(high_count != 0)
+ begin // {
+ high_count <= high_count - 1;
+ mclk_div <= 1'b1;
+ end // }
+ else if(low_count != 0)
+ begin // {
+ low_count <= low_count - 1;
+ mclk_div <= 1'b0;
+ end // }
+ else
+ begin // {
+ high_count <= clk_div_ratio[WD:1] + clk_div_ratio[0];
+ low_count <= clk_div_ratio[WD:1] + 1;
+ mclk_div <= ~mclk_div;
+ end // }
+ end // }
+end // }
+
+
+endmodule
+
diff --git a/verilog/rtl/lib/registers.v b/verilog/rtl/lib/registers.v
new file mode 100755
index 0000000..665ef0a
--- /dev/null
+++ b/verilog/rtl/lib/registers.v
@@ -0,0 +1,277 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Tubo 8051 cores common library Module ////
+//// ////
+//// This file is part of the Turbo 8051 cores project ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//// Description ////
+//// Turbo 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Mar 2, 2011 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+/*********************************************************************
+** module: bit register
+
+** description: infers a register, make it modular
+ ***********************************************************************/
+module bit_register (
+ //inputs
+ we,
+ clk,
+ reset_n,
+ data_in,
+
+ //outputs
+ data_out
+ );
+
+//---------------------------------
+// Reset Default value
+//---------------------------------
+parameter RESET_DEFAULT = 1'h0;
+
+ input we;
+ input clk;
+ input reset_n;
+ input data_in;
+ output data_out;
+
+ reg data_out;
+
+ //infer the register
+ always @(posedge clk or negedge reset_n)
+ begin
+ if (!reset_n)
+ data_out <= RESET_DEFAULT;
+ else if (we)
+ data_out <= data_in;
+ end // always @ (posedge clk or negedge reset_n)
+endmodule // register
+
+
+/*********************************************************************
+** module: req register.
+
+** description: This register is set by cpu writting 1 and reset by
+ harward req = 1
+
+ Note: When there is a clash between cpu and hardware, cpu is given higher
+ priority
+
+ ***********************************************************************/
+module req_register (
+ //inputs
+ clk,
+ reset_n,
+ cpu_we,
+ cpu_req,
+ hware_ack,
+
+ //outputs
+ data_out
+ );
+
+//---------------------------------
+// Reset Default value
+//---------------------------------
+parameter RESET_DEFAULT = 1'h0;
+
+ input clk ;
+ input reset_n ;
+ input cpu_we ; // cpu write enable
+ input cpu_req ; // CPU Request
+ input hware_ack; // Hardware Ack
+ output data_out ;
+
+ reg data_out;
+
+ //infer the register
+ always @(posedge clk or negedge reset_n)
+ begin
+ if (!reset_n)
+ data_out <= RESET_DEFAULT;
+ else if (cpu_we & cpu_req) // Set on CPU Request
+ data_out <= 1'b1;
+ else if (hware_ack) // Reset the flag on Hardware ack
+ data_out <= 1'b0;
+ end // always @ (posedge clk or negedge reset_n)
+endmodule // register
+
+
+/*********************************************************************
+** module: req register.
+
+** description: This register is cleared by cpu writting 1 and set by
+ harward req = 1
+
+ Note: When there is a clash between cpu and hardware,
+ hardware is given higher priority
+
+ ***********************************************************************/
+module stat_register (
+ //inputs
+ clk,
+ reset_n,
+ cpu_we,
+ cpu_ack,
+ hware_req,
+
+ //outputs
+ data_out
+ );
+
+//---------------------------------
+// Reset Default value
+//---------------------------------
+parameter RESET_DEFAULT = 1'h0;
+
+ input clk ;
+ input reset_n ;
+ input cpu_we ; // cpu write enable
+ input cpu_ack ; // CPU Ack
+ input hware_req; // Hardware Req
+ output data_out ;
+
+ reg data_out;
+
+ //infer the register
+ always @(posedge clk or negedge reset_n)
+ begin
+ if (!reset_n)
+ data_out <= RESET_DEFAULT;
+ else if (hware_req) // Set the flag on Hardware Req
+ data_out <= 1'b1;
+ else if (cpu_we & cpu_ack) // Clear on CPU Ack
+ data_out <= 1'b0;
+ end // always @ (posedge clk or negedge reset_n)
+endmodule // register
+
+
+
+
+
+/*********************************************************************
+** copyright message here.
+
+** module: generic register
+
+***********************************************************************/
+module generic_register (
+ //List of Inputs
+ we,
+ data_in,
+ reset_n,
+ clk,
+
+ //List of Outs
+ data_out
+ );
+
+ parameter WD = 1;
+ parameter RESET_DEFAULT = 0;
+ input [WD-1:0] we;
+ input [WD-1:0] data_in;
+ input reset_n;
+ input clk;
+ output [WD-1:0] data_out;
+
+
+generate
+ genvar i;
+ for (i = 0; i < WD; i = i + 1) begin : gen_bit_reg
+ bit_register #(RESET_DEFAULT[i]) u_bit_reg (
+ .we (we[i]),
+ .clk (clk),
+ .reset_n (reset_n),
+ .data_in (data_in[i]),
+ .data_out (data_out[i])
+ );
+ end
+endgenerate
+
+
+endmodule
+
+
+/*********************************************************************
+** copyright message here.
+
+** module: generic register
+
+***********************************************************************/
+module generic_intr_stat_reg (
+ //inputs
+ clk,
+ reset_n,
+ reg_we,
+ reg_din,
+ hware_req,
+
+ //outputs
+ data_out
+ );
+
+ parameter WD = 1;
+ parameter RESET_DEFAULT = 0;
+ input [WD-1:0] reg_we;
+ input [WD-1:0] reg_din;
+ input [WD-1:0] hware_req;
+ input reset_n;
+ input clk;
+ output [WD-1:0] data_out;
+
+
+generate
+ genvar i;
+ for (i = 0; i < WD; i = i + 1) begin : gen_bit_reg
+ stat_register #(RESET_DEFAULT[i]) u_bit_reg (
+ //inputs
+ . clk (clk ),
+ . reset_n (reset_n ),
+ . cpu_we (reg_we[i] ),
+ . cpu_ack (reg_din[i] ),
+ . hware_req (hware_req[i] ),
+
+ //outputs
+ . data_out (data_out[i] )
+ );
+
+ end
+endgenerate
+
+
+endmodule
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/LICENSE b/verilog/rtl/syntacore/scr1/sim/tests/common/LICENSE
new file mode 100644
index 0000000..48fe522
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2012-2015, The Regents of the University of California (Regents).
+All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of the Regents nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/common.mk b/verilog/rtl/syntacore/scr1/sim/tests/common/common.mk
new file mode 100644
index 0000000..9f78692
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/common.mk
@@ -0,0 +1,44 @@
+ADD_ASM_MACRO ?= -D__ASSEMBLY__=1
+
+FLAGS = -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las $(ADD_FLAGS)
+FLAGS_STR = "$(FLAGS)"
+
+CFLAGS_COMMON = -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=$(TCM)
+CFLAGS_ARCH = -Wa,-march=rv32$(ARCH) -march=rv32$(ARCH) -mabi=$(ABI)
+
+CFLAGS := $(FLAGS) $(EXT_CFLAGS) \
+$(CFLAGS_COMMON) \
+$(CFLAGS_ARCH) \
+-DFLAGS_STR=\"$(FLAGS_STR)\" \
+$(ADD_CFLAGS)
+
+LDFLAGS ?= -nostartfiles -nostdlib -lc -lgcc -march=rv32$(ARCH) -mabi=$(ABI)
+
+ifeq (,$(findstring 0,$(TCM)))
+ld_script ?= $(inc_dir)/link_tcm.ld
+asm_src ?= crt_tcm.S
+else
+ld_script ?= $(inc_dir)/link.ld
+asm_src ?= crt.S
+endif
+
+VPATH += $(src_dir) $(inc_dir) $(ADD_VPATH)
+incs += -I$(src_dir) -I$(inc_dir) $(ADD_incs)
+
+c_objs := $(addprefix $(bld_dir)/,$(patsubst %.c, %.o, $(c_src)))
+asm_objs := $(addprefix $(bld_dir)/,$(patsubst %.S, %.o, $(asm_src)))
+
+$(bld_dir)/%.o: %.S
+ $(RISCV_GCC) $(CFLAGS) $(ADD_ASM_MACRO) -c $(incs) $< -o $@
+
+$(bld_dir)/%.o: %.c
+ $(RISCV_GCC) $(CFLAGS) -c $(incs) $< -o $@
+
+$(bld_dir)/%.elf: $(ld_script) $(c_objs) $(asm_objs)
+ $(RISCV_GCC) -o $@ -T $^ $(LDFLAGS)
+
+$(bld_dir)/%.hex: $(bld_dir)/%.elf
+ $(RISCV_OBJCOPY) $^ $@
+
+$(bld_dir)/%.dump: $(bld_dir)/%.elf
+ $(RISCV_OBJDUMP) $^ > $@
\ No newline at end of file
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/crt.S b/verilog/rtl/syntacore/scr1/sim/tests/common/crt.S
new file mode 100644
index 0000000..7887a29
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/crt.S
@@ -0,0 +1,146 @@
+/// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details
+/// @file <crt.S>
+///
+
+#include "riscv_csr_encoding.h"
+#include "sc_test.h"
+
+# define LREG lw
+# define SREG sw
+# define REGBYTES 4
+
+ .globl _start
+ .globl main
+ .globl trap_entry
+ .globl handle_trap
+ .globl sc_exit
+ .weak trap_entry, handle_trap
+
+ .text
+ .org (64*3)
+ .balign 64
+machine_trap_entry:
+ j trap_entry
+
+ .balign 64
+
+_start:
+#ifndef __RVE_EXT
+ zero_int_regs 1, 31
+#else
+ zero_int_regs 1, 15
+#endif
+ # Global pointer init
+ .option push
+ .option norelax
+ la gp, __global_pointer$
+ .option pop
+ # clear bss
+ la a1, __BSS_START__
+ la a2, __BSS_END__
+ j 4f
+3: sw zero, 0(a1)
+ add a1, a1, 4
+4: bne a1, a2, 3b
+ la sp, __C_STACK_TOP__
+
+ // Timer init
+ li t0, mtime_ctrl
+ li t1, (1 << SCR1_MTIME_CTRL_EN) // enable, use internal clock
+ sw t1, (t0)
+ li t0, mtime_div
+ li t1, (100-1) // divide by 100
+ sw t1, (t0)
+ li t0, mtimecmp
+ li t1, -1
+ sw t1, (t0) // max value for mtimecmp
+ sw t1, 4(t0)
+
+ li a0, 0
+ li a1, 0
+ jal main
+ j sc_exit
+
+trap_entry:
+ addi sp, sp, -272
+
+ SREG x1, 1*REGBYTES(sp)
+ SREG x2, 2*REGBYTES(sp)
+ SREG x3, 3*REGBYTES(sp)
+ SREG x4, 4*REGBYTES(sp)
+ SREG x5, 5*REGBYTES(sp)
+ SREG x6, 6*REGBYTES(sp)
+ SREG x7, 7*REGBYTES(sp)
+ SREG x8, 8*REGBYTES(sp)
+ SREG x9, 9*REGBYTES(sp)
+ SREG x10, 10*REGBYTES(sp)
+ SREG x11, 11*REGBYTES(sp)
+ SREG x12, 12*REGBYTES(sp)
+ SREG x13, 13*REGBYTES(sp)
+ SREG x14, 14*REGBYTES(sp)
+ SREG x15, 15*REGBYTES(sp)
+#ifndef __RVE_EXT
+ SREG x16, 16*REGBYTES(sp)
+ SREG x17, 17*REGBYTES(sp)
+ SREG x18, 18*REGBYTES(sp)
+ SREG x19, 19*REGBYTES(sp)
+ SREG x20, 20*REGBYTES(sp)
+ SREG x21, 21*REGBYTES(sp)
+ SREG x22, 22*REGBYTES(sp)
+ SREG x23, 23*REGBYTES(sp)
+ SREG x24, 24*REGBYTES(sp)
+ SREG x25, 25*REGBYTES(sp)
+ SREG x26, 26*REGBYTES(sp)
+ SREG x27, 27*REGBYTES(sp)
+ SREG x28, 28*REGBYTES(sp)
+ SREG x29, 29*REGBYTES(sp)
+ SREG x30, 30*REGBYTES(sp)
+ SREG x31, 31*REGBYTES(sp)
+#endif // __RVE_EXT
+
+ csrr a0, mcause
+ csrr a1, mepc
+ mv a2, sp
+ jal handle_trap
+
+ LREG x1, 1*REGBYTES(sp)
+ LREG x2, 2*REGBYTES(sp)
+ LREG x3, 3*REGBYTES(sp)
+ LREG x4, 4*REGBYTES(sp)
+ LREG x5, 5*REGBYTES(sp)
+ LREG x6, 6*REGBYTES(sp)
+ LREG x7, 7*REGBYTES(sp)
+ LREG x8, 8*REGBYTES(sp)
+ LREG x9, 9*REGBYTES(sp)
+ LREG x10, 10*REGBYTES(sp)
+ LREG x11, 11*REGBYTES(sp)
+ LREG x12, 12*REGBYTES(sp)
+ LREG x13, 13*REGBYTES(sp)
+ LREG x14, 14*REGBYTES(sp)
+ LREG x15, 15*REGBYTES(sp)
+#ifndef __RVE_EXT
+ LREG x16, 16*REGBYTES(sp)
+ LREG x17, 17*REGBYTES(sp)
+ LREG x18, 18*REGBYTES(sp)
+ LREG x19, 19*REGBYTES(sp)
+ LREG x20, 20*REGBYTES(sp)
+ LREG x21, 21*REGBYTES(sp)
+ LREG x22, 22*REGBYTES(sp)
+ LREG x23, 23*REGBYTES(sp)
+ LREG x24, 24*REGBYTES(sp)
+ LREG x25, 25*REGBYTES(sp)
+ LREG x26, 26*REGBYTES(sp)
+ LREG x27, 27*REGBYTES(sp)
+ LREG x28, 28*REGBYTES(sp)
+ LREG x29, 29*REGBYTES(sp)
+ LREG x30, 30*REGBYTES(sp)
+ LREG x31, 31*REGBYTES(sp)
+#endif // __RVE_EXT
+
+ addi sp, sp, 272
+ mret
+
+handle_trap:
+ j SIM_EXIT
+
+// end of crt.S
\ No newline at end of file
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/crt_tcm.S b/verilog/rtl/syntacore/scr1/sim/tests/common/crt_tcm.S
new file mode 100644
index 0000000..5083438
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/crt_tcm.S
@@ -0,0 +1,157 @@
+/// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details
+/// @file <crt_tcm.S>
+///
+
+#include "riscv_csr_encoding.h"
+#include "reloc.h"
+#include "sc_test.h"
+
+# define LREG lw
+# define SREG sw
+# define REGBYTES 4
+
+ .globl _start
+ .globl main
+ .globl trap_entry
+ .globl handle_trap
+ .globl sc_exit
+ .weak trap_entry, handle_trap
+
+ .section .text.init
+ .org (64*3)
+ .align 6;
+machine_trap_entry:
+ j trap_entry
+
+ .align 6
+_start:
+#ifndef __RVE_EXT
+ zero_int_regs 1, 31
+#else
+ zero_int_regs 1, 15
+#endif
+ # Global pointer init
+ .option push
+ .option norelax
+ la gp, __global_pointer$
+ .option pop
+
+ RELOC_PROC;
+
+ // init tdata
+ mv a1, tp
+ la a2, _tdata_end
+ j 6f
+5: lw a3, 0(a0)
+ sw a3, 0(a1)
+ add a0, a0, 4
+ add a1, a1, 4
+6: bne a0, a2, 5b
+ // clear tbss
+ j 8f
+7: sw zero, 0(a1)
+ add a1, a1, 4
+8: bne a1, a4, 7b
+
+ // Timer init
+ li t0, mtime_ctrl
+ li t1, (1 << SCR1_MTIME_CTRL_EN) // enable, use internal clock
+ sw t1, (t0)
+ li t0, mtime_div
+ li t1, (100-1) // divide by 100
+ sw t1, (t0)
+ li t0, mtimecmp
+ li t1, -1
+ sw t1, (t0) // max value for mtimecmp
+ sw t1, 4(t0)
+
+ li a0, 0
+ li a1, 0
+9: auipc t0, %pcrel_hi(main)
+ jalr t0, %pcrel_lo(9b)
+ la t0, sc_exit
+ //j sc_exit
+
+trap_entry:
+ addi sp, sp, -272
+
+ SREG x1, 1*REGBYTES(sp)
+ SREG x2, 2*REGBYTES(sp)
+ SREG x3, 3*REGBYTES(sp)
+ SREG x4, 4*REGBYTES(sp)
+ SREG x5, 5*REGBYTES(sp)
+ SREG x6, 6*REGBYTES(sp)
+ SREG x7, 7*REGBYTES(sp)
+ SREG x8, 8*REGBYTES(sp)
+ SREG x9, 9*REGBYTES(sp)
+ SREG x10, 10*REGBYTES(sp)
+ SREG x11, 11*REGBYTES(sp)
+ SREG x12, 12*REGBYTES(sp)
+ SREG x13, 13*REGBYTES(sp)
+ SREG x14, 14*REGBYTES(sp)
+ SREG x15, 15*REGBYTES(sp)
+#ifndef __RVE_EXT
+ SREG x16, 16*REGBYTES(sp)
+ SREG x17, 17*REGBYTES(sp)
+ SREG x18, 18*REGBYTES(sp)
+ SREG x19, 19*REGBYTES(sp)
+ SREG x20, 20*REGBYTES(sp)
+ SREG x21, 21*REGBYTES(sp)
+ SREG x22, 22*REGBYTES(sp)
+ SREG x23, 23*REGBYTES(sp)
+ SREG x24, 24*REGBYTES(sp)
+ SREG x25, 25*REGBYTES(sp)
+ SREG x26, 26*REGBYTES(sp)
+ SREG x27, 27*REGBYTES(sp)
+ SREG x28, 28*REGBYTES(sp)
+ SREG x29, 29*REGBYTES(sp)
+ SREG x30, 30*REGBYTES(sp)
+ SREG x31, 31*REGBYTES(sp)
+#endif // __RVE_EXT
+
+ csrr a0, mcause
+ csrr a1, mepc
+ mv a2, sp
+ jal handle_trap
+
+ LREG x1, 1*REGBYTES(sp)
+ LREG x2, 2*REGBYTES(sp)
+ LREG x3, 3*REGBYTES(sp)
+ LREG x4, 4*REGBYTES(sp)
+ LREG x5, 5*REGBYTES(sp)
+ LREG x6, 6*REGBYTES(sp)
+ LREG x7, 7*REGBYTES(sp)
+ LREG x8, 8*REGBYTES(sp)
+ LREG x9, 9*REGBYTES(sp)
+ LREG x10, 10*REGBYTES(sp)
+ LREG x11, 11*REGBYTES(sp)
+ LREG x12, 12*REGBYTES(sp)
+ LREG x13, 13*REGBYTES(sp)
+ LREG x14, 14*REGBYTES(sp)
+ LREG x15, 15*REGBYTES(sp)
+#ifndef __RVE_EXT
+ LREG x16, 16*REGBYTES(sp)
+ LREG x17, 17*REGBYTES(sp)
+ LREG x18, 18*REGBYTES(sp)
+ LREG x19, 19*REGBYTES(sp)
+ LREG x20, 20*REGBYTES(sp)
+ LREG x21, 21*REGBYTES(sp)
+ LREG x22, 22*REGBYTES(sp)
+ LREG x23, 23*REGBYTES(sp)
+ LREG x24, 24*REGBYTES(sp)
+ LREG x25, 25*REGBYTES(sp)
+ LREG x26, 26*REGBYTES(sp)
+ LREG x27, 27*REGBYTES(sp)
+ LREG x28, 28*REGBYTES(sp)
+ LREG x29, 29*REGBYTES(sp)
+ LREG x30, 30*REGBYTES(sp)
+ LREG x31, 31*REGBYTES(sp)
+#endif // __RVE_EXT
+
+ addi sp, sp, 272
+ mret
+
+handle_trap:
+ j SIM_EXIT
+
+// end of crt.S
\ No newline at end of file
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/csr.h b/verilog/rtl/syntacore/scr1/sim/tests/common/csr.h
new file mode 100644
index 0000000..72c60fc
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/csr.h
@@ -0,0 +1,113 @@
+/// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details
+/// @file <csr.h>
+/// Architecture specific CSR's defs and inlines
+
+#ifndef SCR_CSR_H
+#define SCR_CSR_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#define __xstringify(s) __stringify(s)
+#define __stringify(s) #s
+
+#ifdef read_csr
+#undef read_csr
+#endif
+
+#ifdef write_csr
+#undef write_csr
+#endif
+
+#ifdef swap_csr
+#undef swap_csr
+#endif
+
+#ifdef set_csr
+#undef set_csr
+#endif
+
+#ifdef clear_csr
+#undef clear_csr
+#endif
+
+#ifdef rdtime
+#undef rdtime
+#endif
+
+#ifdef rdcycle
+#undef rdcycle
+#endif
+
+#ifdef rdinstret
+#undef rdinstret
+#endif
+
+#define read_csr(reg) \
+ ({ \
+ unsigned long __tmp; \
+ asm volatile ("csrr %0, " __xstringify(reg) : "=r"(__tmp)); \
+ __tmp; \
+ })
+
+#define write_csr(reg, val) \
+ do { \
+ if (__builtin_constant_p(val) && (val) == 0) \
+ asm volatile ("csrw " __xstringify(reg) ", zero" ::); \
+ else if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
+ asm volatile ("csrw " __xstringify(reg) ", %0" :: "i"(val)); \
+ else \
+ asm volatile ("csrw " __xstringify(reg) ", %0" :: "r"(val)); \
+ } while (0)
+
+#define swap_csr(reg, val) \
+ ({ \
+ unsigned long __tmp; \
+ if (__builtin_constant_p(val) && (val) == 0) \
+ asm volatile ("csrrw %0, " __xstringify(reg) ", zero" : "=r"(__tmp) :); \
+ else if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
+ asm volatile ("csrrw %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(val)); \
+ else \
+ asm volatile ("csrrw %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(val)); \
+ __tmp; \
+ })
+
+#define set_csr(reg, bit) \
+ ({ \
+ unsigned long __tmp; \
+ if (__builtin_constant_p(bit) && (bit) < 32) \
+ asm volatile ("csrrs %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(bit)); \
+ else \
+ asm volatile ("csrrs %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(bit)); \
+ __tmp; \
+ })
+
+#define clear_csr(reg, bit) \
+ ({ \
+ unsigned long __tmp; \
+ if (__builtin_constant_p(bit) && (bit) < 32) \
+ asm volatile ("csrrc %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(bit)); \
+ else \
+ asm volatile ("csrrc %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(bit)); \
+ __tmp; \
+ })
+
+#define rdtime() read_csr(time)
+#define rdcycle() read_csr(cycle)
+#define rdinstret() read_csr(instret)
+
+static inline unsigned long __attribute__((const)) cpuid()
+{
+ unsigned long res;
+ asm ("csrr %0, mcpuid" : "=r"(res));
+ return res;
+}
+
+static inline unsigned long __attribute__((const)) impid()
+{
+ unsigned long res;
+ asm ("csrr %0, mimpid" : "=r"(res));
+ return res;
+}
+
+#endif // SCR_CSR_H
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/link.ld b/verilog/rtl/syntacore/scr1/sim/tests/common/link.ld
new file mode 100644
index 0000000..050c58d
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/link.ld
@@ -0,0 +1,99 @@
+/*
+* Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details
+* @file <link.ld>
+* @brief bare metal tests' linker script
+*/
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+MEMORY {
+ RAM (rwx) : ORIGIN = 0x0, LENGTH = 64K
+}
+
+STACK_SIZE = 1024;
+
+CL_SIZE = 32;
+
+SECTIONS {
+
+ /* code segment */
+ .text.init 0 : {
+ FILL(0);
+ . = 0x100 - 12;
+ SIM_EXIT = .;
+ LONG(0x13);
+ SIM_STOP = .;
+ LONG(0x6F);
+ LONG(-1);
+ . = 0x100;
+ PROVIDE(__TEXT_START__ = .);
+ *(.text.init)
+ } >RAM
+
+ .text : {
+ *crt.o(.text .text.*)
+ *(.text .text.*)
+ *(sc_test_section)
+ . = ALIGN(CL_SIZE);
+ PROVIDE(__TEXT_END__ = .);
+ } >RAM
+
+ /* data segment */
+ .data : {
+ *(.data .data.*)
+ . = ALIGN(CL_SIZE);
+ } >RAM
+
+ .sdata : {
+ __global_pointer$ = . + 0x800;
+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(CL_SIZE);
+ } >RAM
+
+ /* thread-local data segment */
+ .tdata : {
+ PROVIDE(_tls_data = .);
+ PROVIDE(_tdata_begin = .);
+ *(.tdata .tdata.*)
+ PROVIDE(_tdata_end = .);
+ . = ALIGN(CL_SIZE);
+ } >RAM
+
+ .tbss : {
+ PROVIDE(__BSS_START__ = .);
+ *(.tbss .tbss.*)
+ . = ALIGN(CL_SIZE);
+ PROVIDE(_tbss_end = .);
+ } >RAM
+
+ /* bss segment */
+ .sbss : {
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ } >RAM
+
+ .bss : {
+ *(.bss .bss.*)
+ . = ALIGN(CL_SIZE);
+ PROVIDE(__BSS_END__ = .);
+ } >RAM
+
+ _end = .;
+ PROVIDE(__end = .);
+
+ /* End of uninitalized data segement */
+
+ .stack ORIGIN(RAM) + LENGTH(RAM) - STACK_SIZE : {
+ FILL(0);
+ PROVIDE(__STACK_START__ = .);
+ . += STACK_SIZE;
+ PROVIDE(__C_STACK_TOP__ = .);
+ PROVIDE(__STACK_END__ = .);
+ } >RAM
+
+ /DISCARD/ : {
+ *(.eh_frame .eh_frame.*)
+ }
+}
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/link_tcm.ld b/verilog/rtl/syntacore/scr1/sim/tests/common/link_tcm.ld
new file mode 100644
index 0000000..7b37506
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/link_tcm.ld
@@ -0,0 +1,114 @@
+/*
+* Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details
+* @file <link.ld>
+* @brief bare metal tests' linker script
+*/
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+MEMORY {
+ RAM (rwx) : ORIGIN = 0x0, LENGTH = 64K
+ TCM (rwx) : ORIGIN = 0x00480000, LENGTH = 64K
+}
+
+STACK_SIZE = 1024;
+
+CL_SIZE = 32;
+
+SECTIONS {
+
+ /* code segment */
+ .text.init ORIGIN(RAM) : {
+ FILL(0);
+ . = 0x100 - 12;
+ SIM_EXIT = .;
+ LONG(0x13);
+ SIM_STOP = .;
+ LONG(0x6F);
+ LONG(-1);
+ . = 0x100;
+ *crt_tcm.o(.text .text.*)
+ *(.text.init)
+ . = ALIGN(CL_SIZE);
+ } >RAM
+
+ __reloc_start = .;
+
+ .text : {
+ PROVIDE(__TEXT_START__ = .);
+ *(.text .text.*)
+ *(sc_test_section)
+ . = ALIGN(CL_SIZE);
+ PROVIDE(__TEXT_END__ = .);
+ } >TCM AT>RAM
+
+ .rodata ALIGN(CL_SIZE) : {
+ __global_pointer$ = . + 0x800;
+ *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*)
+ . = ALIGN(CL_SIZE);
+ LONG(0x13);
+ . = ALIGN(CL_SIZE);
+ } >TCM AT>RAM
+
+
+ /* data segment */
+ .data ALIGN(CL_SIZE) : {
+ PROVIDE(__DATA_START__ = .);
+ *(.data .data.*)
+ . = ALIGN(CL_SIZE);
+ } >TCM AT>RAM
+
+
+ .sdata ALIGN(CL_SIZE) : {
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ . = ALIGN(CL_SIZE);
+ PROVIDE(__DATA_END__ = .);
+ } >TCM AT>RAM
+
+ /* thread-local data segment */
+ .tdata ALIGN(CL_SIZE) : {
+ PROVIDE(_tls_data = .);
+ PROVIDE(_tdata_begin = .);
+ *(.tdata .tdata.*)
+ PROVIDE(_tdata_end = .);
+ . = ALIGN(CL_SIZE);
+ } >TCM AT>RAM
+
+ .tbss ALIGN(CL_SIZE) : {
+ PROVIDE(_tbss_begin = .);
+ *(.tbss .tbss.*)
+ . = ALIGN(CL_SIZE);
+ PROVIDE(_tbss_end = .);
+ } >TCM AT>RAM
+
+ /* bss segment */
+ .sbss ALIGN(CL_SIZE) : {
+ PROVIDE(__BSS_START__ = .);
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ . = ALIGN(CL_SIZE);
+ } >TCM AT>RAM
+
+ .bss ALIGN(CL_SIZE) : {
+ *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON)
+ . = ALIGN(CL_SIZE);
+ PROVIDE(__BSS_END__ = .);
+ } >TCM AT>RAM
+
+ _end = .;
+ PROVIDE(__end = .);
+
+ /* End of uninitalized data segement */
+
+ .stack ORIGIN(TCM) + LENGTH(TCM) - STACK_SIZE : {
+ PROVIDE(__STACK_START__ = .);
+ . += STACK_SIZE;
+ PROVIDE(__C_STACK_TOP__ = .);
+ PROVIDE(__STACK_END__ = .);
+ } >TCM
+
+ /DISCARD/ : {
+ *(.eh_frame .eh_frame.*)
+ }
+}
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/reloc.h b/verilog/rtl/syntacore/scr1/sim/tests/common/reloc.h
new file mode 100644
index 0000000..275d7a8
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/reloc.h
@@ -0,0 +1,37 @@
+#ifndef RELOC_H
+#define RELOC_H
+
+#if (TCM == 1)
+#define RELOC_PROC \
+ la a0, __reloc_start; \
+ la a1, __TEXT_START__; \
+ la a2, __DATA_END__; \
+ beq a0, a1, 21f; \
+ j 2f; \
+1: lw a3, 0(a0); \
+ sw a3, 0(a1); \
+ add a0, a0, 4; \
+ add a1, a1, 4; \
+2: bne a1, a2, 1b; \
+ /* clear bss */ \
+ la a2, __BSS_START__; \
+21: la a1, __BSS_END__; \
+ j 4f; \
+3: sw zero, 0(a2); \
+ add a2, a2, 4; \
+4: bne a1, a2, 3b; \
+ /* init stack */ \
+ la sp, __C_STACK_TOP__; \
+ /* init hart0 TLS */ \
+ la a0, _tdata_begin; \
+ la a2, _tbss_end; \
+ sub a1, a2, a0; \
+ la a4, __STACK_START__; \
+ sub tp, a4, a1;
+#else // #if TCM
+
+#define RELOC_PROC
+
+#endif // #else #if TCM
+
+#endif //
\ No newline at end of file
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/riscv_csr_encoding.h b/verilog/rtl/syntacore/scr1/sim/tests/common/riscv_csr_encoding.h
new file mode 100644
index 0000000..a1c9f64
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/riscv_csr_encoding.h
@@ -0,0 +1,1473 @@
+// See LICENSE for license details.
+
+#ifndef RISCV_CSR_ENCODING_H
+#define RISCV_CSR_ENCODING_H
+
+#define MSTATUS_UIE 0x00000001
+#define MSTATUS_SIE 0x00000002
+#define MSTATUS_HIE 0x00000004
+#define MSTATUS_MIE 0x00000008
+#define MSTATUS_UPIE 0x00000010
+#define MSTATUS_SPIE 0x00000020
+#define MSTATUS_HPIE 0x00000040
+#define MSTATUS_MPIE 0x00000080
+#define MSTATUS_SPP 0x00000100
+#define MSTATUS_HPP 0x00000600
+#define MSTATUS_MPP 0x00001800
+#define MSTATUS_FS 0x00006000
+#define MSTATUS_XS 0x00018000
+#define MSTATUS_MPRV 0x00020000
+#define MSTATUS_SUM 0x00040000
+#define MSTATUS_MXR 0x00080000
+#define MSTATUS_TVM 0x00100000
+#define MSTATUS_TW 0x00200000
+#define MSTATUS_TSR 0x00400000
+#define MSTATUS32_SD 0x80000000
+#define MSTATUS_UXL 0x0000000300000000
+#define MSTATUS_SXL 0x0000000C00000000
+#define MSTATUS64_SD 0x8000000000000000
+
+#define SSTATUS_UIE 0x00000001
+#define SSTATUS_SIE 0x00000002
+#define SSTATUS_UPIE 0x00000010
+#define SSTATUS_SPIE 0x00000020
+#define SSTATUS_SPP 0x00000100
+#define SSTATUS_FS 0x00006000
+#define SSTATUS_XS 0x00018000
+#define SSTATUS_SUM 0x00040000
+#define SSTATUS_MXR 0x00080000
+#define SSTATUS32_SD 0x80000000
+#define SSTATUS_UXL 0x0000000300000000
+#define SSTATUS64_SD 0x8000000000000000
+
+#define DCSR_XDEBUGVER (3U<<30)
+#define DCSR_NDRESET (1<<29)
+#define DCSR_FULLRESET (1<<28)
+#define DCSR_EBREAKM (1<<15)
+#define DCSR_EBREAKH (1<<14)
+#define DCSR_EBREAKS (1<<13)
+#define DCSR_EBREAKU (1<<12)
+#define DCSR_STOPCYCLE (1<<10)
+#define DCSR_STOPTIME (1<<9)
+#define DCSR_CAUSE (7<<6)
+#define DCSR_DEBUGINT (1<<5)
+#define DCSR_HALT (1<<3)
+#define DCSR_STEP (1<<2)
+#define DCSR_PRV (3<<0)
+
+#define DCSR_CAUSE_NONE 0
+#define DCSR_CAUSE_SWBP 1
+#define DCSR_CAUSE_HWBP 2
+#define DCSR_CAUSE_DEBUGINT 3
+#define DCSR_CAUSE_STEP 4
+#define DCSR_CAUSE_HALT 5
+
+#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4))
+#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5))
+#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11))
+
+#define MCONTROL_SELECT (1<<19)
+#define MCONTROL_TIMING (1<<18)
+#define MCONTROL_ACTION (0x3f<<12)
+#define MCONTROL_CHAIN (1<<11)
+#define MCONTROL_MATCH (0xf<<7)
+#define MCONTROL_M (1<<6)
+#define MCONTROL_H (1<<5)
+#define MCONTROL_S (1<<4)
+#define MCONTROL_U (1<<3)
+#define MCONTROL_EXECUTE (1<<2)
+#define MCONTROL_STORE (1<<1)
+#define MCONTROL_LOAD (1<<0)
+
+#define MCONTROL_TYPE_NONE 0
+#define MCONTROL_TYPE_MATCH 2
+
+#define MCONTROL_ACTION_DEBUG_EXCEPTION 0
+#define MCONTROL_ACTION_DEBUG_MODE 1
+#define MCONTROL_ACTION_TRACE_START 2
+#define MCONTROL_ACTION_TRACE_STOP 3
+#define MCONTROL_ACTION_TRACE_EMIT 4
+
+#define MCONTROL_MATCH_EQUAL 0
+#define MCONTROL_MATCH_NAPOT 1
+#define MCONTROL_MATCH_GE 2
+#define MCONTROL_MATCH_LT 3
+#define MCONTROL_MATCH_MASK_LOW 4
+#define MCONTROL_MATCH_MASK_HIGH 5
+
+#define MIP_SSIP (1 << IRQ_S_SOFT)
+#define MIP_HSIP (1 << IRQ_H_SOFT)
+#define MIP_MSIP (1 << IRQ_M_SOFT)
+#define MIP_STIP (1 << IRQ_S_TIMER)
+#define MIP_HTIP (1 << IRQ_H_TIMER)
+#define MIP_MTIP (1 << IRQ_M_TIMER)
+#define MIP_SEIP (1 << IRQ_S_EXT)
+#define MIP_HEIP (1 << IRQ_H_EXT)
+#define MIP_MEIP (1 << IRQ_M_EXT)
+
+#define SIP_SSIP MIP_SSIP
+#define SIP_STIP MIP_STIP
+
+#define PRV_U 0
+#define PRV_S 1
+#define PRV_H 2
+#define PRV_M 3
+
+#define SPTBR32_MODE 0x80000000
+#define SPTBR32_ASID 0x7FC00000
+#define SPTBR32_PPN 0x003FFFFF
+#define SPTBR64_MODE 0xF000000000000000
+#define SPTBR64_ASID 0x0FFFF00000000000
+#define SPTBR64_PPN 0x00000FFFFFFFFFFF
+
+#define SPTBR_MODE_OFF 0
+#define SPTBR_MODE_SV32 1
+#define SPTBR_MODE_SV39 8
+#define SPTBR_MODE_SV48 9
+#define SPTBR_MODE_SV57 10
+#define SPTBR_MODE_SV64 11
+
+#define PMP_R 0x01
+#define PMP_W 0x02
+#define PMP_X 0x04
+#define PMP_A 0x18
+#define PMP_L 0x80
+#define PMP_SHIFT 2
+
+#define PMP_TOR 0x08
+#define PMP_NA4 0x10
+#define PMP_NAPOT 0x18
+
+#define IRQ_S_SOFT 1
+#define IRQ_H_SOFT 2
+#define IRQ_M_SOFT 3
+#define IRQ_S_TIMER 5
+#define IRQ_H_TIMER 6
+#define IRQ_M_TIMER 7
+#define IRQ_S_EXT 9
+#define IRQ_H_EXT 10
+#define IRQ_M_EXT 11
+#define IRQ_COP 12
+#define IRQ_HOST 13
+
+#define DEFAULT_RSTVEC 0x00001000
+#define CLINT_BASE 0x02000000
+#define CLINT_SIZE 0x000c0000
+#define EXT_IO_BASE 0x40000000
+#define DRAM_BASE 0x80000000
+
+// page table entry (PTE) fields
+#define PTE_V 0x001 // Valid
+#define PTE_R 0x002 // Read
+#define PTE_W 0x004 // Write
+#define PTE_X 0x008 // Execute
+#define PTE_U 0x010 // User
+#define PTE_G 0x020 // Global
+#define PTE_A 0x040 // Accessed
+#define PTE_D 0x080 // Dirty
+#define PTE_SOFT 0x300 // Reserved for Software
+
+#define PTE_PPN_SHIFT 10
+
+#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
+
+#ifdef __riscv
+
+#if __riscv_xlen == 64
+# define MSTATUS_SD MSTATUS64_SD
+# define SSTATUS_SD SSTATUS64_SD
+# define RISCV_PGLEVEL_BITS 9
+# define SPTBR_MODE SPTBR64_MODE
+#else
+# define MSTATUS_SD MSTATUS32_SD
+# define SSTATUS_SD SSTATUS32_SD
+# define RISCV_PGLEVEL_BITS 10
+# define SPTBR_MODE SPTBR32_MODE
+#endif
+#define RISCV_PGSHIFT 12
+#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
+
+#ifndef __ASSEMBLER__
+
+#ifdef __GNUC__
+
+#define read_csr(reg) ({ unsigned long __tmp; \
+ asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
+ __tmp; })
+
+#define write_csr(reg, val) ({ \
+ asm volatile ("csrw " #reg ", %0" :: "rK"(val)); })
+
+#define swap_csr(reg, val) ({ unsigned long __tmp; \
+ asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "rK"(val)); \
+ __tmp; })
+
+#define set_csr(reg, bit) ({ unsigned long __tmp; \
+ asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
+ __tmp; })
+
+#define clear_csr(reg, bit) ({ unsigned long __tmp; \
+ asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
+ __tmp; })
+
+#define rdtime() read_csr(time)
+#define rdcycle() read_csr(cycle)
+#define rdinstret() read_csr(instret)
+
+#endif
+
+#endif
+
+#endif
+
+#endif
+/* Automatically generated by parse-opcodes. */
+#ifndef RISCV_ENCODING_H
+#define RISCV_ENCODING_H
+#define MATCH_BEQ 0x63
+#define MASK_BEQ 0x707f
+#define MATCH_BNE 0x1063
+#define MASK_BNE 0x707f
+#define MATCH_BLT 0x4063
+#define MASK_BLT 0x707f
+#define MATCH_BGE 0x5063
+#define MASK_BGE 0x707f
+#define MATCH_BLTU 0x6063
+#define MASK_BLTU 0x707f
+#define MATCH_BGEU 0x7063
+#define MASK_BGEU 0x707f
+#define MATCH_JALR 0x67
+#define MASK_JALR 0x707f
+#define MATCH_JAL 0x6f
+#define MASK_JAL 0x7f
+#define MATCH_LUI 0x37
+#define MASK_LUI 0x7f
+#define MATCH_AUIPC 0x17
+#define MASK_AUIPC 0x7f
+#define MATCH_ADDI 0x13
+#define MASK_ADDI 0x707f
+#define MATCH_SLLI 0x1013
+#define MASK_SLLI 0xfc00707f
+#define MATCH_SLTI 0x2013
+#define MASK_SLTI 0x707f
+#define MATCH_SLTIU 0x3013
+#define MASK_SLTIU 0x707f
+#define MATCH_XORI 0x4013
+#define MASK_XORI 0x707f
+#define MATCH_SRLI 0x5013
+#define MASK_SRLI 0xfc00707f
+#define MATCH_SRAI 0x40005013
+#define MASK_SRAI 0xfc00707f
+#define MATCH_ORI 0x6013
+#define MASK_ORI 0x707f
+#define MATCH_ANDI 0x7013
+#define MASK_ANDI 0x707f
+#define MATCH_ADD 0x33
+#define MASK_ADD 0xfe00707f
+#define MATCH_SUB 0x40000033
+#define MASK_SUB 0xfe00707f
+#define MATCH_SLL 0x1033
+#define MASK_SLL 0xfe00707f
+#define MATCH_SLT 0x2033
+#define MASK_SLT 0xfe00707f
+#define MATCH_SLTU 0x3033
+#define MASK_SLTU 0xfe00707f
+#define MATCH_XOR 0x4033
+#define MASK_XOR 0xfe00707f
+#define MATCH_SRL 0x5033
+#define MASK_SRL 0xfe00707f
+#define MATCH_SRA 0x40005033
+#define MASK_SRA 0xfe00707f
+#define MATCH_OR 0x6033
+#define MASK_OR 0xfe00707f
+#define MATCH_AND 0x7033
+#define MASK_AND 0xfe00707f
+#define MATCH_ADDIW 0x1b
+#define MASK_ADDIW 0x707f
+#define MATCH_SLLIW 0x101b
+#define MASK_SLLIW 0xfe00707f
+#define MATCH_SRLIW 0x501b
+#define MASK_SRLIW 0xfe00707f
+#define MATCH_SRAIW 0x4000501b
+#define MASK_SRAIW 0xfe00707f
+#define MATCH_ADDW 0x3b
+#define MASK_ADDW 0xfe00707f
+#define MATCH_SUBW 0x4000003b
+#define MASK_SUBW 0xfe00707f
+#define MATCH_SLLW 0x103b
+#define MASK_SLLW 0xfe00707f
+#define MATCH_SRLW 0x503b
+#define MASK_SRLW 0xfe00707f
+#define MATCH_SRAW 0x4000503b
+#define MASK_SRAW 0xfe00707f
+#define MATCH_LB 0x3
+#define MASK_LB 0x707f
+#define MATCH_LH 0x1003
+#define MASK_LH 0x707f
+#define MATCH_LW 0x2003
+#define MASK_LW 0x707f
+#define MATCH_LD 0x3003
+#define MASK_LD 0x707f
+#define MATCH_LBU 0x4003
+#define MASK_LBU 0x707f
+#define MATCH_LHU 0x5003
+#define MASK_LHU 0x707f
+#define MATCH_LWU 0x6003
+#define MASK_LWU 0x707f
+#define MATCH_SB 0x23
+#define MASK_SB 0x707f
+#define MATCH_SH 0x1023
+#define MASK_SH 0x707f
+#define MATCH_SW 0x2023
+#define MASK_SW 0x707f
+#define MATCH_SD 0x3023
+#define MASK_SD 0x707f
+#define MATCH_FENCE 0xf
+#define MASK_FENCE 0x707f
+#define MATCH_FENCE_I 0x100f
+#define MASK_FENCE_I 0x707f
+#define MATCH_MUL 0x2000033
+#define MASK_MUL 0xfe00707f
+#define MATCH_MULH 0x2001033
+#define MASK_MULH 0xfe00707f
+#define MATCH_MULHSU 0x2002033
+#define MASK_MULHSU 0xfe00707f
+#define MATCH_MULHU 0x2003033
+#define MASK_MULHU 0xfe00707f
+#define MATCH_DIV 0x2004033
+#define MASK_DIV 0xfe00707f
+#define MATCH_DIVU 0x2005033
+#define MASK_DIVU 0xfe00707f
+#define MATCH_REM 0x2006033
+#define MASK_REM 0xfe00707f
+#define MATCH_REMU 0x2007033
+#define MASK_REMU 0xfe00707f
+#define MATCH_MULW 0x200003b
+#define MASK_MULW 0xfe00707f
+#define MATCH_DIVW 0x200403b
+#define MASK_DIVW 0xfe00707f
+#define MATCH_DIVUW 0x200503b
+#define MASK_DIVUW 0xfe00707f
+#define MATCH_REMW 0x200603b
+#define MASK_REMW 0xfe00707f
+#define MATCH_REMUW 0x200703b
+#define MASK_REMUW 0xfe00707f
+#define MATCH_AMOADD_W 0x202f
+#define MASK_AMOADD_W 0xf800707f
+#define MATCH_AMOXOR_W 0x2000202f
+#define MASK_AMOXOR_W 0xf800707f
+#define MATCH_AMOOR_W 0x4000202f
+#define MASK_AMOOR_W 0xf800707f
+#define MATCH_AMOAND_W 0x6000202f
+#define MASK_AMOAND_W 0xf800707f
+#define MATCH_AMOMIN_W 0x8000202f
+#define MASK_AMOMIN_W 0xf800707f
+#define MATCH_AMOMAX_W 0xa000202f
+#define MASK_AMOMAX_W 0xf800707f
+#define MATCH_AMOMINU_W 0xc000202f
+#define MASK_AMOMINU_W 0xf800707f
+#define MATCH_AMOMAXU_W 0xe000202f
+#define MASK_AMOMAXU_W 0xf800707f
+#define MATCH_AMOSWAP_W 0x800202f
+#define MASK_AMOSWAP_W 0xf800707f
+#define MATCH_LR_W 0x1000202f
+#define MASK_LR_W 0xf9f0707f
+#define MATCH_SC_W 0x1800202f
+#define MASK_SC_W 0xf800707f
+#define MATCH_AMOADD_D 0x302f
+#define MASK_AMOADD_D 0xf800707f
+#define MATCH_AMOXOR_D 0x2000302f
+#define MASK_AMOXOR_D 0xf800707f
+#define MATCH_AMOOR_D 0x4000302f
+#define MASK_AMOOR_D 0xf800707f
+#define MATCH_AMOAND_D 0x6000302f
+#define MASK_AMOAND_D 0xf800707f
+#define MATCH_AMOMIN_D 0x8000302f
+#define MASK_AMOMIN_D 0xf800707f
+#define MATCH_AMOMAX_D 0xa000302f
+#define MASK_AMOMAX_D 0xf800707f
+#define MATCH_AMOMINU_D 0xc000302f
+#define MASK_AMOMINU_D 0xf800707f
+#define MATCH_AMOMAXU_D 0xe000302f
+#define MASK_AMOMAXU_D 0xf800707f
+#define MATCH_AMOSWAP_D 0x800302f
+#define MASK_AMOSWAP_D 0xf800707f
+#define MATCH_LR_D 0x1000302f
+#define MASK_LR_D 0xf9f0707f
+#define MATCH_SC_D 0x1800302f
+#define MASK_SC_D 0xf800707f
+#define MATCH_ECALL 0x73
+#define MASK_ECALL 0xffffffff
+#define MATCH_EBREAK 0x100073
+#define MASK_EBREAK 0xffffffff
+#define MATCH_URET 0x200073
+#define MASK_URET 0xffffffff
+#define MATCH_SRET 0x10200073
+#define MASK_SRET 0xffffffff
+#define MATCH_MRET 0x30200073
+#define MASK_MRET 0xffffffff
+#define MATCH_DRET 0x7b200073
+#define MASK_DRET 0xffffffff
+#define MATCH_SFENCE_VMA 0x12000073
+#define MASK_SFENCE_VMA 0xfe007fff
+#define MATCH_WFI 0x10500073
+#define MASK_WFI 0xffffffff
+#define MATCH_CSRRW 0x1073
+#define MASK_CSRRW 0x707f
+#define MATCH_CSRRS 0x2073
+#define MASK_CSRRS 0x707f
+#define MATCH_CSRRC 0x3073
+#define MASK_CSRRC 0x707f
+#define MATCH_CSRRWI 0x5073
+#define MASK_CSRRWI 0x707f
+#define MATCH_CSRRSI 0x6073
+#define MASK_CSRRSI 0x707f
+#define MATCH_CSRRCI 0x7073
+#define MASK_CSRRCI 0x707f
+#define MATCH_FADD_S 0x53
+#define MASK_FADD_S 0xfe00007f
+#define MATCH_FSUB_S 0x8000053
+#define MASK_FSUB_S 0xfe00007f
+#define MATCH_FMUL_S 0x10000053
+#define MASK_FMUL_S 0xfe00007f
+#define MATCH_FDIV_S 0x18000053
+#define MASK_FDIV_S 0xfe00007f
+#define MATCH_FSGNJ_S 0x20000053
+#define MASK_FSGNJ_S 0xfe00707f
+#define MATCH_FSGNJN_S 0x20001053
+#define MASK_FSGNJN_S 0xfe00707f
+#define MATCH_FSGNJX_S 0x20002053
+#define MASK_FSGNJX_S 0xfe00707f
+#define MATCH_FMIN_S 0x28000053
+#define MASK_FMIN_S 0xfe00707f
+#define MATCH_FMAX_S 0x28001053
+#define MASK_FMAX_S 0xfe00707f
+#define MATCH_FSQRT_S 0x58000053
+#define MASK_FSQRT_S 0xfff0007f
+#define MATCH_FADD_D 0x2000053
+#define MASK_FADD_D 0xfe00007f
+#define MATCH_FSUB_D 0xa000053
+#define MASK_FSUB_D 0xfe00007f
+#define MATCH_FMUL_D 0x12000053
+#define MASK_FMUL_D 0xfe00007f
+#define MATCH_FDIV_D 0x1a000053
+#define MASK_FDIV_D 0xfe00007f
+#define MATCH_FSGNJ_D 0x22000053
+#define MASK_FSGNJ_D 0xfe00707f
+#define MATCH_FSGNJN_D 0x22001053
+#define MASK_FSGNJN_D 0xfe00707f
+#define MATCH_FSGNJX_D 0x22002053
+#define MASK_FSGNJX_D 0xfe00707f
+#define MATCH_FMIN_D 0x2a000053
+#define MASK_FMIN_D 0xfe00707f
+#define MATCH_FMAX_D 0x2a001053
+#define MASK_FMAX_D 0xfe00707f
+#define MATCH_FCVT_S_D 0x40100053
+#define MASK_FCVT_S_D 0xfff0007f
+#define MATCH_FCVT_D_S 0x42000053
+#define MASK_FCVT_D_S 0xfff0007f
+#define MATCH_FSQRT_D 0x5a000053
+#define MASK_FSQRT_D 0xfff0007f
+#define MATCH_FADD_Q 0x6000053
+#define MASK_FADD_Q 0xfe00007f
+#define MATCH_FSUB_Q 0xe000053
+#define MASK_FSUB_Q 0xfe00007f
+#define MATCH_FMUL_Q 0x16000053
+#define MASK_FMUL_Q 0xfe00007f
+#define MATCH_FDIV_Q 0x1e000053
+#define MASK_FDIV_Q 0xfe00007f
+#define MATCH_FSGNJ_Q 0x26000053
+#define MASK_FSGNJ_Q 0xfe00707f
+#define MATCH_FSGNJN_Q 0x26001053
+#define MASK_FSGNJN_Q 0xfe00707f
+#define MATCH_FSGNJX_Q 0x26002053
+#define MASK_FSGNJX_Q 0xfe00707f
+#define MATCH_FMIN_Q 0x2e000053
+#define MASK_FMIN_Q 0xfe00707f
+#define MATCH_FMAX_Q 0x2e001053
+#define MASK_FMAX_Q 0xfe00707f
+#define MATCH_FCVT_S_Q 0x40300053
+#define MASK_FCVT_S_Q 0xfff0007f
+#define MATCH_FCVT_Q_S 0x46000053
+#define MASK_FCVT_Q_S 0xfff0007f
+#define MATCH_FCVT_D_Q 0x42300053
+#define MASK_FCVT_D_Q 0xfff0007f
+#define MATCH_FCVT_Q_D 0x46100053
+#define MASK_FCVT_Q_D 0xfff0007f
+#define MATCH_FSQRT_Q 0x5e000053
+#define MASK_FSQRT_Q 0xfff0007f
+#define MATCH_FLE_S 0xa0000053
+#define MASK_FLE_S 0xfe00707f
+#define MATCH_FLT_S 0xa0001053
+#define MASK_FLT_S 0xfe00707f
+#define MATCH_FEQ_S 0xa0002053
+#define MASK_FEQ_S 0xfe00707f
+#define MATCH_FLE_D 0xa2000053
+#define MASK_FLE_D 0xfe00707f
+#define MATCH_FLT_D 0xa2001053
+#define MASK_FLT_D 0xfe00707f
+#define MATCH_FEQ_D 0xa2002053
+#define MASK_FEQ_D 0xfe00707f
+#define MATCH_FLE_Q 0xa6000053
+#define MASK_FLE_Q 0xfe00707f
+#define MATCH_FLT_Q 0xa6001053
+#define MASK_FLT_Q 0xfe00707f
+#define MATCH_FEQ_Q 0xa6002053
+#define MASK_FEQ_Q 0xfe00707f
+#define MATCH_FCVT_W_S 0xc0000053
+#define MASK_FCVT_W_S 0xfff0007f
+#define MATCH_FCVT_WU_S 0xc0100053
+#define MASK_FCVT_WU_S 0xfff0007f
+#define MATCH_FCVT_L_S 0xc0200053
+#define MASK_FCVT_L_S 0xfff0007f
+#define MATCH_FCVT_LU_S 0xc0300053
+#define MASK_FCVT_LU_S 0xfff0007f
+#define MATCH_FMV_X_W 0xe0000053
+#define MASK_FMV_X_W 0xfff0707f
+#define MATCH_FCLASS_S 0xe0001053
+#define MASK_FCLASS_S 0xfff0707f
+#define MATCH_FCVT_W_D 0xc2000053
+#define MASK_FCVT_W_D 0xfff0007f
+#define MATCH_FCVT_WU_D 0xc2100053
+#define MASK_FCVT_WU_D 0xfff0007f
+#define MATCH_FCVT_L_D 0xc2200053
+#define MASK_FCVT_L_D 0xfff0007f
+#define MATCH_FCVT_LU_D 0xc2300053
+#define MASK_FCVT_LU_D 0xfff0007f
+#define MATCH_FMV_X_D 0xe2000053
+#define MASK_FMV_X_D 0xfff0707f
+#define MATCH_FCLASS_D 0xe2001053
+#define MASK_FCLASS_D 0xfff0707f
+#define MATCH_FCVT_W_Q 0xc6000053
+#define MASK_FCVT_W_Q 0xfff0007f
+#define MATCH_FCVT_WU_Q 0xc6100053
+#define MASK_FCVT_WU_Q 0xfff0007f
+#define MATCH_FCVT_L_Q 0xc6200053
+#define MASK_FCVT_L_Q 0xfff0007f
+#define MATCH_FCVT_LU_Q 0xc6300053
+#define MASK_FCVT_LU_Q 0xfff0007f
+#define MATCH_FMV_X_Q 0xe6000053
+#define MASK_FMV_X_Q 0xfff0707f
+#define MATCH_FCLASS_Q 0xe6001053
+#define MASK_FCLASS_Q 0xfff0707f
+#define MATCH_FCVT_S_W 0xd0000053
+#define MASK_FCVT_S_W 0xfff0007f
+#define MATCH_FCVT_S_WU 0xd0100053
+#define MASK_FCVT_S_WU 0xfff0007f
+#define MATCH_FCVT_S_L 0xd0200053
+#define MASK_FCVT_S_L 0xfff0007f
+#define MATCH_FCVT_S_LU 0xd0300053
+#define MASK_FCVT_S_LU 0xfff0007f
+#define MATCH_FMV_W_X 0xf0000053
+#define MASK_FMV_W_X 0xfff0707f
+#define MATCH_FCVT_D_W 0xd2000053
+#define MASK_FCVT_D_W 0xfff0007f
+#define MATCH_FCVT_D_WU 0xd2100053
+#define MASK_FCVT_D_WU 0xfff0007f
+#define MATCH_FCVT_D_L 0xd2200053
+#define MASK_FCVT_D_L 0xfff0007f
+#define MATCH_FCVT_D_LU 0xd2300053
+#define MASK_FCVT_D_LU 0xfff0007f
+#define MATCH_FMV_D_X 0xf2000053
+#define MASK_FMV_D_X 0xfff0707f
+#define MATCH_FCVT_Q_W 0xd6000053
+#define MASK_FCVT_Q_W 0xfff0007f
+#define MATCH_FCVT_Q_WU 0xd6100053
+#define MASK_FCVT_Q_WU 0xfff0007f
+#define MATCH_FCVT_Q_L 0xd6200053
+#define MASK_FCVT_Q_L 0xfff0007f
+#define MATCH_FCVT_Q_LU 0xd6300053
+#define MASK_FCVT_Q_LU 0xfff0007f
+#define MATCH_FMV_Q_X 0xf6000053
+#define MASK_FMV_Q_X 0xfff0707f
+#define MATCH_FLW 0x2007
+#define MASK_FLW 0x707f
+#define MATCH_FLD 0x3007
+#define MASK_FLD 0x707f
+#define MATCH_FLQ 0x4007
+#define MASK_FLQ 0x707f
+#define MATCH_FSW 0x2027
+#define MASK_FSW 0x707f
+#define MATCH_FSD 0x3027
+#define MASK_FSD 0x707f
+#define MATCH_FSQ 0x4027
+#define MASK_FSQ 0x707f
+#define MATCH_FMADD_S 0x43
+#define MASK_FMADD_S 0x600007f
+#define MATCH_FMSUB_S 0x47
+#define MASK_FMSUB_S 0x600007f
+#define MATCH_FNMSUB_S 0x4b
+#define MASK_FNMSUB_S 0x600007f
+#define MATCH_FNMADD_S 0x4f
+#define MASK_FNMADD_S 0x600007f
+#define MATCH_FMADD_D 0x2000043
+#define MASK_FMADD_D 0x600007f
+#define MATCH_FMSUB_D 0x2000047
+#define MASK_FMSUB_D 0x600007f
+#define MATCH_FNMSUB_D 0x200004b
+#define MASK_FNMSUB_D 0x600007f
+#define MATCH_FNMADD_D 0x200004f
+#define MASK_FNMADD_D 0x600007f
+#define MATCH_FMADD_Q 0x6000043
+#define MASK_FMADD_Q 0x600007f
+#define MATCH_FMSUB_Q 0x6000047
+#define MASK_FMSUB_Q 0x600007f
+#define MATCH_FNMSUB_Q 0x600004b
+#define MASK_FNMSUB_Q 0x600007f
+#define MATCH_FNMADD_Q 0x600004f
+#define MASK_FNMADD_Q 0x600007f
+#define MATCH_C_NOP 0x1
+#define MASK_C_NOP 0xffff
+#define MATCH_C_ADDI16SP 0x6101
+#define MASK_C_ADDI16SP 0xef83
+#define MATCH_C_JR 0x8002
+#define MASK_C_JR 0xf07f
+#define MATCH_C_JALR 0x9002
+#define MASK_C_JALR 0xf07f
+#define MATCH_C_EBREAK 0x9002
+#define MASK_C_EBREAK 0xffff
+#define MATCH_C_LD 0x6000
+#define MASK_C_LD 0xe003
+#define MATCH_C_SD 0xe000
+#define MASK_C_SD 0xe003
+#define MATCH_C_ADDIW 0x2001
+#define MASK_C_ADDIW 0xe003
+#define MATCH_C_LDSP 0x6002
+#define MASK_C_LDSP 0xe003
+#define MATCH_C_SDSP 0xe002
+#define MASK_C_SDSP 0xe003
+#define MATCH_C_ADDI4SPN 0x0
+#define MASK_C_ADDI4SPN 0xe003
+#define MATCH_C_FLD 0x2000
+#define MASK_C_FLD 0xe003
+#define MATCH_C_LW 0x4000
+#define MASK_C_LW 0xe003
+#define MATCH_C_FLW 0x6000
+#define MASK_C_FLW 0xe003
+#define MATCH_C_FSD 0xa000
+#define MASK_C_FSD 0xe003
+#define MATCH_C_SW 0xc000
+#define MASK_C_SW 0xe003
+#define MATCH_C_FSW 0xe000
+#define MASK_C_FSW 0xe003
+#define MATCH_C_ADDI 0x1
+#define MASK_C_ADDI 0xe003
+#define MATCH_C_JAL 0x2001
+#define MASK_C_JAL 0xe003
+#define MATCH_C_LI 0x4001
+#define MASK_C_LI 0xe003
+#define MATCH_C_LUI 0x6001
+#define MASK_C_LUI 0xe003
+#define MATCH_C_SRLI 0x8001
+#define MASK_C_SRLI 0xec03
+#define MATCH_C_SRAI 0x8401
+#define MASK_C_SRAI 0xec03
+#define MATCH_C_ANDI 0x8801
+#define MASK_C_ANDI 0xec03
+#define MATCH_C_SUB 0x8c01
+#define MASK_C_SUB 0xfc63
+#define MATCH_C_XOR 0x8c21
+#define MASK_C_XOR 0xfc63
+#define MATCH_C_OR 0x8c41
+#define MASK_C_OR 0xfc63
+#define MATCH_C_AND 0x8c61
+#define MASK_C_AND 0xfc63
+#define MATCH_C_SUBW 0x9c01
+#define MASK_C_SUBW 0xfc63
+#define MATCH_C_ADDW 0x9c21
+#define MASK_C_ADDW 0xfc63
+#define MATCH_C_J 0xa001
+#define MASK_C_J 0xe003
+#define MATCH_C_BEQZ 0xc001
+#define MASK_C_BEQZ 0xe003
+#define MATCH_C_BNEZ 0xe001
+#define MASK_C_BNEZ 0xe003
+#define MATCH_C_SLLI 0x2
+#define MASK_C_SLLI 0xe003
+#define MATCH_C_FLDSP 0x2002
+#define MASK_C_FLDSP 0xe003
+#define MATCH_C_LWSP 0x4002
+#define MASK_C_LWSP 0xe003
+#define MATCH_C_FLWSP 0x6002
+#define MASK_C_FLWSP 0xe003
+#define MATCH_C_MV 0x8002
+#define MASK_C_MV 0xf003
+#define MATCH_C_ADD 0x9002
+#define MASK_C_ADD 0xf003
+#define MATCH_C_FSDSP 0xa002
+#define MASK_C_FSDSP 0xe003
+#define MATCH_C_SWSP 0xc002
+#define MASK_C_SWSP 0xe003
+#define MATCH_C_FSWSP 0xe002
+#define MASK_C_FSWSP 0xe003
+#define MATCH_CUSTOM0 0xb
+#define MASK_CUSTOM0 0x707f
+#define MATCH_CUSTOM0_RS1 0x200b
+#define MASK_CUSTOM0_RS1 0x707f
+#define MATCH_CUSTOM0_RS1_RS2 0x300b
+#define MASK_CUSTOM0_RS1_RS2 0x707f
+#define MATCH_CUSTOM0_RD 0x400b
+#define MASK_CUSTOM0_RD 0x707f
+#define MATCH_CUSTOM0_RD_RS1 0x600b
+#define MASK_CUSTOM0_RD_RS1 0x707f
+#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b
+#define MASK_CUSTOM0_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM1 0x2b
+#define MASK_CUSTOM1 0x707f
+#define MATCH_CUSTOM1_RS1 0x202b
+#define MASK_CUSTOM1_RS1 0x707f
+#define MATCH_CUSTOM1_RS1_RS2 0x302b
+#define MASK_CUSTOM1_RS1_RS2 0x707f
+#define MATCH_CUSTOM1_RD 0x402b
+#define MASK_CUSTOM1_RD 0x707f
+#define MATCH_CUSTOM1_RD_RS1 0x602b
+#define MASK_CUSTOM1_RD_RS1 0x707f
+#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b
+#define MASK_CUSTOM1_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM2 0x5b
+#define MASK_CUSTOM2 0x707f
+#define MATCH_CUSTOM2_RS1 0x205b
+#define MASK_CUSTOM2_RS1 0x707f
+#define MATCH_CUSTOM2_RS1_RS2 0x305b
+#define MASK_CUSTOM2_RS1_RS2 0x707f
+#define MATCH_CUSTOM2_RD 0x405b
+#define MASK_CUSTOM2_RD 0x707f
+#define MATCH_CUSTOM2_RD_RS1 0x605b
+#define MASK_CUSTOM2_RD_RS1 0x707f
+#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b
+#define MASK_CUSTOM2_RD_RS1_RS2 0x707f
+#define MATCH_CUSTOM3 0x7b
+#define MASK_CUSTOM3 0x707f
+#define MATCH_CUSTOM3_RS1 0x207b
+#define MASK_CUSTOM3_RS1 0x707f
+#define MATCH_CUSTOM3_RS1_RS2 0x307b
+#define MASK_CUSTOM3_RS1_RS2 0x707f
+#define MATCH_CUSTOM3_RD 0x407b
+#define MASK_CUSTOM3_RD 0x707f
+#define MATCH_CUSTOM3_RD_RS1 0x607b
+#define MASK_CUSTOM3_RD_RS1 0x707f
+#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b
+#define MASK_CUSTOM3_RD_RS1_RS2 0x707f
+#define CSR_FFLAGS 0x1
+#define CSR_FRM 0x2
+#define CSR_FCSR 0x3
+#define CSR_CYCLE 0xc00
+#define CSR_TIME 0xc01
+#define CSR_INSTRET 0xc02
+#define CSR_HPMCOUNTER3 0xc03
+#define CSR_HPMCOUNTER4 0xc04
+#define CSR_HPMCOUNTER5 0xc05
+#define CSR_HPMCOUNTER6 0xc06
+#define CSR_HPMCOUNTER7 0xc07
+#define CSR_HPMCOUNTER8 0xc08
+#define CSR_HPMCOUNTER9 0xc09
+#define CSR_HPMCOUNTER10 0xc0a
+#define CSR_HPMCOUNTER11 0xc0b
+#define CSR_HPMCOUNTER12 0xc0c
+#define CSR_HPMCOUNTER13 0xc0d
+#define CSR_HPMCOUNTER14 0xc0e
+#define CSR_HPMCOUNTER15 0xc0f
+#define CSR_HPMCOUNTER16 0xc10
+#define CSR_HPMCOUNTER17 0xc11
+#define CSR_HPMCOUNTER18 0xc12
+#define CSR_HPMCOUNTER19 0xc13
+#define CSR_HPMCOUNTER20 0xc14
+#define CSR_HPMCOUNTER21 0xc15
+#define CSR_HPMCOUNTER22 0xc16
+#define CSR_HPMCOUNTER23 0xc17
+#define CSR_HPMCOUNTER24 0xc18
+#define CSR_HPMCOUNTER25 0xc19
+#define CSR_HPMCOUNTER26 0xc1a
+#define CSR_HPMCOUNTER27 0xc1b
+#define CSR_HPMCOUNTER28 0xc1c
+#define CSR_HPMCOUNTER29 0xc1d
+#define CSR_HPMCOUNTER30 0xc1e
+#define CSR_HPMCOUNTER31 0xc1f
+#define CSR_SSTATUS 0x100
+#define CSR_SIE 0x104
+#define CSR_STVEC 0x105
+#define CSR_SCOUNTEREN 0x106
+#define CSR_SSCRATCH 0x140
+#define CSR_SEPC 0x141
+#define CSR_SCAUSE 0x142
+#define CSR_SBADADDR 0x143
+#define CSR_SIP 0x144
+#define CSR_SPTBR 0x180
+#define CSR_MSTATUS 0x300
+#define CSR_MISA 0x301
+#define CSR_MEDELEG 0x302
+#define CSR_MIDELEG 0x303
+#define CSR_MIE 0x304
+#define CSR_MTVEC 0x305
+#define CSR_MCOUNTEREN 0x306
+#define CSR_MSCRATCH 0x340
+#define CSR_MEPC 0x341
+#define CSR_MCAUSE 0x342
+#define CSR_MBADADDR 0x343
+#define CSR_MIP 0x344
+#define CSR_PMPCFG0 0x3a0
+#define CSR_PMPCFG1 0x3a1
+#define CSR_PMPCFG2 0x3a2
+#define CSR_PMPCFG3 0x3a3
+#define CSR_PMPADDR0 0x3b0
+#define CSR_PMPADDR1 0x3b1
+#define CSR_PMPADDR2 0x3b2
+#define CSR_PMPADDR3 0x3b3
+#define CSR_PMPADDR4 0x3b4
+#define CSR_PMPADDR5 0x3b5
+#define CSR_PMPADDR6 0x3b6
+#define CSR_PMPADDR7 0x3b7
+#define CSR_PMPADDR8 0x3b8
+#define CSR_PMPADDR9 0x3b9
+#define CSR_PMPADDR10 0x3ba
+#define CSR_PMPADDR11 0x3bb
+#define CSR_PMPADDR12 0x3bc
+#define CSR_PMPADDR13 0x3bd
+#define CSR_PMPADDR14 0x3be
+#define CSR_PMPADDR15 0x3bf
+#define CSR_TSELECT 0x7a0
+#define CSR_TDATA1 0x7a1
+#define CSR_TDATA2 0x7a2
+#define CSR_TDATA3 0x7a3
+#define CSR_DCSR 0x7b0
+#define CSR_DPC 0x7b1
+#define CSR_DSCRATCH 0x7b2
+#define CSR_MCYCLE 0xb00
+#define CSR_MINSTRET 0xb02
+#define CSR_MHPMCOUNTER3 0xb03
+#define CSR_MHPMCOUNTER4 0xb04
+#define CSR_MHPMCOUNTER5 0xb05
+#define CSR_MHPMCOUNTER6 0xb06
+#define CSR_MHPMCOUNTER7 0xb07
+#define CSR_MHPMCOUNTER8 0xb08
+#define CSR_MHPMCOUNTER9 0xb09
+#define CSR_MHPMCOUNTER10 0xb0a
+#define CSR_MHPMCOUNTER11 0xb0b
+#define CSR_MHPMCOUNTER12 0xb0c
+#define CSR_MHPMCOUNTER13 0xb0d
+#define CSR_MHPMCOUNTER14 0xb0e
+#define CSR_MHPMCOUNTER15 0xb0f
+#define CSR_MHPMCOUNTER16 0xb10
+#define CSR_MHPMCOUNTER17 0xb11
+#define CSR_MHPMCOUNTER18 0xb12
+#define CSR_MHPMCOUNTER19 0xb13
+#define CSR_MHPMCOUNTER20 0xb14
+#define CSR_MHPMCOUNTER21 0xb15
+#define CSR_MHPMCOUNTER22 0xb16
+#define CSR_MHPMCOUNTER23 0xb17
+#define CSR_MHPMCOUNTER24 0xb18
+#define CSR_MHPMCOUNTER25 0xb19
+#define CSR_MHPMCOUNTER26 0xb1a
+#define CSR_MHPMCOUNTER27 0xb1b
+#define CSR_MHPMCOUNTER28 0xb1c
+#define CSR_MHPMCOUNTER29 0xb1d
+#define CSR_MHPMCOUNTER30 0xb1e
+#define CSR_MHPMCOUNTER31 0xb1f
+#define CSR_MHPMEVENT3 0x323
+#define CSR_MHPMEVENT4 0x324
+#define CSR_MHPMEVENT5 0x325
+#define CSR_MHPMEVENT6 0x326
+#define CSR_MHPMEVENT7 0x327
+#define CSR_MHPMEVENT8 0x328
+#define CSR_MHPMEVENT9 0x329
+#define CSR_MHPMEVENT10 0x32a
+#define CSR_MHPMEVENT11 0x32b
+#define CSR_MHPMEVENT12 0x32c
+#define CSR_MHPMEVENT13 0x32d
+#define CSR_MHPMEVENT14 0x32e
+#define CSR_MHPMEVENT15 0x32f
+#define CSR_MHPMEVENT16 0x330
+#define CSR_MHPMEVENT17 0x331
+#define CSR_MHPMEVENT18 0x332
+#define CSR_MHPMEVENT19 0x333
+#define CSR_MHPMEVENT20 0x334
+#define CSR_MHPMEVENT21 0x335
+#define CSR_MHPMEVENT22 0x336
+#define CSR_MHPMEVENT23 0x337
+#define CSR_MHPMEVENT24 0x338
+#define CSR_MHPMEVENT25 0x339
+#define CSR_MHPMEVENT26 0x33a
+#define CSR_MHPMEVENT27 0x33b
+#define CSR_MHPMEVENT28 0x33c
+#define CSR_MHPMEVENT29 0x33d
+#define CSR_MHPMEVENT30 0x33e
+#define CSR_MHPMEVENT31 0x33f
+#define CSR_MVENDORID 0xf11
+#define CSR_MARCHID 0xf12
+#define CSR_MIMPID 0xf13
+#define CSR_MHARTID 0xf14
+#define CSR_CYCLEH 0xc80
+#define CSR_TIMEH 0xc81
+#define CSR_INSTRETH 0xc82
+#define CSR_HPMCOUNTER3H 0xc83
+#define CSR_HPMCOUNTER4H 0xc84
+#define CSR_HPMCOUNTER5H 0xc85
+#define CSR_HPMCOUNTER6H 0xc86
+#define CSR_HPMCOUNTER7H 0xc87
+#define CSR_HPMCOUNTER8H 0xc88
+#define CSR_HPMCOUNTER9H 0xc89
+#define CSR_HPMCOUNTER10H 0xc8a
+#define CSR_HPMCOUNTER11H 0xc8b
+#define CSR_HPMCOUNTER12H 0xc8c
+#define CSR_HPMCOUNTER13H 0xc8d
+#define CSR_HPMCOUNTER14H 0xc8e
+#define CSR_HPMCOUNTER15H 0xc8f
+#define CSR_HPMCOUNTER16H 0xc90
+#define CSR_HPMCOUNTER17H 0xc91
+#define CSR_HPMCOUNTER18H 0xc92
+#define CSR_HPMCOUNTER19H 0xc93
+#define CSR_HPMCOUNTER20H 0xc94
+#define CSR_HPMCOUNTER21H 0xc95
+#define CSR_HPMCOUNTER22H 0xc96
+#define CSR_HPMCOUNTER23H 0xc97
+#define CSR_HPMCOUNTER24H 0xc98
+#define CSR_HPMCOUNTER25H 0xc99
+#define CSR_HPMCOUNTER26H 0xc9a
+#define CSR_HPMCOUNTER27H 0xc9b
+#define CSR_HPMCOUNTER28H 0xc9c
+#define CSR_HPMCOUNTER29H 0xc9d
+#define CSR_HPMCOUNTER30H 0xc9e
+#define CSR_HPMCOUNTER31H 0xc9f
+#define CSR_MCYCLEH 0xb80
+#define CSR_MINSTRETH 0xb82
+#define CSR_MHPMCOUNTER3H 0xb83
+#define CSR_MHPMCOUNTER4H 0xb84
+#define CSR_MHPMCOUNTER5H 0xb85
+#define CSR_MHPMCOUNTER6H 0xb86
+#define CSR_MHPMCOUNTER7H 0xb87
+#define CSR_MHPMCOUNTER8H 0xb88
+#define CSR_MHPMCOUNTER9H 0xb89
+#define CSR_MHPMCOUNTER10H 0xb8a
+#define CSR_MHPMCOUNTER11H 0xb8b
+#define CSR_MHPMCOUNTER12H 0xb8c
+#define CSR_MHPMCOUNTER13H 0xb8d
+#define CSR_MHPMCOUNTER14H 0xb8e
+#define CSR_MHPMCOUNTER15H 0xb8f
+#define CSR_MHPMCOUNTER16H 0xb90
+#define CSR_MHPMCOUNTER17H 0xb91
+#define CSR_MHPMCOUNTER18H 0xb92
+#define CSR_MHPMCOUNTER19H 0xb93
+#define CSR_MHPMCOUNTER20H 0xb94
+#define CSR_MHPMCOUNTER21H 0xb95
+#define CSR_MHPMCOUNTER22H 0xb96
+#define CSR_MHPMCOUNTER23H 0xb97
+#define CSR_MHPMCOUNTER24H 0xb98
+#define CSR_MHPMCOUNTER25H 0xb99
+#define CSR_MHPMCOUNTER26H 0xb9a
+#define CSR_MHPMCOUNTER27H 0xb9b
+#define CSR_MHPMCOUNTER28H 0xb9c
+#define CSR_MHPMCOUNTER29H 0xb9d
+#define CSR_MHPMCOUNTER30H 0xb9e
+#define CSR_MHPMCOUNTER31H 0xb9f
+#define CAUSE_MISALIGNED_FETCH 0x0
+#define CAUSE_FETCH_ACCESS 0x1
+#define CAUSE_ILLEGAL_INSTRUCTION 0x2
+#define CAUSE_BREAKPOINT 0x3
+#define CAUSE_MISALIGNED_LOAD 0x4
+#define CAUSE_LOAD_ACCESS 0x5
+#define CAUSE_MISALIGNED_STORE 0x6
+#define CAUSE_STORE_ACCESS 0x7
+#define CAUSE_USER_ECALL 0x8
+#define CAUSE_SUPERVISOR_ECALL 0x9
+#define CAUSE_HYPERVISOR_ECALL 0xa
+#define CAUSE_MACHINE_ECALL 0xb
+#define CAUSE_FETCH_PAGE_FAULT 0xc
+#define CAUSE_LOAD_PAGE_FAULT 0xd
+#define CAUSE_STORE_PAGE_FAULT 0xf
+#endif
+#ifdef DECLARE_INSN
+DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)
+DECLARE_INSN(bne, MATCH_BNE, MASK_BNE)
+DECLARE_INSN(blt, MATCH_BLT, MASK_BLT)
+DECLARE_INSN(bge, MATCH_BGE, MASK_BGE)
+DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU)
+DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU)
+DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR)
+DECLARE_INSN(jal, MATCH_JAL, MASK_JAL)
+DECLARE_INSN(lui, MATCH_LUI, MASK_LUI)
+DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC)
+DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI)
+DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI)
+DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI)
+DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU)
+DECLARE_INSN(xori, MATCH_XORI, MASK_XORI)
+DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI)
+DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI)
+DECLARE_INSN(ori, MATCH_ORI, MASK_ORI)
+DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI)
+DECLARE_INSN(add, MATCH_ADD, MASK_ADD)
+DECLARE_INSN(sub, MATCH_SUB, MASK_SUB)
+DECLARE_INSN(sll, MATCH_SLL, MASK_SLL)
+DECLARE_INSN(slt, MATCH_SLT, MASK_SLT)
+DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU)
+DECLARE_INSN(xor, MATCH_XOR, MASK_XOR)
+DECLARE_INSN(srl, MATCH_SRL, MASK_SRL)
+DECLARE_INSN(sra, MATCH_SRA, MASK_SRA)
+DECLARE_INSN(or, MATCH_OR, MASK_OR)
+DECLARE_INSN(and, MATCH_AND, MASK_AND)
+DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW)
+DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW)
+DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW)
+DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW)
+DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW)
+DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW)
+DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW)
+DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW)
+DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW)
+DECLARE_INSN(lb, MATCH_LB, MASK_LB)
+DECLARE_INSN(lh, MATCH_LH, MASK_LH)
+DECLARE_INSN(lw, MATCH_LW, MASK_LW)
+DECLARE_INSN(ld, MATCH_LD, MASK_LD)
+DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU)
+DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU)
+DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU)
+DECLARE_INSN(sb, MATCH_SB, MASK_SB)
+DECLARE_INSN(sh, MATCH_SH, MASK_SH)
+DECLARE_INSN(sw, MATCH_SW, MASK_SW)
+DECLARE_INSN(sd, MATCH_SD, MASK_SD)
+DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE)
+DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I)
+DECLARE_INSN(mul, MATCH_MUL, MASK_MUL)
+DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH)
+DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU)
+DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU)
+DECLARE_INSN(div, MATCH_DIV, MASK_DIV)
+DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU)
+DECLARE_INSN(rem, MATCH_REM, MASK_REM)
+DECLARE_INSN(remu, MATCH_REMU, MASK_REMU)
+DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW)
+DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW)
+DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW)
+DECLARE_INSN(remw, MATCH_REMW, MASK_REMW)
+DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW)
+DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
+DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)
+DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W)
+DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W)
+DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W)
+DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W)
+DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W)
+DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W)
+DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W)
+DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W)
+DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W)
+DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D)
+DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D)
+DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D)
+DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D)
+DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D)
+DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D)
+DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D)
+DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D)
+DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D)
+DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D)
+DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D)
+DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL)
+DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK)
+DECLARE_INSN(uret, MATCH_URET, MASK_URET)
+DECLARE_INSN(sret, MATCH_SRET, MASK_SRET)
+DECLARE_INSN(mret, MATCH_MRET, MASK_MRET)
+DECLARE_INSN(dret, MATCH_DRET, MASK_DRET)
+DECLARE_INSN(sfence_vma, MATCH_SFENCE_VMA, MASK_SFENCE_VMA)
+DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI)
+DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW)
+DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS)
+DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC)
+DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI)
+DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI)
+DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI)
+DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S)
+DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S)
+DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S)
+DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S)
+DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S)
+DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S)
+DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S)
+DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S)
+DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S)
+DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S)
+DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D)
+DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D)
+DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D)
+DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D)
+DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D)
+DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D)
+DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D)
+DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D)
+DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D)
+DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D)
+DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S)
+DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D)
+DECLARE_INSN(fadd_q, MATCH_FADD_Q, MASK_FADD_Q)
+DECLARE_INSN(fsub_q, MATCH_FSUB_Q, MASK_FSUB_Q)
+DECLARE_INSN(fmul_q, MATCH_FMUL_Q, MASK_FMUL_Q)
+DECLARE_INSN(fdiv_q, MATCH_FDIV_Q, MASK_FDIV_Q)
+DECLARE_INSN(fsgnj_q, MATCH_FSGNJ_Q, MASK_FSGNJ_Q)
+DECLARE_INSN(fsgnjn_q, MATCH_FSGNJN_Q, MASK_FSGNJN_Q)
+DECLARE_INSN(fsgnjx_q, MATCH_FSGNJX_Q, MASK_FSGNJX_Q)
+DECLARE_INSN(fmin_q, MATCH_FMIN_Q, MASK_FMIN_Q)
+DECLARE_INSN(fmax_q, MATCH_FMAX_Q, MASK_FMAX_Q)
+DECLARE_INSN(fcvt_s_q, MATCH_FCVT_S_Q, MASK_FCVT_S_Q)
+DECLARE_INSN(fcvt_q_s, MATCH_FCVT_Q_S, MASK_FCVT_Q_S)
+DECLARE_INSN(fcvt_d_q, MATCH_FCVT_D_Q, MASK_FCVT_D_Q)
+DECLARE_INSN(fcvt_q_d, MATCH_FCVT_Q_D, MASK_FCVT_Q_D)
+DECLARE_INSN(fsqrt_q, MATCH_FSQRT_Q, MASK_FSQRT_Q)
+DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S)
+DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S)
+DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S)
+DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D)
+DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D)
+DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D)
+DECLARE_INSN(fle_q, MATCH_FLE_Q, MASK_FLE_Q)
+DECLARE_INSN(flt_q, MATCH_FLT_Q, MASK_FLT_Q)
+DECLARE_INSN(feq_q, MATCH_FEQ_Q, MASK_FEQ_Q)
+DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S)
+DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S)
+DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S)
+DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S)
+DECLARE_INSN(fmv_x_w, MATCH_FMV_X_W, MASK_FMV_X_W)
+DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S)
+DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D)
+DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D)
+DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D)
+DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D)
+DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D)
+DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D)
+DECLARE_INSN(fcvt_w_q, MATCH_FCVT_W_Q, MASK_FCVT_W_Q)
+DECLARE_INSN(fcvt_wu_q, MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q)
+DECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q)
+DECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q)
+DECLARE_INSN(fmv_x_q, MATCH_FMV_X_Q, MASK_FMV_X_Q)
+DECLARE_INSN(fclass_q, MATCH_FCLASS_Q, MASK_FCLASS_Q)
+DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W)
+DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU)
+DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L)
+DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU)
+DECLARE_INSN(fmv_w_x, MATCH_FMV_W_X, MASK_FMV_W_X)
+DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W)
+DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU)
+DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L)
+DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU)
+DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X)
+DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W)
+DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU)
+DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L)
+DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU)
+DECLARE_INSN(fmv_q_x, MATCH_FMV_Q_X, MASK_FMV_Q_X)
+DECLARE_INSN(flw, MATCH_FLW, MASK_FLW)
+DECLARE_INSN(fld, MATCH_FLD, MASK_FLD)
+DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ)
+DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW)
+DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD)
+DECLARE_INSN(fsq, MATCH_FSQ, MASK_FSQ)
+DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S)
+DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S)
+DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S)
+DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S)
+DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D)
+DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D)
+DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D)
+DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D)
+DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q)
+DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q)
+DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q)
+DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q)
+DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP)
+DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP)
+DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR)
+DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR)
+DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK)
+DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD)
+DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD)
+DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW)
+DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP)
+DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP)
+DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN)
+DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD)
+DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW)
+DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW)
+DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD)
+DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW)
+DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW)
+DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI)
+DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL)
+DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI)
+DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI)
+DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI)
+DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI)
+DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI)
+DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB)
+DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR)
+DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR)
+DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND)
+DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW)
+DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW)
+DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J)
+DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ)
+DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ)
+DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI)
+DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP)
+DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP)
+DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP)
+DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV)
+DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD)
+DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP)
+DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP)
+DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP)
+DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0)
+DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1)
+DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2)
+DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD)
+DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1)
+DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2)
+DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1)
+DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1)
+DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2)
+DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD)
+DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1)
+DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2)
+DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2)
+DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1)
+DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2)
+DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD)
+DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1)
+DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2)
+DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3)
+DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1)
+DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2)
+DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD)
+DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1)
+DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2)
+#endif
+#ifdef DECLARE_CSR
+DECLARE_CSR(fflags, CSR_FFLAGS)
+DECLARE_CSR(frm, CSR_FRM)
+DECLARE_CSR(fcsr, CSR_FCSR)
+DECLARE_CSR(cycle, CSR_CYCLE)
+DECLARE_CSR(time, CSR_TIME)
+DECLARE_CSR(instret, CSR_INSTRET)
+DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3)
+DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4)
+DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5)
+DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6)
+DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7)
+DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8)
+DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9)
+DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10)
+DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11)
+DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12)
+DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13)
+DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14)
+DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15)
+DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16)
+DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17)
+DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18)
+DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19)
+DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20)
+DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21)
+DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22)
+DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23)
+DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24)
+DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25)
+DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26)
+DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27)
+DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28)
+DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29)
+DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30)
+DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31)
+DECLARE_CSR(sstatus, CSR_SSTATUS)
+DECLARE_CSR(sie, CSR_SIE)
+DECLARE_CSR(stvec, CSR_STVEC)
+DECLARE_CSR(scounteren, CSR_SCOUNTEREN)
+DECLARE_CSR(sscratch, CSR_SSCRATCH)
+DECLARE_CSR(sepc, CSR_SEPC)
+DECLARE_CSR(scause, CSR_SCAUSE)
+DECLARE_CSR(sbadaddr, CSR_SBADADDR)
+DECLARE_CSR(sip, CSR_SIP)
+DECLARE_CSR(sptbr, CSR_SPTBR)
+DECLARE_CSR(mstatus, CSR_MSTATUS)
+DECLARE_CSR(misa, CSR_MISA)
+DECLARE_CSR(medeleg, CSR_MEDELEG)
+DECLARE_CSR(mideleg, CSR_MIDELEG)
+DECLARE_CSR(mie, CSR_MIE)
+DECLARE_CSR(mtvec, CSR_MTVEC)
+DECLARE_CSR(mcounteren, CSR_MCOUNTEREN)
+DECLARE_CSR(mscratch, CSR_MSCRATCH)
+DECLARE_CSR(mepc, CSR_MEPC)
+DECLARE_CSR(mcause, CSR_MCAUSE)
+DECLARE_CSR(mbadaddr, CSR_MBADADDR)
+DECLARE_CSR(mip, CSR_MIP)
+DECLARE_CSR(pmpcfg0, CSR_PMPCFG0)
+DECLARE_CSR(pmpcfg1, CSR_PMPCFG1)
+DECLARE_CSR(pmpcfg2, CSR_PMPCFG2)
+DECLARE_CSR(pmpcfg3, CSR_PMPCFG3)
+DECLARE_CSR(pmpaddr0, CSR_PMPADDR0)
+DECLARE_CSR(pmpaddr1, CSR_PMPADDR1)
+DECLARE_CSR(pmpaddr2, CSR_PMPADDR2)
+DECLARE_CSR(pmpaddr3, CSR_PMPADDR3)
+DECLARE_CSR(pmpaddr4, CSR_PMPADDR4)
+DECLARE_CSR(pmpaddr5, CSR_PMPADDR5)
+DECLARE_CSR(pmpaddr6, CSR_PMPADDR6)
+DECLARE_CSR(pmpaddr7, CSR_PMPADDR7)
+DECLARE_CSR(pmpaddr8, CSR_PMPADDR8)
+DECLARE_CSR(pmpaddr9, CSR_PMPADDR9)
+DECLARE_CSR(pmpaddr10, CSR_PMPADDR10)
+DECLARE_CSR(pmpaddr11, CSR_PMPADDR11)
+DECLARE_CSR(pmpaddr12, CSR_PMPADDR12)
+DECLARE_CSR(pmpaddr13, CSR_PMPADDR13)
+DECLARE_CSR(pmpaddr14, CSR_PMPADDR14)
+DECLARE_CSR(pmpaddr15, CSR_PMPADDR15)
+DECLARE_CSR(tselect, CSR_TSELECT)
+DECLARE_CSR(tdata1, CSR_TDATA1)
+DECLARE_CSR(tdata2, CSR_TDATA2)
+DECLARE_CSR(tdata3, CSR_TDATA3)
+DECLARE_CSR(dcsr, CSR_DCSR)
+DECLARE_CSR(dpc, CSR_DPC)
+DECLARE_CSR(dscratch, CSR_DSCRATCH)
+DECLARE_CSR(mcycle, CSR_MCYCLE)
+DECLARE_CSR(minstret, CSR_MINSTRET)
+DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3)
+DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4)
+DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5)
+DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6)
+DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7)
+DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8)
+DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9)
+DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10)
+DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11)
+DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12)
+DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13)
+DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14)
+DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15)
+DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16)
+DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17)
+DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18)
+DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19)
+DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20)
+DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21)
+DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22)
+DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23)
+DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24)
+DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25)
+DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26)
+DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27)
+DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28)
+DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29)
+DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30)
+DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31)
+DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3)
+DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4)
+DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5)
+DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6)
+DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7)
+DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8)
+DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9)
+DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10)
+DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11)
+DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12)
+DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13)
+DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14)
+DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15)
+DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16)
+DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17)
+DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18)
+DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19)
+DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20)
+DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21)
+DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22)
+DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23)
+DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24)
+DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25)
+DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26)
+DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27)
+DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28)
+DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29)
+DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30)
+DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31)
+DECLARE_CSR(mvendorid, CSR_MVENDORID)
+DECLARE_CSR(marchid, CSR_MARCHID)
+DECLARE_CSR(mimpid, CSR_MIMPID)
+DECLARE_CSR(mhartid, CSR_MHARTID)
+DECLARE_CSR(cycleh, CSR_CYCLEH)
+DECLARE_CSR(timeh, CSR_TIMEH)
+DECLARE_CSR(instreth, CSR_INSTRETH)
+DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H)
+DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H)
+DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H)
+DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H)
+DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H)
+DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H)
+DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H)
+DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H)
+DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H)
+DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H)
+DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H)
+DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H)
+DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H)
+DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H)
+DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H)
+DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H)
+DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H)
+DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H)
+DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H)
+DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H)
+DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H)
+DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H)
+DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H)
+DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H)
+DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H)
+DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H)
+DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H)
+DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H)
+DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H)
+DECLARE_CSR(mcycleh, CSR_MCYCLEH)
+DECLARE_CSR(minstreth, CSR_MINSTRETH)
+DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H)
+DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H)
+DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H)
+DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H)
+DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H)
+DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H)
+DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H)
+DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H)
+DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H)
+DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H)
+DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H)
+DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H)
+DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H)
+DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H)
+DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H)
+DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H)
+DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H)
+DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H)
+DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H)
+DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H)
+DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H)
+DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H)
+DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H)
+DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H)
+DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H)
+DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H)
+DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H)
+DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H)
+DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H)
+#endif
+#ifdef DECLARE_CAUSE
+DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH)
+DECLARE_CAUSE("fetch access", CAUSE_FETCH_ACCESS)
+DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION)
+DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT)
+DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD)
+DECLARE_CAUSE("load access", CAUSE_LOAD_ACCESS)
+DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE)
+DECLARE_CAUSE("store access", CAUSE_STORE_ACCESS)
+DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL)
+DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL)
+DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL)
+DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL)
+DECLARE_CAUSE("fetch page fault", CAUSE_FETCH_PAGE_FAULT)
+DECLARE_CAUSE("load page fault", CAUSE_LOAD_PAGE_FAULT)
+DECLARE_CAUSE("store page fault", CAUSE_STORE_PAGE_FAULT)
+#endif
+
+#include "scr1_specific.h"
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/riscv_macros.h b/verilog/rtl/syntacore/scr1/sim/tests/common/riscv_macros.h
new file mode 100644
index 0000000..9390a8c
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/riscv_macros.h
@@ -0,0 +1,819 @@
+// See LICENSE for license details.
+
+#ifndef __RISCV_MACROS_H
+#define __RISCV_MACROS_H
+
+#include "riscv_csr_encoding.h"
+#include "sc_test.h"
+
+//-----------------------------------------------------------------------
+// Begin Macro
+//-----------------------------------------------------------------------
+
+#define RVTEST_RV64U \
+ .macro init; \
+ .endm
+
+#define RVTEST_RV64UF \
+ .macro init; \
+ RVTEST_FP_ENABLE; \
+ .endm
+
+#define RVTEST_RV32U \
+ .macro init; \
+ .endm
+
+#define RVTEST_RV32UF \
+ .macro init; \
+ RVTEST_FP_ENABLE; \
+ .endm
+
+#define RVTEST_RV64M \
+ .macro init; \
+ RVTEST_ENABLE_MACHINE; \
+ .endm
+
+#define RVTEST_RV64S \
+ .macro init; \
+ RVTEST_ENABLE_SUPERVISOR; \
+ .endm
+
+#define RVTEST_RV32M \
+ .macro init; \
+ RVTEST_ENABLE_MACHINE; \
+ .endm
+
+#define RVTEST_RV32S \
+ .macro init; \
+ RVTEST_ENABLE_SUPERVISOR; \
+ .endm
+
+#if __riscv_xlen == 64
+# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bgez a0, 1f; RVTEST_PASS; 1:
+#else
+# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bltz a0, 1f; RVTEST_PASS; 1:
+#endif
+
+#define INIT_PMP \
+ la t0, 1f; \
+ csrw mtvec, t0; \
+ li t0, -1; /* Set up a PMP to permit all accesses */ \
+ csrw pmpaddr0, t0; \
+ li t0, PMP_NAPOT | PMP_R | PMP_W | PMP_X; \
+ csrw pmpcfg0, t0; \
+ .balign 4; \
+1:
+
+#define INIT_SPTBR \
+ la t0, 1f; \
+ csrw mtvec, t0; \
+ csrwi sptbr, 0; \
+ .balign 4; \
+1:
+
+#define DELEGATE_NO_TRAPS
+
+#define RVTEST_ENABLE_SUPERVISOR \
+ li a0, MSTATUS_MPP & (MSTATUS_MPP >> 1); \
+ csrs mstatus, a0; \
+ li a0, SIP_SSIP | SIP_STIP; \
+ csrs mideleg, a0; \
+
+#define RVTEST_ENABLE_MACHINE \
+ li a0, MSTATUS_MPP; \
+ csrs mstatus, a0; \
+
+#define RVTEST_FP_ENABLE \
+ li a0, MSTATUS_FS & (MSTATUS_FS >> 1); \
+ csrs mstatus, a0; \
+ csrwi fcsr, 0
+
+#define RISCV_MULTICORE_DISABLE \
+ csrr a0, mhartid; \
+ 1: bnez a0, 1b
+
+#define EXTRA_TVEC_USER
+#define EXTRA_TVEC_SUPERVISOR
+#define EXTRA_TVEC_HYPERVISOR
+#define EXTRA_TVEC_MACHINE
+#define EXTRA_INIT
+#define EXTRA_INIT_TIMER
+
+#define INTERRUPT_HANDLER j other_exception /* No interrupts should occur */
+
+#define RVTEST_CODE_BEGIN \
+ .section .text.init; \
+ .org 0xC0, 0x00; \
+ .balign 64; \
+ .weak stvec_handler; \
+ .weak mtvec_handler; \
+trap_vector: \
+ /* test whether the test came from pass/fail */ \
+ csrr a4, mcause; \
+ li a5, CAUSE_USER_ECALL; \
+ beq a4, a5, _report; \
+ li a5, CAUSE_SUPERVISOR_ECALL; \
+ beq a4, a5, _report; \
+ li a5, CAUSE_MACHINE_ECALL; \
+ beq a4, a5, _report; \
+ /* if an mtvec_handler is defined, jump to it */ \
+ la a4, mtvec_handler; \
+ beqz a4, 1f; \
+ jr a4; \
+ /* was it an interrupt or an exception? */ \
+1: csrr a4, mcause; \
+ bgez a4, handle_exception; \
+ INTERRUPT_HANDLER; \
+handle_exception: \
+ /* we don't know how to handle whatever the exception was */ \
+other_exception: \
+ /* some unhandlable exception occurred */ \
+ li a0, 0x1; \
+_report: \
+ j sc_exit; \
+ .balign 64; \
+ .globl _start; \
+_start: \
+ RISCV_MULTICORE_DISABLE; \
+ /*INIT_SPTBR;*/ \
+ /*INIT_PMP;*/ \
+ DELEGATE_NO_TRAPS; \
+ li TESTNUM, 0; \
+ la t0, trap_vector; \
+ csrw mtvec, t0; \
+ CHECK_XLEN; \
+ /* if an stvec_handler is defined, delegate exceptions to it */ \
+ la t0, stvec_handler; \
+ beqz t0, 1f; \
+ csrw stvec, t0; \
+ li t0, (1 << CAUSE_LOAD_PAGE_FAULT) | \
+ (1 << CAUSE_STORE_PAGE_FAULT) | \
+ (1 << CAUSE_FETCH_PAGE_FAULT) | \
+ (1 << CAUSE_MISALIGNED_FETCH) | \
+ (1 << CAUSE_USER_ECALL) | \
+ (1 << CAUSE_BREAKPOINT); \
+ csrw medeleg, t0; \
+ csrr t1, medeleg; \
+ bne t0, t1, other_exception; \
+1: csrwi mstatus, 0; \
+ init; \
+ EXTRA_INIT; \
+ EXTRA_INIT_TIMER; \
+ la t0, _run_test; \
+ csrw mepc, t0; \
+ csrr a0, mhartid; \
+ mret; \
+ .section .text; \
+_run_test:
+
+//-----------------------------------------------------------------------
+// End Macro
+//-----------------------------------------------------------------------
+
+#define RVTEST_CODE_END ecall: ecall
+
+//-----------------------------------------------------------------------
+// Pass/Fail Macro
+//-----------------------------------------------------------------------
+
+#define RVTEST_PASS \
+ fence; \
+ mv a1, TESTNUM; \
+ li a0, 0x0; \
+ ecall
+
+#define TESTNUM x28
+#define RVTEST_FAIL \
+ fence; \
+ mv a1, TESTNUM; \
+ li a0, 0x1; \
+ ecall
+
+//-----------------------------------------------------------------------
+// Data Section Macro
+//-----------------------------------------------------------------------
+
+#define EXTRA_DATA
+
+#define RVTEST_DATA_BEGIN \
+ EXTRA_DATA \
+ .pushsection .tohost,"aw",@progbits; \
+ .balign 64; .global tohost; tohost: .dword 0; \
+ .balign 64; .global fromhost; fromhost: .dword 0; \
+ .popsection; \
+ .balign 16; \
+ .global begin_regstate; begin_regstate: .dword 0; .dword 0; .dword 0; \
+ .balign 16; \
+ .global begin_signature; begin_signature:
+
+#define RVTEST_DATA_END .balign 16; .global end_signature; end_signature:
+
+#-----------------------------------------------------------------------
+# Helper macros
+#-----------------------------------------------------------------------
+
+#define MASK_XLEN(x) ((x) & ((1 << (__riscv_xlen - 1) << 1) - 1))
+
+#define TEST_CASE( testnum, testreg, correctval, code... ) \
+test_ ## testnum: \
+ code; \
+ li x29, MASK_XLEN(correctval); \
+ li TESTNUM, testnum; \
+ 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, x3, result, \
+ li x1, MASK_XLEN(val1); \
+ inst x3, x1, SEXT_IMM(imm); \
+ )
+
+#define TEST_IMM_OP_RVC( testnum, inst, result, val1, imm ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, val1; \
+ inst x1, 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 x3, x1, SEXT_IMM(imm); \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ addi x6, x3, 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, x3, result, \
+ li x4, 0; \
+1: li x1, MASK_XLEN(val1); \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ inst x3, 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 vector config instructions
+#-----------------------------------------------------------------------
+
+#define TEST_VSETCFGIVL( testnum, nxpr, nfpr, bank, vl, result ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, (bank << 12); \
+ vsetcfg x1,nxpr,nfpr; \
+ li x1, vl; \
+ vsetvl x1,x1; \
+ )
+
+#define TEST_VVCFG( testnum, nxpr, nfpr, bank, vl, result ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, (bank << 12) | (nfpr << 6) | nxpr; \
+ vsetcfg x1; \
+ li x1, vl; \
+ vsetvl x1,x1; \
+ )
+
+#define TEST_VSETVL( testnum, nxpr, nfpr, bank, vl, result ) \
+ TEST_CASE( testnum, x1, result, \
+ li x1, (bank << 12); \
+ vsetcfg x1,nxpr,nfpr; \
+ li x1, vl; \
+ vsetvl x1, x1; \
+ )
+
+#-----------------------------------------------------------------------
+# Tests for an instruction with register operands
+#-----------------------------------------------------------------------
+
+#define TEST_R_OP( testnum, inst, result, val1 ) \
+ TEST_CASE( testnum, x3, result, \
+ li x1, val1; \
+ inst x3, 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 x3, x1; \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ addi x6, x3, 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, x3, result, \
+ li x1, MASK_XLEN(val1); \
+ li x2, MASK_XLEN(val2); \
+ inst x3, 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 x3, x1, x2; \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ addi x6, x3, 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, x3, 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 x3, 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, x3, 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 x3, 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, x3, result, \
+ la x1, base; \
+ inst x3, offset(x1); \
+ )
+
+#define TEST_ST_OP( testnum, load_inst, store_inst, result, offset, base ) \
+ TEST_CASE( testnum, x3, result, \
+ la x1, base; \
+ li x2, result; \
+ store_inst x2, offset(x1); \
+ load_inst x3, offset(x1); \
+ )
+
+#define TEST_LD_DEST_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ li x4, 0; \
+1: la x1, base; \
+ inst x3, offset(x1); \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ addi x6, x3, 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; \
+ li x4, 0; \
+1: la x1, base; \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ inst x3, offset(x1); \
+ li x29, result; \
+ bne x3, 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; \
+ 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 x3, offset(x2); \
+ li x29, result; \
+ bne x3, 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; \
+ 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 x3, offset(x2); \
+ li x29, result; \
+ bne x3, x29, fail; \
+ addi x4, x4, 1; \
+ li x5, 2; \
+ bne x4, x5, 1b \
+
+#-----------------------------------------------------------------------
+# Test branch instructions
+#-----------------------------------------------------------------------
+
+#define TEST_BR1_OP_TAKEN( testnum, inst, val1 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ li x1, val1; \
+ inst x1, 2f; \
+ bne x0, TESTNUM, fail; \
+1: bne x0, TESTNUM, 3f; \
+2: inst x1, 1b; \
+ bne x0, TESTNUM, fail; \
+3:
+
+#define TEST_BR1_OP_NOTTAKEN( testnum, inst, val1 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ li x1, val1; \
+ inst x1, 1f; \
+ bne x0, TESTNUM, 2f; \
+1: bne x0, TESTNUM, fail; \
+2: inst x1, 1b; \
+3:
+
+#define TEST_BR1_SRC1_BYPASS( testnum, nop_cycles, inst, val1 ) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ li x4, 0; \
+1: li x1, val1; \
+ TEST_INSERT_NOPS_ ## nop_cycles \
+ inst x1, 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; \
+ 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; \
+ 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; \
+ 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; \
+ 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; \
+ 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; \
+ 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; \
+ 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; \
+ j 2f; \
+ .balign 4; \
+ .data; \
+ test_ ## testnum ## _data: \
+ .float val1; \
+ .float val2; \
+ .float val3; \
+ .result; \
+ .text; \
+2:
+
+#define TEST_FP_OP_D_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); \
+ ld a3, 24(a0); \
+ code; \
+ fsflags a1, x0; \
+ li a2, flags; \
+ bne a0, a3, fail; \
+ bne a1, a2, fail; \
+ j 2f; \
+ .data; \
+ .balign 8; \
+ test_ ## testnum ## _data: \
+ .double val1; \
+ .double val2; \
+ .double val3; \
+ .result; \
+ .text; \
+2:
+
+#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_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_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_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_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_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_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_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; \
+ 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; \
+ j 1f; \
+ .balign 4; \
+ test_ ## testnum ## _data: \
+ .float result; \
+1:
+
+#define TEST_INT_FP_OP_D( testnum, inst, result, val1 ) \
+test_ ## testnum: \
+ li 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; \
+ j 1f; \
+ .balign 8; \
+ test_ ## testnum ## _data: \
+ .double result; \
+1:
+
+#-----------------------------------------------------------------------
+# 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/common/sc_print.c b/verilog/rtl/syntacore/scr1/sim/tests/common/sc_print.c
new file mode 100644
index 0000000..3af9d23
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/sc_print.c
@@ -0,0 +1,282 @@
+/// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details
+/// @file <sc_print.c>
+///
+
+#include <string.h>
+#include <stdarg.h>
+#include "sc_print.h"
+
+#define SC_SIM_OUTPORT (0xf0000000)
+#define CHAR_BIT (8)
+
+static void
+sc_puts(long str, long strlen) {
+ volatile char *out_ptr = (volatile char*)SC_SIM_OUTPORT;
+ const char *in_ptr = (const char*)str;
+ for (long len = strlen; len > 0; --len)
+ *out_ptr = *in_ptr++;
+}
+
+#undef putchar
+int
+putchar(int ch) {
+ static __thread char buf[64] __attribute__((aligned(64)));
+ static __thread int buflen = 0;
+
+ buf[buflen++] = ch;
+
+ if ( ch == '\n' || buflen == sizeof(buf) ) {
+ sc_puts((long)buf, buflen);
+ buflen = 0;
+ }
+
+ return 0;
+}
+
+static void
+printf_putch(int ch, void** data)
+{
+ putchar(ch);
+}
+
+static void
+print(const char *str)
+{
+ sc_puts((long)str, strlen(str));
+}
+
+
+static long long
+getint(va_list *ap, int lflag)
+{
+ if ( lflag >= 2 )
+ return va_arg(*ap, long long);
+ else if ( lflag )
+ return va_arg(*ap, long);
+ else
+ return va_arg(*ap, int);
+}
+
+
+static unsigned long long
+getuint(va_list *ap, int lflag)
+{
+ if ( lflag >= 2 )
+ return va_arg(*ap, unsigned long long);
+ else if ( lflag )
+ return va_arg(*ap, unsigned long);
+ else
+ return va_arg(*ap, unsigned int);
+}
+
+static inline void
+printnum(void(*putch)(int, void**),
+void **putdat,
+unsigned long long num,
+unsigned base,
+int width,
+int padc,
+int hex_A)
+{
+ unsigned digs[sizeof(num) * CHAR_BIT];
+ int pos = 0;
+
+ for ( ;; ) {
+ digs[pos++] = num % base;
+ if ( num < base )
+ break;
+ num /= base;
+ }
+
+ while ( width-- > pos )
+ putch(padc, putdat);
+
+ while ( pos-- > 0 )
+ putch(digs[pos] + (digs[pos] >= 10 ? hex_A - 10 : '0'), putdat);
+}
+
+static void
+vprintfmt(void(*putch)(int, void**), void **putdat, const char *fmt, va_list ap)
+{
+ register const char* p;
+ const char* last_fmt;
+ register int ch;
+ int err;
+ unsigned long long num;
+ int base;
+ int lflag;
+ int width;
+ int precision;
+ int altflag;
+ char padc;
+ int hex_A = 'a';
+ for ( ;; ) {
+ while ( (ch = *(unsigned char *)fmt) != '%' ) {
+ if ( ch == '\0' )
+ return;
+ ++fmt;
+ putch(ch, putdat);
+ }
+ ++fmt;
+
+ // Process a %-escape sequence
+ last_fmt = fmt;
+ padc = ' ';
+ width = -1;
+ precision = -1;
+ lflag = 0;
+ altflag = 0;
+
+reswitch:
+ switch ( ch = *(unsigned char *)fmt++ ) {
+ // flag to pad on the right
+ case '-':
+ padc = '-';
+ goto reswitch;
+
+ // flag to pad with 0's instead of spaces
+ case '0':
+ padc = '0';
+ goto reswitch;
+
+ // width field
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ for ( precision = 0;; ++fmt ) {
+ precision = precision * 10 + ch - '0';
+ ch = *fmt;
+ if ( ch < '0' || ch > '9' )
+ break;
+ }
+ goto process_precision;
+
+ case '*':
+ precision = va_arg(ap, int);
+ goto process_precision;
+
+ case '.':
+ if ( width < 0 )
+ width = 0;
+ goto reswitch;
+
+ case '#':
+ altflag = 1;
+ goto reswitch;
+
+process_precision:
+ if ( width < 0 ) {
+ width = precision;
+ precision = -1;
+ }
+ goto reswitch;
+
+ // long flag (doubled for long long)
+ case 'l':
+ lflag++;
+ goto reswitch;
+
+ // character
+ case 'c':
+ putch(va_arg(ap, int), putdat);
+ break;
+
+ // string
+ case 's':
+ if ( (p = va_arg(ap, char *)) == NULL )
+ p = "(null)";
+ if ( width > 0 && padc != '-' )
+ for ( width -= strnlen(p, precision); width > 0; width-- )
+ putch(padc, putdat);
+ for ( ; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width-- ) {
+ putch(ch, putdat);
+ p++;
+ }
+ for ( ; width > 0; width-- )
+ putch(' ', putdat);
+ break;
+
+ // (signed) decimal
+ case 'd':
+ num = getint(&ap, lflag);
+ if ( (long long)num < 0 ) {
+ putch('-', putdat);
+ num = -(long long)num;
+ }
+ base = 10;
+ goto signed_number;
+
+ case 'f':
+ {
+ // #ifndef nopfloat
+ // double num = getdouble(&ap, lflag);
+ // printdoubleF(putch, putdat, num, width, precision, padc);
+ // #endif
+ }
+ break;
+
+ // unsigned decimal
+ case 'u':
+ base = 10;
+ goto unsigned_number;
+
+ // (unsigned) octal
+ case 'o':
+ // should do something with padding so it's always 3 octits
+ base = 8;
+ goto unsigned_number;
+
+ // pointer
+ case 'p':
+ // static_assert(sizeof(long) == sizeof(void*));
+ lflag = 1;
+ putch('0', putdat);
+ putch('x', putdat);
+ /* fall through to 'x' */
+
+ // (unsigned) hexadecimal
+ case 'x':
+ hex_A = 'a';
+ base = 16;
+ goto unsigned_number;
+
+ case 'X':
+ hex_A = 'A';
+ base = 16;
+unsigned_number:
+ num = getuint(&ap, lflag);
+signed_number:
+ printnum(putch, putdat, num, base, width, padc, hex_A);
+ break;
+
+ // escaped '%' character
+ case '%':
+ putch(ch, putdat);
+ break;
+
+ // unrecognized escape sequence - just print it literally
+ default:
+ putch('%', putdat);
+ fmt = last_fmt;
+ break;
+ }
+ }
+}
+
+int
+sc_printf(const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+
+ vprintfmt(printf_putch, NULL, fmt, ap);
+
+ va_end(ap);
+ return 0; // incorrect return value, but who cares, anyway?
+}
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/sc_print.h b/verilog/rtl/syntacore/scr1/sim/tests/common/sc_print.h
new file mode 100644
index 0000000..f175417
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/sc_print.h
@@ -0,0 +1,10 @@
+/// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details
+/// @file <sc_print.h>
+///
+
+#ifndef SC_PRINT_H
+#define SC_PRINT_H
+
+extern int sc_printf(const char* fmt, ...);
+
+#endif // SC_PRINT_H
\ No newline at end of file
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/sc_test.h b/verilog/rtl/syntacore/scr1/sim/tests/common/sc_test.h
new file mode 100644
index 0000000..84827aa
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/sc_test.h
@@ -0,0 +1,48 @@
+/// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details
+/// @file <sc_test.h>
+///
+
+#ifndef SC_TEST_H
+#define SC_TEST_H
+
+#if defined(__ASSEMBLER__)
+.altmacro
+
+.macro zero_int_reg regn
+mv x\regn, zero
+.endm
+
+.macro zero_int_regs reg_first, reg_last
+.set regn, \reg_first
+.rept \reg_last - \reg_first + 1
+zero_int_reg %(regn)
+.set regn, regn+1
+.endr
+.endm
+
+#define report_results(result) \
+li a0, result; \
+la t0, sc_exit; \
+jr t0;
+
+.pushsection sc_test_section, "ax"
+sc_exit: la t0, SIM_EXIT; jr t0;
+.balign 32
+.popsection
+#define sc_pass report_results(0x0)
+#define sc_fail report_results(0x1)
+
+#else
+
+extern void sc_exit(unsigned result, unsigned res0, unsigned res1, unsigned res2, unsigned res3)
+ __attribute__ ((noinline, noreturn));
+
+static inline void __attribute__ ((noreturn))
+report_results(unsigned result, unsigned res0, unsigned res1, unsigned res2, unsigned res3)
+{
+ sc_exit(result, res0, res1, res2, res3);
+}
+
+#endif
+
+#endif // SC_TEST_H
diff --git a/verilog/rtl/syntacore/scr1/sim/tests/common/scr1_specific.h b/verilog/rtl/syntacore/scr1/sim/tests/common/scr1_specific.h
new file mode 100644
index 0000000..f965880
--- /dev/null
+++ b/verilog/rtl/syntacore/scr1/sim/tests/common/scr1_specific.h
@@ -0,0 +1,20 @@
+#ifndef __SCR1__SPECIFIC
+#define __SCR1__SPECIFIC
+
+#define mcounten 0x7E0
+
+// Memory-mapped registers
+#define mtime_ctrl 0x00490000
+#define mtime_div 0x00490004
+#define mtime 0x00490008
+#define mtimeh 0x0049000C
+#define mtimecmp 0x00490010
+#define mtimecmph 0x00490014
+
+#define SCR1_MTIME_CTRL_EN 0
+#define SCR1_MTIME_CTRL_CLKSRC 1
+
+#define SCR1_MTIME_CTRL_WR_MASK 0x3
+#define SCR1_MTIME_DIV_WR_MASK 0x3FF
+
+#endif // _SCR1__SPECIFIC