pull the git change from https://github.com/dineshannayya/riscduino.git on 15th Feb 2022 with SRAM
diff --git a/verilog/dv/Makefile b/verilog/dv/Makefile
new file mode 100644
index 0000000..4ee38f8
--- /dev/null
+++ b/verilog/dv/Makefile
@@ -0,0 +1,39 @@
+# 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
+
+# ---- Test patterns for project striVe ----
+
+.SUFFIXES:
+.SILENT: clean all
+
+PATTERNS = wb_port risc_boot user_risc_boot user_uart user_spi user_i2cm riscv_regress user_basic user_mbist_test1 user_risc_soft_boot user_uart_master uart_master
+
+all:  ${PATTERNS}
+	for i in ${PATTERNS}; do \
+		( cd $$i && make -f Makefile $${i}.vcd &> verify.log && grep Monitor verify.log) ; \
+	done
+
+DV_PATTERNS = $(foreach dv, $(PATTERNS), verify-$(dv))
+$(DV_PATTERNS): verify-% : 
+	cd $* && make
+
+clean:  ${PATTERNS}
+	for i in ${PATTERNS}; do \
+		( cd $$i && make clean ) ; \
+	done
+	rm -rf *.log
+	
+.PHONY: clean all
diff --git a/verilog/dv/README.md b/verilog/dv/README.md
new file mode 100644
index 0000000..1a834f7
--- /dev/null
+++ b/verilog/dv/README.md
@@ -0,0 +1,236 @@
+<!---
+# 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
+-->
+
+# Simulation Environment Setup
+
+There are two options for setting up the simulation environment: 
+
+* Pulling a pre-built docker image 
+* Installing the dependecies locally
+
+## 1. Docker
+
+There is an available docker setup with the needed tools at [efabless/dockerized-verification-setup](https://github.com/efabless/dockerized-verification-setup) 
+
+Run the following to pull the image: 
+
+```
+docker pull efabless/dv_setup:latest
+```
+
+## 2. Local Installion (Linux)
+
+You will need to fullfil these dependecies: 
+
+* Icarus Verilog (10.2+)
+* RV32I Toolchain
+
+Using apt, you can install Icarus Verilog:
+
+```bash
+sudo apt-get install iverilog
+```
+
+Next, you will need to build the RV32I toolchain. Firstly, export the installation path for the RV32I toolchain, 
+
+```bash
+export GCC_PATH=<gcc-installation-path>
+```
+
+Then, run the following: 
+
+```bash
+# packages needed:
+sudo apt-get install autoconf automake autotools-dev curl libmpc-dev \
+    libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo \
+    gperf libtool patchutils bc zlib1g-dev git libexpat1-dev
+
+sudo mkdir $GCC_PATH
+sudo chown $USER $GCC_PATH
+
+git clone https://github.com/riscv/riscv-gnu-toolchain riscv-gnu-toolchain-rv32i
+cd riscv-gnu-toolchain-rv32i
+git checkout 411d134
+git submodule update --init --recursive
+
+mkdir build; cd build
+../configure --with-arch=rv32i --prefix=$GCC_PATH
+make -j$(nproc)
+```
+
+# Running Simulation
+
+## Docker
+
+First, you will need to export a number of environment variables: 
+
+```bash
+export PDK_PATH=<pdk-location/sky130A>
+export CARAVEL_ROOT=<caravel_root>
+export UPRJ_ROOT=<user_project_root>
+```
+
+Then, run the following command to start the docker container :
+
+```
+docker run -it -v $CARAVEL_ROOT:$CARAVEL_ROOT -v $PDK_PATH:$PDK_PATH -v $UPRJ_ROOT:$UPRJ_ROOT -e CARAVEL_ROOT=$CARAVEL_ROOT -e PDK_PATH=$PDK_PATH -e UPRJ_ROOT=$UPRJ_ROOT -u $(id -u $USER):$(id -g $USER) efabless/dv_setup:latest
+```
+
+Then, navigate to the directory where the DV tests reside : 
+
+```bash
+cd $UPRJ_ROOT/verilog/dv/
+```
+
+Then, follow the instructions at [Both](#both) to run RTL/GL simulation.
+
+## Local
+
+You will need to export these environment variables: 
+
+```bash
+export GCC_PATH=<gcc-installation-path>
+export PDK_PATH=<pdk-location/sky130A>
+```
+
+Then, follow the instruction at [Both](#both) to run RTL/GL simulation.
+
+## Both
+
+To run RTL simulation for one of the DV tests, 
+
+```bash
+cd <dv-test>
+make
+```
+
+To run gate level simulation for one of the DV tests, 
+
+```bash
+cd <dv-test>
+SIM=GL make
+```
+
+# User Project Example DV
+
+The directory includes four tests for the counter user-project example: 
+
+### IO Ports Test 
+
+* This test is meant to verify that we can configure the pads for the user project area. The firmware configures the lower 8 IO pads in the user space as outputs:
+
+	```c
+	reg_mprj_io_0 =  GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_1 =  GPIO_MODE_USER_STD_OUTPUT;
+	.....
+	reg_mprj_io_7 =  GPIO_MODE_USER_STD_OUTPUT;
+	```
+
+* Then, the firmware applies the pad configuration by enabling the serial transfer on the shift register responsible for configuring the pads and waits until the transfer is done. 
+	```c
+	reg_mprj_xfer = 1;
+	while (reg_mprj_xfer == 1);
+	```
+
+* The testbench success criteria is that we can observe the counter value on the lower 8 I/O pads. This criteria is checked by the testbench through observing the values on the I/O pads as follows: 
+
+	```verilog
+	wait(mprj_io_0 == 8'h01);
+	wait(mprj_io_0 == 8'h02);
+	wait(mprj_io_0 == 8'h03);
+	....
+	wait(mprj_io_0 == 8'hFF);
+	```
+
+* If the testbench fails, it will print a timeout message to the terminal. 
+
+### Logic Analyzer Test 1
+ 
+* This test is meant to verify that we can use the logic analyzer to monitor and write signals in the user project from the management SoC. Firstly, the firmware configures the upper 16 of the first 32 GPIO pads as outputs from the managent SoC, applies the configuration by initiating the serial transfer on the shift register, and writes a value on the pads to indicate the end of pad configuration and the start of the test. 
+
+	```c
+	reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT;
+	reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT;
+	.....
+	reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT;
+
+	reg_mprj_xfer = 1;
+	while (reg_mprj_xfer == 1);
+
+	// Flag start of the test 
+	reg_mprj_datal = 0xAB400000;
+	```
+	
+	This is done to flag the start/success/end of the simulation by writing a certain value to the I/Os which is then checked by the testbench to know whether the test started/ended/succeeded. For example, the testbench checks on the value of the upper 16 of 32 I/Os, if it is equal to `16'hAB40`, then we know that the test started.  
+
+	```verilog
+	wait(checkbits == 16'hAB40);
+	$display("LA Test 1 started");
+	```
+	
+* Then, the firmware configures the logic analyzer (LA) probes `[31:0]` as inputs to the management SoC to monitor the counter value, and configure the logic analyzer probes `[63:32]` as outputs from the management SoC (inputs to the user_proj_example) to set the counter initial value. This is done by writing to the LA probes enable registers.   Note that the output enable is active low, while the input enable is active high.  Every channel can be configured for input, output, or both independently.
+
+ 
+	```c
+	reg_la0_oenb = reg_la0_iena = 0xFFFFFFFF;    // [31:0] inputs to mgmt_soc
+	reg_la1_oenb = reg_la1_iena = 0x00000000;    // [63:32] outputs from mgmt_soc
+	```
+
+* Then, the firmware writes an initial value to the counter through the LA1 data register. Afte writing the counter value, the LA probes are disabled to prevent the counter write signal from being always set to one. 
+
+	```c
+	reg_la1_data = 0x00000000;     // Write zero to count register
+	reg_la1_oenb  = reg_la1_iena = 0xFFFFFFFF;     // Disable probes
+	```
+
+* The firmware then waits until the count value exceeds 500 and flags the success of the test by writing `0xAB41` to pads 16 to 31.  The firmware reads the count value through the logic analyzer probes `[31:0]` 
+
+	```c
+	if (reg_la0_data > 0x1F4) {	     // Read current count value through LA
+		reg_mprj_datal = 0xAB410000; // Flag success of the test
+		break;
+	}
+	```
+  
+### Logic Analyzer Test 2
+ 
+* This test is meant to verify that we can drive the clock and reset signals for the user project example through the logic analyzer. In the [user_proj_example](verilog/rtl/user_proj_example.v) RTL, the clock can either be supplied from the `wb_clk_i` or from the logic analyzer through bit `[64]`. Similarly, the reset signal can be supplied from the `wb_rst_i` or through `LA[65]`.  The firmware configures the clk and reset LA probes as outputs from the management SoC by writing to the LA2 enable register. 
+
+	```c
+	reg_la2_oenb  = reg_la2_iena = 0xFFFFFFFC; 	// Configure LA[64] LA[65] as outputs from the cpu
+	```
+
+* Then, the firmware supplies both clock reset signals through LA2 data register. First, both are set to one. Then, reset is driven to zero and the clock is toggled for 6 clock cycles. 
+
+	```c
+	reg_la2_data = 0x00000003;	// Write one to LA[64] and LA[65]
+	for (i=0; i<11; i=i+1) {   	// Toggle clk & de-assert reset
+		clk = !clk;               	
+		reg_la2_data = 0x00000000 | clk;
+	}
+	```
+* The testbench success criteria is that the firmware reads a count value of five through the LA probes. 
+	```c
+	if (reg_la0_data == 0x05) {
+		reg_mprj_datal = 0xAB610000;   // FLag success of the test
+	}
+	```
+	
+### Wishbone Test
+
+* This test is meant to verify that we can read and write to the count register through the wishbone port. The firmware writes a value of `0x2710` to the count register, then reads back the count value after some time. The read and write transactions happen through the management SoC wishbone bus and are initiated by either writing or reading from the user project address on the wishbone bus. 
diff --git a/verilog/dv/agents/uart_agent.v b/verilog/dv/agents/uart_agent.v
new file mode 100644
index 0000000..72121e9
--- /dev/null
+++ b/verilog/dv/agents/uart_agent.v
@@ -0,0 +1,527 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+module uart_agent (
+	mclk,
+	txd,
+	rxd
+	);
+
+input	mclk;
+output	txd;
+
+input	rxd;
+
+event	uart_read_done, uart_write_done;
+event	error_detected,uart_parity_error, uart_stop_error1, uart_stop_error2;
+event 	uart_timeout_error;
+event	abort;
+
+reg [15:0] rx_count;
+reg [15:0] tx_count;
+reg [15:0] par_err_count;
+reg [15:0] stop_err1_cnt;
+reg [15:0] stop_err2_cnt;
+reg [15:0] timeout_err_cnt;
+reg [15:0] err_cnt;
+
+reg 	   txd, read, write;
+wire	   uart_rx_clk;
+reg	   uart_clk;
+reg	   stop_err_check;
+
+integer timeout_count;
+integer data_bit_number;
+reg [15:0] clk_count;
+reg        debug_mode;
+
+reg      error_ind; // 1 indicate error
+
+initial 
+begin
+	debug_mode = 1; // Keep in debug mode and enable display
+	txd = 1'b1;
+ 	uart_clk = 0;
+	clk_count = 0;
+	stop_err_check = 0;
+  error_ind = 0;
+end
+
+always @(posedge mclk)
+begin
+   if (clk_count == 'h0) begin
+      uart_clk  = ~uart_clk;
+      clk_count = control_setup.divisor;	
+   end else begin
+      clk_count = clk_count - 1;	
+   end
+end
+assign uart_rx_clk = uart_clk;
+
+always @(posedge mclk)
+begin
+	timeout_count = timeout_count + 1;
+	if (timeout_count == (control_setup.maxtime * 16))
+		-> abort;
+end
+
+always @uart_read_done
+    rx_count = rx_count + 1;
+
+always @uart_write_done
+    tx_count = tx_count + 1;
+
+always @uart_parity_error begin
+    error_ind = 1;
+    par_err_count = par_err_count + 1;
+end
+
+always @uart_stop_error1 begin
+    error_ind = 1;
+    stop_err1_cnt = stop_err1_cnt + 1;
+end
+
+always @uart_stop_error2 begin
+    error_ind = 1;
+    stop_err2_cnt = stop_err2_cnt + 1;
+end
+
+always @uart_timeout_error begin
+    error_ind = 1;
+    timeout_err_cnt = timeout_err_cnt + 1;
+end
+
+
+always @error_detected begin
+    error_ind = 1;
+    err_cnt = err_cnt + 1;
+end
+
+
+////////////////////////////////////////////////////////////////////////////////
+task uart_init;
+begin
+  read = 0;
+  write = 0;
+  tx_count = 0;
+  rx_count = 0;
+  stop_err_check = 0;
+  par_err_count = 0;
+  stop_err1_cnt = 0;
+  stop_err2_cnt = 0;
+  timeout_err_cnt = 0;
+  err_cnt = 0;
+  clk_count = 0;
+
+end 
+endtask 
+
+
+////////////////////////////////////////////////////////////////////////////////
+task read_char_chk;
+input 	expected_data;
+
+integer i;
+reg	[7:0] expected_data;
+reg 	[7:0] data;
+reg	parity;
+
+begin
+	data <= 8'h0;
+	parity <= 1;
+	timeout_count = 0;
+
+fork	
+   begin : loop_1
+        @(abort)
+	if(debug_mode)
+         $display ("%m: >>>>> Exceed time limit, uart no responce.\n");
+         ->uart_timeout_error;
+         disable loop_2;
+   end
+
+   begin : loop_2
+
+// start cycle
+	@(negedge rxd) 
+	 disable loop_1;
+	 read <= 1;
+
+// data cycle
+	@(posedge uart_rx_clk);
+	 for (i = 0; i < data_bit_number; i = i + 1)
+	  begin
+	    @(posedge uart_rx_clk)
+	    data[i] <=  rxd;
+	    parity <= parity ^ rxd;
+	  end		
+
+// parity cycle
+	if(control_setup.parity_en)
+	begin
+          @(posedge uart_rx_clk);
+	  if ((control_setup.even_odd_parity && (rxd == parity)) ||
+	     (!control_setup.even_odd_parity && (rxd != parity)))
+	     begin
+		   $display ("%m: >>>>>  Parity Error");	
+ 		-> error_detected;
+		-> uart_parity_error;
+	     end
+	end
+
+// stop cycle 1
+        @(posedge uart_rx_clk);	
+	  if (!rxd)
+	     begin
+		$display ("%m: >>>>>  Stop signal 1 Error");	
+ 		-> error_detected;
+		-> uart_stop_error1;
+	     end
+
+// stop cycle 2
+	if (control_setup.stop_bit_number)
+	begin
+	      @(posedge uart_rx_clk);	// stop cycle 2
+		if (!rxd)
+		  begin
+		    $display ("%m: >>>>>  Stop signal 2 Error");	
+ 		    -> error_detected;
+		    -> uart_stop_error2;
+		  end
+	end
+
+	read <= 0;
+	-> uart_read_done;
+
+	if (expected_data != data)
+	begin
+		$display ("%m: Error! Data return is %h, expecting %h", data, expected_data);
+		-> error_detected;
+	end
+	else begin
+	        if(debug_mode)
+		  $display ("%m: Data match  %h", expected_data);
+	end
+
+	if(debug_mode)
+	   $display ("%m:... Read Data from UART done cnt :%d...",rx_count +1);
+   end
+join
+
+end
+
+endtask
+
+////////////////////////////////////////////////////////////////////////////////
+task read_char2;
+output [7:0]	rxd_data;
+output          timeout; // 1-> timeout
+integer i;
+reg	[7:0] rxd_data;
+reg 	[7:0] data;
+reg	parity;
+
+begin
+	data <= 8'h0;
+	parity <= 1;
+	timeout_count = 0;
+	timeout = 0;
+
+   fork	
+   begin 
+        @(abort)
+         //$display (">>>>>  Exceed time limit, uart no responce.\n");
+         //->uart_timeout_error;
+	  timeout = 1;
+   end
+
+   begin
+
+// start cycle
+	@(negedge rxd) 
+	 read <= 1;
+
+// data cycle
+	@(posedge uart_rx_clk );
+	 for (i = 0; i < data_bit_number; i = i + 1)
+	  begin
+	    @(posedge uart_rx_clk)
+	    data[i] <=  rxd;
+	    parity <= parity ^ rxd;
+	  end		
+
+// parity cycle
+	if(control_setup.parity_en)
+	begin
+          @(posedge uart_rx_clk);
+	  if ((control_setup.even_odd_parity && (rxd == parity)) ||
+	     (!control_setup.even_odd_parity && (rxd != parity)))
+	     begin
+		$display (">>>>>  Parity Error");	
+ 		-> error_detected;
+		-> uart_parity_error;
+	     end
+	end
+
+// stop cycle 1
+        @(posedge uart_rx_clk);	
+	  if (!rxd)
+	     begin
+		$display (">>>>>  Stop signal 1 Error");	
+ 		-> error_detected;
+		-> uart_stop_error1;
+	     end
+
+// stop cycle 2
+	if (control_setup.stop_bit_number)
+	begin
+	      @(posedge uart_rx_clk);	// stop cycle 2
+		if (!rxd)
+		  begin
+		    $display (">>>>>  Stop signal 2 Error");	
+ 		    -> error_detected;
+		    -> uart_stop_error2;
+		  end
+	end
+
+	read <= 0;
+	-> uart_read_done;
+
+//      $display ("(%m) Received Data  %c", data);
+//	$display ("... Read Data from UART done cnt :%d...",rx_count +1);
+        $write ("%c",data);
+	rxd_data = data;
+   end
+   join_any
+   disable fork; //disable pending fork activity
+
+end
+
+endtask
+
+
+////////////////////////////////////////////////////////////////////////////////
+task read_char;
+output [7:0]	rxd_data;
+output          timeout; // 1-> timeout
+
+reg	[7:0] rxd_data;
+
+
+integer i;
+reg	[7:0] expected_data;
+reg 	[7:0] data;
+reg	parity;
+
+begin
+	data <= 8'h0;
+	parity <= 1;
+	timeout_count = 0;
+	timeout = 0;
+
+
+fork	
+   begin : loop_1
+        @(abort)
+	 if(debug_mode)
+             $display ("%m: >>>>> Exceed time limit, uart no responce.\n");
+	 timeout = 1;
+         ->uart_timeout_error;
+         disable loop_2;
+   end
+
+   begin : loop_2
+
+// start cycle
+	@(negedge rxd) 
+	 disable loop_1;
+	 read <= 1;
+
+// data cycle
+	@(posedge uart_rx_clk);
+	 for (i = 0; i < data_bit_number; i = i + 1)
+	  begin
+	    @(posedge uart_rx_clk)
+	    data[i] <=  rxd;
+	    parity <= parity ^ rxd;
+	  end		
+
+// parity cycle
+	if(control_setup.parity_en)
+	begin
+          @(posedge uart_rx_clk);
+	  if ((control_setup.even_odd_parity && (rxd == parity)) ||
+	     (!control_setup.even_odd_parity && (rxd != parity)))
+	     begin
+		$display ("%m: >>>>>  Parity Error");	
+ 		-> error_detected;
+		-> uart_parity_error;
+	     end
+	end
+
+// stop cycle 1
+        @(posedge uart_rx_clk);	
+	  if (!rxd)
+	     begin
+		$display ("%m: >>>>>  Stop signal 1 Error");	
+ 		-> error_detected;
+		-> uart_stop_error1;
+	     end
+
+// stop cycle 2
+	if (control_setup.stop_bit_number)
+	begin
+	      @(posedge uart_rx_clk);	// stop cycle 2
+		if (!rxd)
+		  begin
+		    $display ("%m: >>>>>  Stop signal 2 Error");	
+ 		    -> error_detected;
+		    -> uart_stop_error2;
+		  end
+	end
+
+	read <= 0;
+	-> uart_read_done;
+
+	rxd_data = data;
+
+
+	if(debug_mode) begin
+	   $display ("%m: Received Data %h", rxd_data);
+	   $display ("%m:... Read Data from UART done cnt :%d...",rx_count +1);
+        end
+   end
+join
+
+end
+
+endtask
+
+////////////////////////////////////////////////////////////////////////////////
+task write_char;
+input [7:0] data;
+
+integer i;
+reg parity;	// 0: odd parity, 1: even parity
+
+begin
+	parity <=  #1 1;
+
+// start cycle
+	@(posedge uart_clk)
+	 begin
+		txd <= #1 0;
+		write <= #1 1;
+	 end
+
+// data cycle
+	begin
+	   for (i = 0; i < data_bit_number; i = i + 1)
+	   begin
+		@(posedge uart_clk)
+		    txd <= #1 data[i];
+		parity <= parity ^ data[i];
+	   end
+	end
+
+// parity cycle
+	if (control_setup.parity_en)
+	begin
+		@(posedge uart_clk)
+			txd <= #1 
+//				control_setup.stick_parity ? ~control_setup.even_odd_parity : 
+				control_setup.even_odd_parity ? !parity : parity;
+	end
+
+// stop cycle 1
+	@(posedge uart_clk)
+		txd <= #1 stop_err_check ? 0 : 1;
+
+// stop cycle 2
+	@(posedge uart_clk);
+		txd <= #1 1;
+	if (data_bit_number == 5)
+		@(negedge uart_clk);
+	else if (control_setup.stop_bit_number)
+		@(posedge uart_clk);
+
+	write <= #1 0;
+	if(debug_mode)
+	   $display ("%m:... Write data %h to UART done cnt : %d ...\n", data,tx_count+1);
+        else
+	   $write ("%c",data);
+	-> uart_write_done;
+end
+endtask
+
+
+////////////////////////////////////////////////////////////////////////////////
+task control_setup;
+input	  [1:0] data_bit_set;	
+input		stop_bit_number;
+input		parity_en;
+input		even_odd_parity;
+input		stick_parity;
+input	 [15:0] maxtime;
+input	 [15:0] divisor;
+
+begin
+        clk_count = divisor;	
+	data_bit_number = data_bit_set + 5;
+end
+endtask
+
+
+////////////////////////////////////////////////////////////////////////////////
+task report_status;
+output 	[15:0] rx_nu;
+output 	[15:0] tx_nu;
+begin
+	$display ("-------------------- UART Reporting Configuration --------------------");
+	$display ("	Data bit number setting is : %0d", data_bit_number);
+	$display ("	Stop bit number setting is : %0d", control_setup.stop_bit_number + 1);
+	$display ("	Divisor of Uart clock   is : %0d", control_setup.divisor);
+	if (control_setup.parity_en) 
+	$display ("	Parity is enable");
+	else
+	$display ("	Parity is disable");
+	
+	if (control_setup.even_odd_parity)
+	$display ("	Even parity setting");
+	else	
+	$display ("	Odd parity setting");
+
+
+	$display ("-----------------------------------------------------------------");
+
+	$display ("-------------------- Reporting Status --------------------\n");
+	$display ("	Number of character received is : %d", rx_count);
+	$display ("	Number of character sent     is : %d", tx_count);
+	$display ("	Number of parity error rxd   is : %d", par_err_count);
+	$display ("	Number of stop1  error rxd   is : %d", stop_err1_cnt);
+	$display ("	Number of stop2  error rxd   is : %d", stop_err2_cnt);
+	$display ("	Number of timeout error      is : %d", timeout_err_cnt);
+	$display ("	Number of error              is : %d", err_cnt);
+	$display ("-----------------------------------------------------------------");
+
+	rx_nu = rx_count;
+	tx_nu = tx_count;
+end
+endtask
+
+
+////////////////////////////////////////////////////////////////////////////////
+endmodule
diff --git a/verilog/dv/agents/uart_master_tasks.sv b/verilog/dv/agents/uart_master_tasks.sv
new file mode 100644
index 0000000..f0a1a7d
--- /dev/null
+++ b/verilog/dv/agents/uart_master_tasks.sv
@@ -0,0 +1,201 @@
+
+task uartm_reg_write;
+input [31:0] addr;
+input [31:0] data;
+reg [7:0] read_data;
+reg flag;
+begin
+   fork
+   begin : loop_1
+       tb_master_uart.write_char("w");
+       tb_master_uart.write_char("m");
+       tb_master_uart.write_char(" ");
+       tb_master_uart.write_char(hex2char(addr[31:28]));
+       tb_master_uart.write_char(hex2char(addr[27:24]));
+       tb_master_uart.write_char(hex2char(addr[23:20]));
+       tb_master_uart.write_char(hex2char(addr[19:16]));
+       tb_master_uart.write_char(hex2char(addr[15:12]));
+       tb_master_uart.write_char(hex2char(addr[11:8]));
+       tb_master_uart.write_char(hex2char(addr[7:4]));
+       tb_master_uart.write_char(hex2char(addr[3:0]));
+       tb_master_uart.write_char(" ");
+       tb_master_uart.write_char(hex2char(data[31:28]));
+       tb_master_uart.write_char(hex2char(data[27:24]));
+       tb_master_uart.write_char(hex2char(data[23:20]));
+       tb_master_uart.write_char(hex2char(data[19:16]));
+       tb_master_uart.write_char(hex2char(data[15:12]));
+       tb_master_uart.write_char(hex2char(data[11:8]));
+       tb_master_uart.write_char(hex2char(data[7:4]));
+       tb_master_uart.write_char(hex2char(data[3:0]));
+       tb_master_uart.write_char("\n");
+   end
+   begin : loop_2
+       // Wait for sucess command
+       flag = 0;
+       while(flag == 0)
+       begin
+          tb_master_uart.read_char2(read_data,flag);
+          //$write ("%c",read_data);
+       end
+   end
+   join
+end
+endtask
+
+task uartm_reg_read;
+input [31:0] addr;
+output [31:0] data;
+reg [7:0] read_data;
+reg flag;
+integer i;
+begin
+   fork
+   begin : loop_1
+      tb_master_uart.write_char("r");
+      tb_master_uart.write_char("m");
+      tb_master_uart.write_char(" ");
+      tb_master_uart.write_char(hex2char(addr[31:28]));
+      tb_master_uart.write_char(hex2char(addr[27:24]));
+      tb_master_uart.write_char(hex2char(addr[23:20]));
+      tb_master_uart.write_char(hex2char(addr[19:16]));
+      tb_master_uart.write_char(hex2char(addr[15:12]));
+      tb_master_uart.write_char(hex2char(addr[11:8]));
+      tb_master_uart.write_char(hex2char(addr[7:4]));
+      tb_master_uart.write_char(hex2char(addr[3:0]));
+      tb_master_uart.write_char("\n");
+   end
+   begin : loop_2
+      // Wait for sucess command
+      flag = 0;
+      i = 0;
+      while(flag == 0)
+      begin
+         tb_master_uart.read_char2(read_data,flag);
+         //$write ("%d:%c",i,read_data);
+           case (i)
+           8'd10 : data[31:28] = char2hex(read_data);
+           8'd11 : data[27:24] = char2hex(read_data);
+           8'd12 : data[23:20] = char2hex(read_data);
+           8'd13 : data[19:16] = char2hex(read_data);
+           8'd14 : data[15:12] = char2hex(read_data);
+           8'd15 : data[11:8]  = char2hex(read_data);
+           8'd16 : data[7:4]   = char2hex(read_data);
+           8'd17 : data[3:0]   = char2hex(read_data);
+           endcase
+	   i = i+1;
+      end
+   end
+   join
+   $display("received Data: %x",data);
+
+end
+endtask
+
+task uartm_reg_read_check;
+input [31:0] addr;
+input [31:0] exp_data;
+reg [31:0] rxd_data;
+reg [7:0] read_data;
+reg flag;
+integer i;
+begin
+   fork
+   begin : loop_1
+      tb_master_uart.write_char("r");
+      tb_master_uart.write_char("m");
+      tb_master_uart.write_char(" ");
+      tb_master_uart.write_char(hex2char(addr[31:28]));
+      tb_master_uart.write_char(hex2char(addr[27:24]));
+      tb_master_uart.write_char(hex2char(addr[23:20]));
+      tb_master_uart.write_char(hex2char(addr[19:16]));
+      tb_master_uart.write_char(hex2char(addr[15:12]));
+      tb_master_uart.write_char(hex2char(addr[11:8]));
+      tb_master_uart.write_char(hex2char(addr[7:4]));
+      tb_master_uart.write_char(hex2char(addr[3:0]));
+      tb_master_uart.write_char("\n");
+   end
+   begin : loop_2
+      // Wait for sucess command
+      flag = 0;
+      i = 0;
+      while(flag == 0)
+      begin
+         tb_master_uart.read_char2(read_data,flag);
+         //$write ("%d:%c",i,read_data);
+           case (i)
+           8'd10 : rxd_data[31:28] = char2hex(read_data);
+           8'd11 : rxd_data[27:24] = char2hex(read_data);
+           8'd12 : rxd_data[23:20] = char2hex(read_data);
+           8'd13 : rxd_data[19:16] = char2hex(read_data);
+           8'd14 : rxd_data[15:12] = char2hex(read_data);
+           8'd15 : rxd_data[11:8]  = char2hex(read_data);
+           8'd16 : rxd_data[7:4]   = char2hex(read_data);
+           8'd17 : rxd_data[3:0]   = char2hex(read_data);
+           endcase
+	   i = i+1;
+      end
+   end
+   join
+   if(rxd_data == exp_data) begin
+      // $display("STATUS: ADDRESS: %x RXD: %x", addr,rxd_data);
+   end else begin
+      $display("ERROR:  ADDRESS: %x EXP: %x RXD: %x", addr,exp_data,rxd_data);
+      test_fail = 1;
+   end
+
+
+end
+endtask
+
+// Character to hex number
+function [3:0] char2hex;
+input [7:0] data_in;
+case (data_in)
+     8'h30:	char2hex = 4'h0; // character '0' 
+     8'h31:	char2hex = 4'h1; // character '1'
+     8'h32:	char2hex = 4'h2; // character '2'
+     8'h33:	char2hex = 4'h3; // character '3'
+     8'h34:	char2hex = 4'h4; // character '4' 
+     8'h35:	char2hex = 4'h5; // character '5'
+     8'h36:	char2hex = 4'h6; // character '6'
+     8'h37:	char2hex = 4'h7; // character '7'
+     8'h38:	char2hex = 4'h8; // character '8'
+     8'h39:	char2hex = 4'h9; // character '9'
+     8'h41:	char2hex = 4'hA; // character 'A'
+     8'h42:	char2hex = 4'hB; // character 'B'
+     8'h43:	char2hex = 4'hC; // character 'C'
+     8'h44:	char2hex = 4'hD; // character 'D'
+     8'h45:	char2hex = 4'hE; // character 'E'
+     8'h46:	char2hex = 4'hF; // character 'F'
+     8'h61:	char2hex = 4'hA; // character 'a'
+     8'h62:	char2hex = 4'hB; // character 'b'
+     8'h63:	char2hex = 4'hC; // character 'c'
+     8'h64:	char2hex = 4'hD; // character 'd'
+     8'h65:	char2hex = 4'hE; // character 'e'
+     8'h66:	char2hex = 4'hF; // character 'f'
+      default :  char2hex = 4'hF;
+   endcase 
+endfunction
+
+// Hex to Asci Character 
+function [7:0] hex2char;
+input [3:0] data_in;
+case (data_in)
+     4'h0:	hex2char = 8'h30; // character '0' 
+     4'h1:	hex2char = 8'h31; // character '1'
+     4'h2:	hex2char = 8'h32; // character '2'
+     4'h3:	hex2char = 8'h33; // character '3'
+     4'h4:	hex2char = 8'h34; // character '4' 
+     4'h5:	hex2char = 8'h35; // character '5'
+     4'h6:	hex2char = 8'h36; // character '6'
+     4'h7:	hex2char = 8'h37; // character '7'
+     4'h8:	hex2char = 8'h38; // character '8'
+     4'h9:	hex2char = 8'h39; // character '9'
+     4'hA:	hex2char = 8'h41; // character 'A'
+     4'hB:	hex2char = 8'h42; // character 'B'
+     4'hC:	hex2char = 8'h43; // character 'C'
+     4'hD:	hex2char = 8'h44; // character 'D'
+     4'hE:	hex2char = 8'h45; // character 'E'
+     4'hF:	hex2char = 8'h46; // character 'F'
+   endcase 
+endfunction
diff --git a/verilog/dv/firmware/LICENSE b/verilog/dv/firmware/LICENSE
new file mode 100644
index 0000000..48fe522
--- /dev/null
+++ b/verilog/dv/firmware/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/dv/firmware/common.mk b/verilog/dv/firmware/common.mk
new file mode 100644
index 0000000..402d346
--- /dev/null
+++ b/verilog/dv/firmware/common.mk
@@ -0,0 +1,66 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# // 
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# //      http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+
+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_ROM_OBJCOPY) $^ $@
+	$(RISCV_RAM_OBJCOPY) $^ $@.ram
+	#assign 0x0800_0xxx  to 0x0000_0xxx to map to TCM Memory
+	sed -i 's/@08000/@00000/g' $@.ram
+
+
+$(bld_dir)/%.dump: $(bld_dir)/%.elf
+	$(RISCV_OBJDUMP) $^ > $@
diff --git a/verilog/dv/firmware/crt.S b/verilog/dv/firmware/crt.S
new file mode 100644
index 0000000..d50cb6b
--- /dev/null
+++ b/verilog/dv/firmware/crt.S
@@ -0,0 +1,160 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya                           ////
+//                                                                        ////
+// Licensed under the Apache License, Version 2.0 (the "License");        ////
+// you may not use this file except in compliance with the License.       ////
+// You may obtain a copy of the License at                                ////
+//                                                                        ////
+//      http://www.apache.org/licenses/LICENSE-2.0                        ////
+//                                                                        ////
+// Unless required by applicable law or agreed to in writing, software    ////
+// distributed under the License is distributed on an "AS IS" BASIS,      ////
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.///
+// See the License for the specific language governing permissions and    ////
+// limitations under the License.                                         ////
+// SPDX-License-Identifier: Apache-2.0                                    ////
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>           ////
+//////////////////////////////////////////////////////////////////////////////
+
+#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 << YCR1_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
diff --git a/verilog/dv/firmware/crt_tcm.S b/verilog/dv/firmware/crt_tcm.S
new file mode 100644
index 0000000..f1bcb65
--- /dev/null
+++ b/verilog/dv/firmware/crt_tcm.S
@@ -0,0 +1,171 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya                           ////
+//                                                                        ////
+// Licensed under the Apache License, Version 2.0 (the "License");        ////
+// you may not use this file except in compliance with the License.       ////
+// You may obtain a copy of the License at                                ////
+//                                                                        ////
+//      http://www.apache.org/licenses/LICENSE-2.0                        ////
+//                                                                        ////
+// Unless required by applicable law or agreed to in writing, software    ////
+// distributed under the License is distributed on an "AS IS" BASIS,      ////
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.///
+// See the License for the specific language governing permissions and    ////
+// limitations under the License.                                         ////
+// SPDX-License-Identifier: Apache-2.0                                    ////
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>           ////
+//////////////////////////////////////////////////////////////////////////////
+
+#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 << YCR1_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
diff --git a/verilog/dv/firmware/csr.h b/verilog/dv/firmware/csr.h
new file mode 100644
index 0000000..976f1fc
--- /dev/null
+++ b/verilog/dv/firmware/csr.h
@@ -0,0 +1,128 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya                           ////
+//                                                                        ////
+// Licensed under the Apache License, Version 2.0 (the "License");        ////
+// you may not use this file except in compliance with the License.       ////
+// You may obtain a copy of the License at                                ////
+//                                                                        ////
+//      http://www.apache.org/licenses/LICENSE-2.0                        ////
+//                                                                        ////
+// Unless required by applicable law or agreed to in writing, software    ////
+// distributed under the License is distributed on an "AS IS" BASIS,      ////
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.///
+// See the License for the specific language governing permissions and    ////
+// limitations under the License.                                         ////
+// SPDX-License-Identifier: Apache-2.0                                    ////
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>           ////
+//////////////////////////////////////////////////////////////////////////////
+/// Architecture specific CSR's defs and inlines
+
+#ifndef YCR_CSR_H
+#define YCR_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 // YCR_CSR_H
diff --git a/verilog/dv/firmware/link.ld b/verilog/dv/firmware/link.ld
new file mode 100644
index 0000000..222363d
--- /dev/null
+++ b/verilog/dv/firmware/link.ld
@@ -0,0 +1,118 @@
+/*
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya                           ////
+//                                                                        ////
+// Licensed under the Apache License, Version 2.0 (the "License");        ////
+// you may not use this file except in compliance with the License.       ////
+// You may obtain a copy of the License at                                ////
+//                                                                        ////
+//      http://www.apache.org/licenses/LICENSE-2.0                        ////
+//                                                                        ////
+// Unless required by applicable law or agreed to in writing, software    ////
+// distributed under the License is distributed on an "AS IS" BASIS,      ////
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.///
+// See the License for the specific language governing permissions and    ////
+// limitations under the License.                                         ////
+// SPDX-License-Identifier: Apache-2.0                                    ////
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>           ////
+//////////////////////////////////////////////////////////////////////////////
+**/
+/*
+* @brief      bare metal tests' linker script
+*/
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+MEMORY {
+  ROM (rxx) : ORIGIN = 0x0, LENGTH = 64K
+  RAM (rwx) : ORIGIN = 0x08000000, LENGTH = 64K
+  TCM (rwx) : ORIGIN = 0x0C480000, LENGTH = 2K
+}
+
+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) 
+  } >ROM
+
+  .text  : {
+    *crt.o(.text .text.*)
+    *(.text .text.*)
+    *(sc_test_section)
+    . = ALIGN(CL_SIZE);
+     PROVIDE(__TEXT_END__ = .);
+  } >ROM
+
+  /* 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(TCM) + LENGTH(TCM) - STACK_SIZE : {
+    FILL(0);
+    PROVIDE(__STACK_START__ = .);
+    . += STACK_SIZE;
+    PROVIDE(__C_STACK_TOP__ = .);
+    PROVIDE(__STACK_END__ = .);
+  } >TCM
+
+  /DISCARD/ : {
+    *(.eh_frame .eh_frame.*)
+  }
+}
diff --git a/verilog/dv/firmware/link_tcm.ld b/verilog/dv/firmware/link_tcm.ld
new file mode 100644
index 0000000..6b09881
--- /dev/null
+++ b/verilog/dv/firmware/link_tcm.ld
@@ -0,0 +1,131 @@
+/**
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya                           ////
+//                                                                        ////
+// Licensed under the Apache License, Version 2.0 (the "License");        ////
+// you may not use this file except in compliance with the License.       ////
+// You may obtain a copy of the License at                                ////
+//                                                                        ////
+//      http://www.apache.org/licenses/LICENSE-2.0                        ////
+//                                                                        ////
+// Unless required by applicable law or agreed to in writing, software    ////
+// distributed under the License is distributed on an "AS IS" BASIS,      ////
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.///
+// See the License for the specific language governing permissions and    ////
+// limitations under the License.                                         ////
+// SPDX-License-Identifier: Apache-2.0                                    ////
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>           ////
+//////////////////////////////////////////////////////////////////////////////
+*/
+/*
+* @brief      bare metal tests' linker script
+*/
+
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+MEMORY {
+  ROM (rxx) : ORIGIN = 0x0, LENGTH = 64K
+  TCM (rwx) : ORIGIN = 0x00480000, LENGTH = 4K
+}
+
+STACK_SIZE = 256;
+
+CL_SIZE = 32;
+
+SECTIONS {
+
+  /* code segment */
+  .text.init ORIGIN(ROM) : { 
+    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);
+  } >ROM
+
+  __reloc_start = .;
+
+  .text : {
+    PROVIDE(__TEXT_START__ = .);
+    *(.text .text.*)
+    *(sc_test_section)
+    . = ALIGN(CL_SIZE);
+     PROVIDE(__TEXT_END__ = .);
+  } >TCM AT>ROM
+
+
+  .rodata ALIGN(CL_SIZE) : {
+    __global_pointer$ = . + 0x800;
+    *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*)
+    . = ALIGN(CL_SIZE);
+    LONG(0x13);
+    . = ALIGN(CL_SIZE);
+  } >TCM AT>ROM
+
+
+  /* data segment */
+  .data ALIGN(CL_SIZE) : {
+    PROVIDE(__DATA_START__ = .);
+    *(.data .data.*)
+    . = ALIGN(CL_SIZE);
+  } >TCM 
+  
+  .sdata ALIGN(CL_SIZE) : {
+    *(.sdata .sdata.* .gnu.linkonce.s.*)
+    . = ALIGN(CL_SIZE);
+    PROVIDE(__DATA_END__ = .);
+  } >TCM
+
+  /* thread-local data segment */
+  .tdata ALIGN(CL_SIZE) : {
+    PROVIDE(_tls_data = .);
+    PROVIDE(_tdata_begin = .);
+    *(.tdata .tdata.*)
+    PROVIDE(_tdata_end = .);
+    . = ALIGN(CL_SIZE);
+  } >TCM
+
+  .tbss ALIGN(CL_SIZE) : {
+    PROVIDE(_tbss_begin = .);
+    *(.tbss .tbss.*)
+    . = ALIGN(CL_SIZE);
+    PROVIDE(_tbss_end = .);
+  } >TCM
+
+  /* bss segment */
+  .sbss ALIGN(CL_SIZE) : {
+    PROVIDE(__BSS_START__ = .);
+    *(.sbss .sbss.* .gnu.linkonce.sb.*)
+    *(.scommon)
+    . = ALIGN(CL_SIZE);
+  } >TCM
+
+  .bss ALIGN(CL_SIZE) : {
+    *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON)
+    . = ALIGN(CL_SIZE);
+    PROVIDE(__BSS_END__ = .);
+  } >TCM
+
+  _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/dv/firmware/reloc.h b/verilog/dv/firmware/reloc.h
new file mode 100644
index 0000000..b78167e
--- /dev/null
+++ b/verilog/dv/firmware/reloc.h
@@ -0,0 +1,56 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya                           ////
+//                                                                        ////
+// Licensed under the Apache License, Version 2.0 (the "License");        ////
+// you may not use this file except in compliance with the License.       ////
+// You may obtain a copy of the License at                                ////
+//                                                                        ////
+//      http://www.apache.org/licenses/LICENSE-2.0                        ////
+//                                                                        ////
+// Unless required by applicable law or agreed to in writing, software    ////
+// distributed under the License is distributed on an "AS IS" BASIS,      ////
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.///
+// See the License for the specific language governing permissions and    ////
+// limitations under the License.                                         ////
+// SPDX-License-Identifier: Apache-2.0                                    ////
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>           ////
+//////////////////////////////////////////////////////////////////////////////
+
+
+#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  // 
diff --git a/verilog/dv/firmware/riscv_csr_encoding.h b/verilog/dv/firmware/riscv_csr_encoding.h
new file mode 100644
index 0000000..09f5abb
--- /dev/null
+++ b/verilog/dv/firmware/riscv_csr_encoding.h
@@ -0,0 +1,1489 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya                           ////
+//                                                                        ////
+// Licensed under the Apache License, Version 2.0 (the "License");        ////
+// you may not use this file except in compliance with the License.       ////
+// You may obtain a copy of the License at                                ////
+//                                                                        ////
+//      http://www.apache.org/licenses/LICENSE-2.0                        ////
+//                                                                        ////
+// Unless required by applicable law or agreed to in writing, software    ////
+// distributed under the License is distributed on an "AS IS" BASIS,      ////
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.///
+// See the License for the specific language governing permissions and    ////
+// limitations under the License.                                         ////
+// SPDX-License-Identifier: Apache-2.0                                    ////
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>           ////
+//////////////////////////////////////////////////////////////////////////////
+
+#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 "ycr1_specific.h"
diff --git a/verilog/dv/firmware/riscv_macros.h b/verilog/dv/firmware/riscv_macros.h
new file mode 100644
index 0000000..d4fc8cb
--- /dev/null
+++ b/verilog/dv/firmware/riscv_macros.h
@@ -0,0 +1,835 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya                           ////
+//                                                                        ////
+// Licensed under the Apache License, Version 2.0 (the "License");        ////
+// you may not use this file except in compliance with the License.       ////
+// You may obtain a copy of the License at                                ////
+//                                                                        ////
+//      http://www.apache.org/licenses/LICENSE-2.0                        ////
+//                                                                        ////
+// Unless required by applicable law or agreed to in writing, software    ////
+// distributed under the License is distributed on an "AS IS" BASIS,      ////
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.///
+// See the License for the specific language governing permissions and    ////
+// limitations under the License.                                         ////
+// SPDX-License-Identifier: Apache-2.0                                    ////
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>           ////
+//////////////////////////////////////////////////////////////////////////////
+
+#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/dv/firmware/sc_print.c b/verilog/dv/firmware/sc_print.c
new file mode 100644
index 0000000..b736d42
--- /dev/null
+++ b/verilog/dv/firmware/sc_print.c
@@ -0,0 +1,296 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya                           ////
+//                                                                        ////
+// Licensed under the Apache License, Version 2.0 (the "License");        ////
+// you may not use this file except in compliance with the License.       ////
+// You may obtain a copy of the License at                                ////
+//                                                                        ////
+//      http://www.apache.org/licenses/LICENSE-2.0                        ////
+//                                                                        ////
+// Unless required by applicable law or agreed to in writing, software    ////
+// distributed under the License is distributed on an "AS IS" BASIS,      ////
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.///
+// See the License for the specific language governing permissions and    ////
+// limitations under the License.                                         ////
+// SPDX-License-Identifier: Apache-2.0                                    ////
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>           ////
+//////////////////////////////////////////////////////////////////////////////
+
+#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/dv/firmware/sc_print.h b/verilog/dv/firmware/sc_print.h
new file mode 100644
index 0000000..fad6b61
--- /dev/null
+++ b/verilog/dv/firmware/sc_print.h
@@ -0,0 +1,24 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya                           ////
+//                                                                        ////
+// Licensed under the Apache License, Version 2.0 (the "License");        ////
+// you may not use this file except in compliance with the License.       ////
+// You may obtain a copy of the License at                                ////
+//                                                                        ////
+//      http://www.apache.org/licenses/LICENSE-2.0                        ////
+//                                                                        ////
+// Unless required by applicable law or agreed to in writing, software    ////
+// distributed under the License is distributed on an "AS IS" BASIS,      ////
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.///
+// See the License for the specific language governing permissions and    ////
+// limitations under the License.                                         ////
+// SPDX-License-Identifier: Apache-2.0                                    ////
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>           ////
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef SC_PRINT_H
+#define SC_PRINT_H
+
+extern int sc_printf(const char* fmt, ...);
+
+#endif // SC_PRINT_H
diff --git a/verilog/dv/firmware/sc_test.h b/verilog/dv/firmware/sc_test.h
new file mode 100644
index 0000000..6b6448a
--- /dev/null
+++ b/verilog/dv/firmware/sc_test.h
@@ -0,0 +1,62 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya                           ////
+//                                                                        ////
+// Licensed under the Apache License, Version 2.0 (the "License");        ////
+// you may not use this file except in compliance with the License.       ////
+// You may obtain a copy of the License at                                ////
+//                                                                        ////
+//      http://www.apache.org/licenses/LICENSE-2.0                        ////
+//                                                                        ////
+// Unless required by applicable law or agreed to in writing, software    ////
+// distributed under the License is distributed on an "AS IS" BASIS,      ////
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.///
+// See the License for the specific language governing permissions and    ////
+// limitations under the License.                                         ////
+// SPDX-License-Identifier: Apache-2.0                                    ////
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>           ////
+//////////////////////////////////////////////////////////////////////////////
+
+#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/dv/firmware/ycr1_specific.h b/verilog/dv/firmware/ycr1_specific.h
new file mode 100644
index 0000000..4c8c583
--- /dev/null
+++ b/verilog/dv/firmware/ycr1_specific.h
@@ -0,0 +1,38 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya                           ////
+//                                                                        ////
+// Licensed under the Apache License, Version 2.0 (the "License");        ////
+// you may not use this file except in compliance with the License.       ////
+// You may obtain a copy of the License at                                ////
+//                                                                        ////
+//      http://www.apache.org/licenses/LICENSE-2.0                        ////
+//                                                                        ////
+// Unless required by applicable law or agreed to in writing, software    ////
+// distributed under the License is distributed on an "AS IS" BASIS,      ////
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.///
+// See the License for the specific language governing permissions and    ////
+// limitations under the License.                                         ////
+// SPDX-License-Identifier: Apache-2.0                                    ////
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>           ////
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef __YCR1__SPECIFIC
+#define __YCR1__SPECIFIC
+
+#define mcounten        0x7E0
+
+// Memory-mapped registers
+#define mtime_ctrl      0x0C490000
+#define mtime_div       0x0C490004
+#define mtime           0x0C490008
+#define mtimeh          0x0C49000C
+#define mtimecmp        0x0C490010
+#define mtimecmph       0x0C490014
+
+#define YCR1_MTIME_CTRL_EN          0
+#define YCR1_MTIME_CTRL_CLKSRC      1
+
+#define YCR1_MTIME_CTRL_WR_MASK     0x3
+#define YCR1_MTIME_DIV_WR_MASK      0x3FF
+
+#endif // _YCR1__SPECIFIC
diff --git a/verilog/dv/model/i2c_slave_model.v b/verilog/dv/model/i2c_slave_model.v
new file mode 100755
index 0000000..83b8f8b
--- /dev/null
+++ b/verilog/dv/model/i2c_slave_model.v
@@ -0,0 +1,373 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Richard Herveille
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+/////////////////////////////////////////////////////////////////////
+////                                                             ////
+////  WISHBONE rev.B2 compliant synthesizable I2C Slave model    ////
+////                                                             ////
+////                                                             ////
+////  Authors: Richard Herveille (richard@asics.ws) www.asics.ws ////
+////           John Sheahan (jrsheahan@optushome.com.au)         ////
+////                                                             ////
+////  Downloaded from: http://www.opencores.org/projects/i2c/    ////
+////                                                             ////
+/////////////////////////////////////////////////////////////////////
+////                                                             ////
+//// Copyright (C) 2001,2002 Richard Herveille                   ////
+////                         richard@asics.ws                    ////
+////                                                             ////
+//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
+//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
+//// POSSIBILITY OF SUCH DAMAGE.                                 ////
+////                                                             ////
+/////////////////////////////////////////////////////////////////////
+
+//  CVS Log
+//
+//  $Id: i2c_slave_model.v,v 1.7 2006-09-04 09:08:51 rherveille Exp $
+//
+//  $Date: 2006-09-04 09:08:51 $
+//  $Revision: 1.7 $
+//  $Author: rherveille $
+//  $Locker:  $
+//  $State: Exp $
+//
+// Change History:
+//               $Log: not supported by cvs2svn $
+//               Revision 1.6  2005/02/28 11:33:48  rherveille
+//               Fixed Tsu:sta timing check.
+//               Added Thd:sta timing check.
+//
+//               Revision 1.5  2003/12/05 11:05:19  rherveille
+//               Fixed slave address MSB='1' bug
+//
+//               Revision 1.4  2003/09/11 08:25:37  rherveille
+//               Fixed a bug in the timing section. Changed 'tst_scl' into 'tst_sto'.
+//
+//               Revision 1.3  2002/10/30 18:11:06  rherveille
+//               Added timing tests to i2c_model.
+//               Updated testbench.
+//
+//               Revision 1.2  2002/03/17 10:26:38  rherveille
+//               Fixed some race conditions in the i2c-slave model.
+//               Added debug information.
+//               Added headers.
+//
+
+
+module i2c_slave_model (scl, sda);
+
+	//
+	// parameters
+	//
+	parameter I2C_ADR = 7'b001_0000;
+
+	//
+	// input && outpus
+	//
+	input scl;
+	inout sda;
+
+	//
+	// Variable declaration
+	//
+	wire debug = 1'b1;
+
+	reg [7:0] mem [255:0]; // initiate memory
+	reg [7:0] mem_adr;   // memory address
+	reg [7:0] mem_do;    // memory data output
+
+	reg sta, d_sta;
+	reg sto, d_sto;
+
+	reg [7:0] sr;        // 8bit shift register
+	reg       rw;        // read/write direction
+
+	wire      my_adr;    // my address called ??
+	wire      i2c_reset; // i2c-statemachine reset
+	reg [2:0] bit_cnt;   // 3bit downcounter
+	wire      acc_done;  // 8bits transfered
+	reg       ld;        // load downcounter
+
+	reg       sda_o;     // sda-drive level
+	wire      sda_dly;   // delayed version of sda
+
+	// statemachine declaration
+	parameter idle        = 3'b000;
+	parameter slave_ack   = 3'b001;
+	parameter get_mem_adr = 3'b010;
+	parameter gma_ack     = 3'b011;
+	parameter data        = 3'b100;
+	parameter data_ack    = 3'b101;
+
+	reg [2:0] state; // synopsys enum_state
+
+	//
+	// module body
+	//
+
+	initial
+	begin
+	   sda_o = 1'b1;
+	   state = idle;
+	end
+
+	// generate shift register
+	always @(posedge scl)
+	  sr <= #1 {sr[6:0],sda};
+
+	//detect my_address
+	assign my_adr = (sr[7:1] == I2C_ADR);
+	// FIXME: This should not be a generic assign, but rather
+	// qualified on address transfer phase and probably reset by stop
+
+	//generate bit-counter
+	always @(posedge scl)
+	  if(ld)
+	    bit_cnt <= #1 3'b111;
+	  else
+	    bit_cnt <= #1 bit_cnt - 3'h1;
+
+	//generate access done signal
+	assign acc_done = !(|bit_cnt);
+
+	// generate delayed version of sda
+	// this model assumes a hold time for sda after the falling edge of scl.
+	// According to the Phillips i2c spec, there s/b a 0 ns hold time for sda
+	// with regards to scl. If the data changes coincident with the clock, the
+	// acknowledge is missed
+	// Fix by Michael Sosnoski
+	assign #1 sda_dly = sda;
+
+
+	//detect start condition
+	always @(negedge sda)
+	  if(scl)
+	    begin
+	        sta   <= #1 1'b1;
+		d_sta <= #1 1'b0;
+		sto   <= #1 1'b0;
+
+	        if(debug)
+	          $display("DEBUG i2c_slave; start condition detected at %t", $time);
+	    end
+	  else
+	    sta <= #1 1'b0;
+
+	always @(posedge scl)
+	  d_sta <= #1 sta;
+
+	// detect stop condition
+	always @(posedge sda)
+	  if(scl)
+	    begin
+	       sta <= #1 1'b0;
+	       sto <= #1 1'b1;
+
+	       if(debug)
+	         $display("DEBUG i2c_slave; stop condition detected at %t", $time);
+	    end
+	  else
+	    sto <= #1 1'b0;
+
+	//generate i2c_reset signal
+	assign i2c_reset = sta || sto;
+
+	// generate statemachine
+	always @(negedge scl or posedge sto)
+	  if (sto || (sta && !d_sta) )
+	    begin
+	        state <= #1 idle; // reset statemachine
+
+	        sda_o <= #1 1'b1;
+	        ld    <= #1 1'b1;
+	    end
+	  else
+	    begin
+	        // initial settings
+	        sda_o <= #1 1'b1;
+	        ld    <= #1 1'b0;
+
+	        case(state) // synopsys full_case parallel_case
+	            idle: // idle state
+	              if (acc_done && my_adr)
+	                begin
+	                    state <= #1 slave_ack;
+	                    rw <= #1 sr[0];
+	                    sda_o <= #1 1'b0; // generate i2c_ack
+
+	                    #2;
+	                    if(debug && rw)
+	                      $display("DEBUG i2c_slave; command byte received (read) at %t", $time);
+	                    if(debug && !rw)
+	                      $display("DEBUG i2c_slave; command byte received (write) at %t", $time);
+
+	                    if(rw)
+	                      begin
+	                          mem_do <= #1 mem[mem_adr];
+
+	                          if(debug)
+	                            begin
+	                                #2 $display("DEBUG i2c_slave; data block read %x from address %x (1)", mem_do, mem_adr);
+	                                #2 $display("DEBUG i2c_slave; memcheck [%x]=%x", mem_adr, mem[mem_adr]);
+	                            end
+	                      end
+	                end
+
+	            slave_ack:
+	              begin
+	                  if(rw)
+	                    begin
+	                        state <= #1 data;
+	                        sda_o <= #1 mem_do[7];
+	                    end
+	                  else
+	                    state <= #1 get_mem_adr;
+
+	                  ld    <= #1 1'b1;
+	              end
+
+	            get_mem_adr: // wait for memory address
+	              if(acc_done)
+	                begin
+	                    state <= #1 gma_ack;
+	                    mem_adr <= #1 sr; // store memory address
+	                    sda_o <= #1 !(sr <= 255); // generate i2c_ack, for valid address
+
+	                    if(debug)
+	                      #1 $display("DEBUG i2c_slave; address received. adr=%x, ack=%b", sr, sda_o);
+	                end
+
+	            gma_ack:
+	              begin
+	                  state <= #1 data;
+	                  ld    <= #1 1'b1;
+	              end
+
+	            data: // receive or drive data
+	              begin
+	                  if(rw)
+	                    sda_o <= #1 mem_do[7];
+
+	                  if(acc_done)
+	                    begin
+	                        state <= #1 data_ack;
+	                        mem_adr <= #2 mem_adr + 8'h1;
+	                        sda_o <= #1 (rw && (mem_adr <= 255) ); // send ack on write, receive ack on read
+
+	                        if(rw)
+	                          begin
+	                              #3 mem_do <= mem[mem_adr];
+
+	                              if(debug)
+	                                #5 $display("DEBUG i2c_slave; data block read %x from address %x (2)", mem_do, mem_adr);
+	                          end
+
+	                        if(!rw)
+	                          begin
+	                              mem[ mem_adr ] <= #1 sr; // store data in memory
+
+	                              if(debug)
+	                                #2 $display("DEBUG i2c_slave; data block write %x to address %x", sr, mem_adr);
+	                          end
+	                    end
+	              end
+
+	            data_ack:
+	              begin
+	                  ld <= #1 1'b1;
+
+	                  if(rw)
+	                    if(sr[0]) // read operation && master send NACK
+	                      begin
+	                          state <= #1 idle;
+	                          sda_o <= #1 1'b1;
+	                      end
+	                    else
+	                      begin
+	                          state <= #1 data;
+	                          sda_o <= #1 mem_do[7];
+	                      end
+	                  else
+	                    begin
+	                        state <= #1 data;
+	                        sda_o <= #1 1'b1;
+	                    end
+	              end
+
+	        endcase
+	    end
+
+	// read data from memory
+	always @(posedge scl)
+	  if(!acc_done && rw)
+	    mem_do <= #1 {mem_do[6:0], 1'b1}; // insert 1'b1 for host ack generation
+
+	// generate tri-states
+	assign sda = sda_o ? 1'bz : 1'b0;
+
+
+	//
+	// Timing checks
+	//
+
+	wire tst_sto = sto;
+	wire tst_sta = sta;
+
+	specify
+	  specparam normal_scl_low  = 4700,
+	            normal_scl_high = 4000,
+	            normal_tsu_sta  = 4700,
+	            normal_thd_sta  = 4000,
+	            normal_tsu_sto  = 4000,
+	            normal_tbuf     = 4700,
+
+	            fast_scl_low  = 1300,
+	            fast_scl_high =  600,
+	            fast_tsu_sta  = 1300,
+	            fast_thd_sta  =  600,
+	            fast_tsu_sto  =  600,
+	            fast_tbuf     = 1300;
+
+	  $width(negedge scl, normal_scl_low);  // scl low time
+	  $width(posedge scl, normal_scl_high); // scl high time
+
+	  $setup(posedge scl, negedge sda &&& scl, normal_tsu_sta); // setup start
+	  $setup(negedge sda &&& scl, negedge scl, normal_thd_sta); // hold start
+	  $setup(posedge scl, posedge sda &&& scl, normal_tsu_sto); // setup stop
+
+	  $setup(posedge tst_sta, posedge tst_sto, normal_tbuf); // stop to start time
+	endspecify
+
+endmodule
+
+
diff --git a/verilog/dv/model/mt48lc8m8a2.v b/verilog/dv/model/mt48lc8m8a2.v
new file mode 100755
index 0000000..cf309f1
--- /dev/null
+++ b/verilog/dv/model/mt48lc8m8a2.v
@@ -0,0 +1,992 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2012 Micron Technology, Inc.
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+
+/****************************************************************************************
+*
+*    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;
+
+    event                         error_detected;
+
+    // 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
+	       ->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
+	       ->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
+	       ->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
+
+	       ->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
+
+	       ->error_detected;
+                $display ("at time %t ERROR: tRC violation during Load Mode Register", $time);
+            end
+            // LMR to LMR
+            if (MRD_chk < tMRD) begin
+
+	       ->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
+
+		   ->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
+
+		   ->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
+
+		   ->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
+
+		   ->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
+
+	       ->error_detected;
+                $display ("at time %t ERROR: Bank 0 is not Precharged.", $time);
+            end else if (Ba == 2'b01 && Pc_b1 == 1'b0) begin
+
+	       ->error_detected;
+                $display ("at time %t ERROR: Bank 1 is not Precharged.", $time);
+            end else if (Ba == 2'b10 && Pc_b2 == 1'b0) begin
+
+	       ->error_detected;
+                $display ("at time %t ERROR: Bank 2 is not Precharged.", $time);
+            end else if (Ba == 2'b11 && Pc_b3 == 1'b0) begin
+
+	       ->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
+
+	       ->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
+
+	       ->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
+
+	       ->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
+
+		   ->error_detected;
+                    $display ("at time %t ERROR: tRAS violation during Precharge all bank", $time);
+		    if($time - RAS_chk0 < tRAS)
+			    $display("ERROR: RAS_CHK0 Rxp: %t  Exd: %t",$time - RAS_chk0,tRAS);
+		    if($time - RAS_chk1 < tRAS)
+			    $display("ERROR: RAS_CHK1 Rxp: %t  Exd: %t",$time - RAS_chk1,tRAS);
+		    if($time - RAS_chk2 < tRAS)
+			    $display("ERROR: RAS_CHK2 Rxp: %t  Exd: %t",$time - RAS_chk2,tRAS);
+		    if($time - RAS_chk3 < tRAS)
+			    $display("ERROR: RAS_CHK3 Rxp: %t  Exd: %t",$time - RAS_chk3,tRAS);
+                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
+
+		   ->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
+
+		       ->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
+
+		       ->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
+
+		       ->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
+
+		       ->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
+
+		   ->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
+
+	       ->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
+		 ->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/model/s25fl256s.sv b/verilog/dv/model/s25fl256s.sv
new file mode 100644
index 0000000..9e230cf
--- /dev/null
+++ b/verilog/dv/model/s25fl256s.sv
@@ -0,0 +1,8206 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2012 Spansion, LLC.
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+///////////////////////////////////////////////////////////////////////////////
+//  File name : s25fl256s.v
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+//  Copyright (C) 2012 Spansion, LLC.
+//
+//  MODIFICATION HISTORY :
+//
+//  version: | author:     |  mod date:  | changes made:
+//    V1.0      V.Mancev     19 Nov 09      Initial
+//            R.Prokopovic
+//    V1.1      V.Mancev     04 Mar 10    addr_cnt for second read in
+//                                        high performance read continuous
+//                                        mode can change its value only
+//                                        when CSNeg = '0'
+//    V1.2      V.Mancev     23 Mar 10    During read operations read_out
+//                                        signal changes its value in
+//                                        shorter interval
+//    V1.3      V.Mancev     12 Apr 10    HOLD mode corrected
+//                                        Condition for PP operation
+//                                        corrected
+//    V1.4      V.Mancev     20 May 10    SRWD bit assignment is corrected
+//                                        Condition for WRR command in
+//                                        write_cycle _decode section is
+//                                        corrected
+//                                        Blocking assignments for signals
+//                                        WSTART and PSTART are replaced
+//                                        with nonblocking assignments
+//                                        Conditions in Page Program
+//                                        section are fixed
+//    V1.5      V.Mancev     25 May 10    Conditions in programming
+//                                        sections are fixed
+//                                        Timing control sections for
+//                                        Program and Erase operation are
+//                                        changed
+//    V1.6      V.Mancev     03 June 10   bus_cycle_state section for
+//                                        PGSP command is fixed
+//    V1.7      V.Mancev     28 July 10   During the QUAD mode HOLD# input
+//                                        is not monitored for its normal
+//                                        function
+//                                        write cycle decode section is
+//                                        changed
+//    V1.8     B.Colakovic   24 Aug 10    All redundant signals are removed
+//                                        from BusCycle process
+//    V1.9      V.Mancev     30 Sep 10    Latest datasheet aligned
+//             B.Colakovic
+//
+//    V2.0      V.Mancev     05 Nov 10    Hybrid configuration added
+//
+//    V2.1      V.Mancev     12 Nov 10    QUAD Program operation during Erase
+//                                        Suspend is added
+//                                        Warning for Resume to Suspend time
+//                                        is added
+//                                        During Erase Suspend, after Program
+//                                        operation is completed, WEL bit is
+//                                        cleared
+//                                        Implemetation of Software Reset is
+//                                        Changed
+//    V2.2      S.Petrovic   18 Apr 11    Corrected timing in always block
+//                                        that generates rising_edge_CSNeg_ipd
+//    V2.3      B.Colakovic  05 July 11   Latest datasheet aligned
+//    V2.4      B.Colakovic  14 July 11   Optimization issue is fixed
+//    V2.5      V.Mancev     19 July 11   Timing check issue is fixed
+//    V2.6      V. Mancev    18 Nov 11    Time tHO is changed to 1 ns
+//                                        (customer's request)
+//                                        BRWR instruction is corrected
+//    V2.7      S.Petrovic   28 Aug 12    QPP Instruction is allowed on
+//                                        previously programmed page
+//    V2.8      V. Mancev    13 Feb 13    Reverted restriction for QPP
+//                                        on programmed page and
+//                                        added clearing with sector erase
+//    V2.9      S.Petrovic   13 Nov 28    Corrected FSM state transition
+//                                        started on Power-Up and HW
+//                                        Reset in StateGen process
+//    V2.10     V. Mancev    13 Dec 20     Corrected DLP read
+//    V2.11     M.Stojanovic 15 May 15    Ignored upper address bits for RD4
+//    V2.12     M.Stojanovic 15 May 29    Ignored upper address bits for all
+//                                        commands in QUAD mode
+//    V2.13     M.Stojanovic 16 May 11    During QPP and QPP4 commands
+//                                        the same page must not be
+//                                        programmed more than once. However
+//                                        do not generate P_ERR if this
+//                                        occurs.
+//    V2.14     M.Krneta     19 May 07    Updated according to the rev *P
+//                                        (QPP and QPP4 commands changed,
+//                                        ECCRD command added,
+//                                        LOCK bit removed)
+//    V2.15     B.Barac      20 Jan 24    Bug 49 fixed, issue with not assigning 
+//                                        sector in commands P4E4 and P4E
+//
+///////////////////////////////////////////////////////////////////////////////
+//  PART DESCRIPTION:
+//
+//  Library:    FLASH
+//  Technology: FLASH MEMORY
+//  Part:       S25FL256S
+//
+//  Description: 256 Megabit Serial Flash Memory
+//
+//////////////////////////////////////////////////////////////////////////////
+//  Comments :
+//      For correct simulation, simulator resolution should be set to 1 ps
+//      A device ordering (trim) option determines whether a feature is enabled
+//      or not, or provide relevant parameters:
+//        -15th character in TimingModel determines if enhanced high
+//         performance option is available
+//            (0,2,3,R,A,B,C,D) EHPLC
+//            (Y,Z,S,T,K,L)     Security EHPLC
+//            (4,6,7,8,9,Q)     HPLC
+//        -15th character in TimingModel determines if RESET# input
+//         is available
+//            (R,A,B,C,D,Q.6,7,K,L,S,T,M,N,U,V)  RESET# is available
+//            (0,2,3,4,8,9,Y.Z.W,X)              RESET# is tied to the inactive
+//                                               state,inside the package.
+//        -16th character in TimingModel determines Sector and Page Size:
+//            (0) Sector Size = 64 kB;  Page Size = 256 bytes
+//                Hybrid Top/Bottom sector size architecture
+//            (1) Sector Size = 256 kB; Page Size = 512 bytes
+//                Uniform sector size architecture
+//////////////////////////////////////////////////////////////////////////////
+//  Known Bugs:
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+// MODULE DECLARATION                                                       //
+//////////////////////////////////////////////////////////////////////////////
+`timescale 1 ps/1 ps
+
+module s25fl256s
+    (
+        // Data Inputs/Outputs
+        SI     ,
+        SO     ,
+        // Controls
+        SCK    ,
+        CSNeg  ,
+        RSTNeg ,
+        WPNeg  ,
+        HOLDNeg
+
+);
+
+///////////////////////////////////////////////////////////////////////////////
+// Port / Part Pin Declarations
+///////////////////////////////////////////////////////////////////////////////
+
+    inout   SI            ;
+    inout   SO            ;
+
+    input   SCK           ;
+    input   CSNeg         ;
+    input   RSTNeg        ;
+    inout   HOLDNeg       ;
+    inout   WPNeg         ;
+
+    // interconnect path delay signals
+    wire   SCK_ipd        ;
+    wire   SI_ipd         ;
+    wire   SO_ipd         ;
+
+    wire SI_in            ;
+    assign SI_in = SI_ipd ;
+
+    wire SI_out           ;
+    assign SI_out = SI    ;
+
+    wire SO_in            ;
+    assign SO_in = SO_ipd ;
+
+    wire SO_out           ;
+    assign SO_out = SO    ;
+
+    wire   CSNeg_ipd      ;
+    wire   HOLDNeg_ipd    ;
+    wire   WPNeg_ipd      ;
+    wire   RSTNeg_ipd     ;
+
+    wire HOLDNeg_in                 ;
+    //Internal pull-up
+    assign HOLDNeg_in = (HOLDNeg_ipd === 1'bx) ? 1'b1 : HOLDNeg_ipd;
+
+    wire HOLDNeg_out                ;
+    assign HOLDNeg_out = HOLDNeg    ;
+
+    wire   WPNeg_in                 ;
+    //Internal pull-up
+    assign WPNeg_in = (WPNeg_ipd === 1'bx) ? 1'b1 : WPNeg_ipd;
+
+    wire   WPNeg_out                ;
+    assign WPNeg_out = WPNeg        ;
+
+    wire   RSTNeg_in                 ;
+    //Internal pull-up
+    assign RSTNeg_in = (RSTNeg_ipd === 1'bx) ? 1'b1 : RSTNeg_ipd;
+
+    // internal delays
+    reg PP_in       ;
+    reg PP_out      ;
+    reg BP_in       ;
+    reg BP_out      ;
+    reg SE_in       ;
+    reg SE_out      ;
+    reg BE_in       ;
+    reg BE_out      ;
+    reg WRR_in      ;
+    reg WRR_out     ;
+    reg ERSSUSP_in  ;
+    reg ERSSUSP_out ;
+    reg PRGSUSP_in  ;
+    reg PRGSUSP_out ;
+    reg PU_in       ;
+    reg PU_out      ;
+    reg RST_in      ;
+    reg RST_out     ;
+    reg PPBERASE_in ;
+    reg PPBERASE_out;
+    reg PASSULCK_in ;
+    reg PASSULCK_out;
+    reg PASSACC_in ;
+    reg PASSACC_out;
+
+    // event control registers
+    reg PRGSUSP_out_event;
+    reg ERSSUSP_out_event;
+    reg Reseted_event;
+    reg SCK_ipd_event;
+    reg next_state_event;
+
+    reg rising_edge_PoweredUp;
+    reg rising_edge_Reseted;
+    reg rising_edge_PASSULCK_in;
+    reg rising_edge_RES_out;
+    reg rising_edge_PSTART;
+    reg rising_edge_WSTART;
+    reg rising_edge_ESTART;
+    reg rising_edge_RSTNeg;
+    reg rising_edge_RST;
+    reg falling_edge_RSTNeg;
+    reg falling_edge_RST;
+    reg rising_edge_RST_out;
+    reg rising_edge_CSNeg_ipd  = 1'b0;
+    reg falling_edge_CSNeg_ipd = 1'b0;
+    reg rising_edge_SCK_ipd    = 1'b0;
+    reg falling_edge_SCK_ipd   = 1'b0;
+
+    reg RST                ;
+
+    reg  SOut_zd = 1'bZ     ;
+    reg  SOut_z  = 1'bZ     ;
+
+    wire SI_z                ;
+    wire SO_z                ;
+
+    reg  SIOut_zd = 1'bZ     ;
+    reg  SIOut_z  = 1'bZ     ;
+
+    reg  WPNegOut_zd   = 1'bZ  ;
+    reg  HOLDNegOut_zd = 1'bZ  ;
+
+    assign SI_z = SIOut_z;
+    assign SO_z = SOut_z;
+
+    parameter UserPreload       = 1;
+    parameter mem_file_name     = "none";//"s25fl256s.mem";
+    parameter otp_file_name     = "s25fl256sOTP.mem";//"none";
+
+    parameter TimingModel       = "DefaultTimingModel";
+
+    parameter  PartID           = "s25fl256s";
+    parameter  MaxData          = 255;
+    parameter  MemSize          = 28'h1FFFFFF;
+    parameter  SecSize256       = 20'h3FFFF;
+    parameter  SecSize64        = 16'hFFFF;
+    parameter  SecSize4         = 12'hFFF;
+    parameter  SecNum64         = 541;
+    parameter  SecNum256        = 127;
+    parameter  PageNum64        = 20'h3FFFF;
+    parameter  PageNum256       = 16'hFFFF;
+    parameter  AddrRANGE        = 28'h1FFFFFF;
+    parameter  HiAddrBit        = 31;
+    parameter  OTPSize          = 1023;
+    parameter  OTPLoAddr        = 12'h000;
+    parameter  OTPHiAddr        = 12'h3FF;
+    parameter  BYTE             = 8;
+
+    // Manufacturer Identification
+    parameter  Manuf_ID       = 8'h01;
+    parameter  DeviceID       = 8'h18;
+    // Electronic Signature
+    parameter  ESignature     = 8'h18;
+    //  Device ID
+    //Manufacturer Identification && Memory Type && Memory Capacity
+    parameter  Jedec_ID       = 8'h01;
+    parameter  DeviceID1      = 8'h02;
+    parameter  DeviceID2      = 8'h19;
+    parameter  ExtendedBytes  = 8'h4D;
+    parameter  ExtendedID64   = 8'h01;
+    parameter  ExtendedID256  = 8'h00;
+    parameter  DieRev         = 8'h00;
+    parameter  MaskRev        = 8'h00;
+
+    integer    PageSize;
+    integer    PageNum;
+    integer    SecSize;
+    integer    b_act = 0;
+
+    integer    ASP_ProtSE = 0;
+    integer    Sec_ProtSE = 0;
+
+    integer    EHP; //Enhanced High Performance Mode active
+
+    integer    BAR_ACC = 0; //Bank Register Access active
+
+    //varaibles to resolve architecture used
+    reg [24*8-1:0] tmp_timing;//stores copy of TimingModel
+    reg [7:0] tmp_char1;//Define EHPLC or HPLC Mode
+    reg [7:0] tmp_char2;//stores "0" or "1" character defining sector/page size
+    integer found = 1'b0;
+
+    // If speedsimulation is needed uncomment following line
+
+       `define SPEEDSIM;
+
+    // powerup
+    reg PoweredUp;
+
+    // Memory Array Configuration
+    reg BottomBoot          = 1'b0;
+    reg TopBoot             = 1'b0;
+    reg UniformSec          = 1'b0;
+
+    // FSM control signals
+    reg PDONE     ;
+    reg PSTART    ;
+    reg PGSUSP    ;
+    reg PGRES     ;
+
+    reg TSU       ;
+
+    reg RES_TO_SUSP_MIN_TIME;
+    reg RES_TO_SUSP_TYP_TIME;
+
+    reg WDONE     ;
+    reg WSTART    ;
+
+    reg EDONE     ;
+    reg ESTART    ;
+    reg ESUSP     ;
+    reg ERES      ;
+
+    reg Reseted   ;
+
+    reg PARAM_REGION      = 1'b0;
+
+    // Lock Bit is enabled for customer programming
+    reg WRLOCKENABLE      = 1'b1;
+    // Flag that mark if ASP Register is allready programmed
+    reg ASPOTPFLAG        = 1'b0;
+
+    //Flag for Password unlock command
+    reg PASS_UNLOCKED     = 1'b0;
+    reg [63:0] PASS_TEMP  = 64'hFFFFFFFFFFFFFFFF;
+
+    reg QUADRD            = 1'b0;
+    reg INITIAL_CONFIG    = 1'b0;
+    reg CHECK_FREQ        = 1'b0;
+
+    // Programming buffer
+    integer WByte[0:511];
+    // CFI array
+    integer CFI_array[8'h00:8'h50];
+    // OTP Memory Array
+    integer OTPMem[OTPLoAddr:OTPHiAddr];
+    // Flash Memory Array
+    integer Mem[0:AddrRANGE];
+
+    // Registers
+    // VDLR Register
+    reg[7:0] VDLR_reg          = 8'h00;
+    reg[7:0] VDLR_reg_in       = 8'h00;
+    // NVDLR Register
+    reg[7:0] NVDLR_reg         = 8'h00;
+    reg[7:0] NVDLR_reg_in      = 8'h00;
+    reg start_dlp              = 1'b0;
+
+    // Status Register 1
+    reg[7:0] Status_reg1       = 8'h00;
+    reg[7:0] Status_reg1_in    = 8'h00;
+
+    wire SRWD ;
+    wire P_ERR;
+    wire E_ERR;
+    wire [2:0]BP;
+    wire WEL;
+    wire WIP;
+    assign SRWD   = Status_reg1[7];
+    assign P_ERR  = Status_reg1[6];
+    assign E_ERR  = Status_reg1[5];
+    assign BP     = Status_reg1[4:2];
+    assign WEL    = Status_reg1[1];
+    assign WIP    = Status_reg1[0];
+
+    // Status Register 2
+    reg[7:0] Status_reg2       = 8'h00;
+    reg[7:0] Status_reg2_in    = 8'h00;
+
+    wire ES ;
+    wire PS ;
+    assign ES   = Status_reg2[1];
+    assign PS   = Status_reg2[0];
+
+    // Configuration Register 1
+    reg[7:0] Config_reg1       = 8'h00;
+    reg[7:0] Config_reg1_in    = 8'h00;
+
+    wire   LC1                     ;
+    wire   LC0                     ;
+    wire   TBPROT                  ;
+//     wire   LOCK                    ;
+    wire   BPNV                    ;
+    wire   TBPARM                  ;
+    wire   QUAD                    ;
+    wire   FREEZE                  ;
+    assign LC1     = Config_reg1[7];
+    assign LC0     = Config_reg1[6];
+    assign TBPROT  = Config_reg1[5];
+//     assign LOCK    = Config_reg1[4];
+    assign BPNV    = Config_reg1[3];
+    assign TBPARM  = Config_reg1[2];
+    assign QUAD    = Config_reg1[1];
+    assign FREEZE  = Config_reg1[0];
+
+    // Autoboot Register
+    reg[31:0] AutoBoot_reg     = 32'h00000000;
+    reg[31:0] AutoBoot_reg_in  = 32'h00000000;
+
+    wire ABE;
+    assign ABE     = AutoBoot_reg[0];
+
+    // Bank Address Register
+    reg [7:0] Bank_Addr_reg    = 8'h00;
+    reg [7:0] Bank_Addr_reg_in = 8'h00;
+
+    wire   EXTADD;
+    wire   BA24;
+
+    assign EXTADD  = Bank_Addr_reg[7];
+    assign BA24    = Bank_Addr_reg[0];
+    
+    // ECC Status Register
+    reg[7:0] ECCSR      = 8'h00;
+    
+    wire   EECC;
+    wire   EECCD;
+    wire   ECCDI;
+    
+    assign EECC   = ECCSR[2];
+    assign EECCD  = ECCSR[1];
+    assign ECCDI  = ECCSR[0];
+
+    // ASP Register
+    reg[15:0] ASP_reg   ;
+    reg[15:0] ASP_reg_in;
+
+    wire    RPME         ;
+    wire    PPBOTP       ;
+    wire    PWDMLB       ;
+    wire    PSTMLB       ;
+    assign  RPME     = ASP_reg[5];
+    assign  PPBOTP   = ASP_reg[3];
+    assign  PWDMLB   = ASP_reg[2];
+    assign  PSTMLB   = ASP_reg[1];
+
+    // Password register
+    reg[63:0] Password_reg     = 64'hFFFFFFFFFFFFFFFF;
+    reg[63:0] Password_reg_in  = 64'hFFFFFFFFFFFFFFFF;
+
+    // PPB Lock Register
+    reg[7:0] PPBL              = 8'h00;
+    reg[7:0] PPBL_in           = 8'h00;
+
+    wire   PPB_LOCK              ;
+    assign PPB_LOCK     = PPBL[0];
+
+    // PPB Access Register
+    reg[7:0] PPBAR             = 8'hFF;
+    reg[7:0] PPBAR_in          = 8'hFF;
+
+    reg[SecNum64:0] PPB_bits   = {542{1'b1}};
+
+    // DYB Access Register
+    reg[7:0] DYBAR             = 8'hFF;
+    reg[7:0] DYBAR_in          = 8'hFF;
+
+    reg[SecNum64:0] DYB_bits   = {542{1'b1}};
+
+    //The Lock Protection Registers for OTP Memory space
+    reg[7:0] LOCK_BYTE1;
+    reg[7:0] LOCK_BYTE2;
+    reg[7:0] LOCK_BYTE3;
+    reg[7:0] LOCK_BYTE4;
+
+    // Command Register
+    reg write;
+    reg cfg_write;
+    reg read_out;
+    reg dual          = 1'b0;
+    reg rd_fast       = 1'b1;
+    reg rd_slow       = 1'b0;
+    reg ddr           = 1'b0;
+    reg ddr80         = 1'b0;
+    reg ddr_fast      = 1'b0;
+    reg hold_mode     = 1'b0;
+    reg any_read      = 1'b0;
+    reg quad_pg       = 1'b0;
+
+    wire rd ;
+    wire fast_rd ;
+    wire ddrd ;
+    wire fast_ddr ;
+    wire ddrd80 ;
+
+    wire quadpg ;
+    assign quadpg = quad_pg;
+
+    wire RD_EQU_1;
+    assign RD_EQU_1 = any_read;
+
+    wire RD_EQU_0;
+    assign RD_EQU_0 = ~any_read;
+
+    reg  change_TBPARM = 0;
+
+    reg  change_BP = 0;
+    reg [2:0] BP_bits   = 3'b0;
+
+    reg DOUBLE          = 1'b0; //Double Data Rate (DDR) flag
+
+    reg RdPswdProtMode    = 1'b0;//Read Password Protection Mode Active flag
+    reg RdPswdProtEnable  = 1'b0;//Read Password Protection Mode Support flag
+
+    integer Byte_number = 0;
+
+    reg oe   = 1'b0;
+    reg oe_z = 1'b0;
+
+    reg [647:0] CFI_array_tmp ;
+    reg [7:0] CFI_tmp;
+
+    integer start_delay;
+    reg start_autoboot;
+    integer ABSD;
+
+    reg  change_addr ;
+    integer Address = 0;
+    integer SectorSuspend = 0;
+
+    //Sector and subsector addresses
+    integer SA        = 0;
+
+    // Sector is protect if Sec_Prot(SecNum) = '1'
+    reg [SecNum64:0] Sec_Prot  = {542{1'b0}};
+
+    // timing check violation
+    reg Viol = 1'b0;
+
+    integer WOTPByte;
+    integer AddrLo;
+    integer AddrHi;
+
+    reg[7:0]  old_bit, new_bit;
+    integer old_int, new_int;
+    reg[63:0] old_pass;
+    reg[63:0] new_pass;
+    integer wr_cnt;
+    integer cnt;
+
+    integer read_cnt = 0;
+    integer byte_cnt = 1;
+    integer read_addr = 0;
+    integer read_addr_tmp = 0;
+    integer Sec_addr = 0;
+    integer SecAddr = 0;
+    integer Page_addr = 0;
+    integer pgm_page = 0;
+
+    reg[7:0] data_out;
+    reg[647:0] ident_out;
+
+    time SCK_cycle = 0;
+    time prev_SCK;
+    time start_ddr;
+    time out_time;
+    time SCK_SO_DDR;
+///////////////////////////////////////////////////////////////////////////////
+//Interconnect Path Delay Section
+///////////////////////////////////////////////////////////////////////////////
+ buf   (SCK_ipd, SCK);
+ buf   (SI_ipd, SI);
+
+ buf   (SO_ipd, SO);
+ buf   (CSNeg_ipd, CSNeg);
+ buf   (HOLDNeg_ipd, HOLDNeg);
+ buf   (WPNeg_ipd, WPNeg);
+ buf   (RSTNeg_ipd, RSTNeg);
+
+///////////////////////////////////////////////////////////////////////////////
+// Propagation  delay Section
+///////////////////////////////////////////////////////////////////////////////
+    nmos   (SI,   SI_z , 1);
+
+    nmos   (SO,   SO_z , 1);
+    nmos   (HOLDNeg,   HOLDNegOut_zd , 1);
+    nmos   (WPNeg,   WPNegOut_zd , 1);
+
+    wire deg_pin;
+    wire deg_sin;
+    wire deg_holdin;
+    wire deh_pin;
+    wire deh_sout;
+    wire deh_ddr_sout;
+    wire deh_holdin;
+    //VHDL VITAL CheckEnable equivalents
+    wire quad_rd;
+    assign quad_rd = deg_holdin && ~QUAD && (SIOut_z != 1'bz);
+    wire wr_prot;
+    assign wr_prot = SRWD && WEL && ~QUAD;
+    wire dual_rd;
+    assign dual_rd = dual ;
+    wire ddro;
+    assign ddro = ddr && ~ddr80 && ~dual ;
+    wire ddro80;
+    assign ddro80 = ddr && ddr80 && ~dual ;
+    wire ddr_rd;
+    assign ddr_rd = PoweredUp && ddr;
+    wire sdr_rd;
+    assign sdr_rd = PoweredUp && ~ddr;
+
+specify
+        // tipd delays: interconnect path delays , mapped to input port delays.
+        // In Verilog is not necessary to declare any tipd_ delay variables,
+        // they can be taken from SDF file
+        // With all the other delays real delays would be taken from SDF file
+
+    // tpd delays
+    specparam        tpd_SCK_SO_normal             =1;
+    specparam        tpd_CSNeg_SO                  =1;
+    specparam        tpd_HOLDNeg_SO                =1;
+    specparam        tpd_RSTNeg_SO                 =1;
+    //DDR operation values
+    specparam        tpd_SCK_SO_DDR                =1;
+
+    //tsetup values: setup times
+    specparam        tsetup_CSNeg_SCK              =1;
+    specparam        tsetup_SI_SCK_normal          =1;
+    specparam        tsetup_WPNeg_CSNeg            =1;
+    specparam        tsetup_HOLDNeg_SCK            =1;
+    specparam        tsetup_RSTNeg_CSNeg           =1;
+    // DDR operation values
+    specparam        tsetup_SI_SCK_DDR             =1;
+    specparam        tsetup_SI_SCK_DDR_fast        =1;
+    specparam        tsetup_CSNeg_SCK_DDR          =1;
+
+    //thold values: hold times
+    specparam        thold_CSNeg_SCK               =1;
+    specparam        thold_SI_SCK_normal           =1;
+    specparam        thold_SO_SCK_normal           =1;
+    specparam        thold_WPNeg_CSNeg             =1;
+    specparam        thold_HOLDNeg_SCK             =1;
+    specparam        thold_CSNeg_RSTNeg            =1;
+    // DDR operation values
+    specparam        thold_SI_SCK_DDR              =1;
+    specparam        thold_SI_SCK_DDR_fast         =1;
+    specparam        thold_CSNeg_SCK_DDR           =1;
+
+    // tpw values: pulse width
+    specparam        tpw_SCK_serial_posedge        =1;
+    specparam        tpw_SCK_dual_posedge          =1;
+    specparam        tpw_SCK_fast_posedge          =1;
+    specparam        tpw_SCK_quadpg_posedge        =1;
+    specparam        tpw_SCK_serial_negedge        =1;
+    specparam        tpw_SCK_dual_negedge          =1;
+    specparam        tpw_SCK_fast_negedge          =1;
+    specparam        tpw_SCK_quadpg_negedge        =1;
+    specparam        tpw_CSNeg_read_posedge        =1;
+    specparam        tpw_CSNeg_pgers_posedge       =1;
+    specparam        tpw_RSTNeg_negedge            =1;
+    specparam        tpw_RSTNeg_posedge            =1;
+    // DDR operation values
+    specparam        tpw_SCK_DDR_posedge           =1;
+    specparam        tpw_SCK_DDR_negedge           =1;
+    specparam        tpw_SCK_DDR80_posedge         =1;
+    specparam        tpw_SCK_DDR80_negedge         =1;
+
+    // tperiod min (calculated as 1/max freq)
+    specparam        tperiod_SCK_serial_rd         =1;// 50 MHz
+    specparam        tperiod_SCK_fast_rd           =1;//133 MHz
+    specparam        tperiod_SCK_dual_rd           =1;//104 MHz
+    specparam        tperiod_SCK_quadpg            =1;// 80 MHz
+    // DDR operation values
+    specparam        tperiod_SCK_DDR_rd            =1;// 66 MHz
+    specparam        tperiod_SCK_DDR80_rd          =1;// 80 MHz
+
+    `ifdef SPEEDSIM
+        // Page Program Operation
+        specparam        tdevice_PP_256            = 75e7;//tPP
+        // Page Program Operation
+        specparam        tdevice_PP_512            = 75e7;//tPP
+        // Typical Byte Programming Time
+        specparam        tdevice_BP                = 4e8;//tBP
+        // Sector Erase Operation
+        specparam        tdevice_SE64              = 10e7; // 650e7;//tSE Dinesh A
+        // Sector Erase Operation
+        specparam        tdevice_SE256             = 10e7; // 1875e7;//tSE Dinesh A
+        // Bulk Erase Operation
+        specparam        tdevice_BE                = 330e9;//tBE
+        // WRR Cycle Time
+        specparam        tdevice_WRR               = 1; // 2e9;//tW Dinesh A
+        // Erase Suspend/Erase Resume Time
+        specparam        tdevice_ERSSUSP           = 45e6;//tESL
+        // Program Suspend/Program Resume Time
+        specparam        tdevice_PRGSUSP           = 1; // 40e6;// Dinesh A
+        // VCC (min) to CS# Low
+        specparam        tdevice_PU                = 1; // 3e8;//tPU Dinesh A
+        // PPB Erase Time
+        specparam        tdevice_PPBERASE          = 1; // 15e9;// Dinesh A
+        // Password Unlock Time
+        specparam        tdevice_PASSULCK          = 1e6;//
+        // Password Unlock to Password Unlock Time
+        specparam        tdevice_PASSACC           = 100e6;
+        // Data In Setup Max time
+        specparam        tdevice_TSU               = 300e3;
+    `else
+        // Page Program Operation
+        specparam        tdevice_PP_256            = 75e7;//tPP
+        // Page Program Operation
+        specparam        tdevice_PP_512            = 75e7;//tPP
+        // Typical Byte Programming Time
+        specparam        tdevice_BP                = 4e8;//tBP
+        // Sector Erase Operation
+        specparam        tdevice_SE64              = 650e9;//tSE
+        // Sector Erase Operation
+        specparam        tdevice_SE256             = 1875e9;//tSE
+        // Bulk Erase Operation
+        specparam        tdevice_BE                = 330e12;//tBE
+        // WRR Cycle Time
+        specparam        tdevice_WRR               = 2e11;//tW
+        // Erase Suspend/Erase Resume Time
+        specparam        tdevice_ERSSUSP           = 45e6;//tESL
+        // Program Suspend/Program Resume Time
+        specparam        tdevice_PRGSUSP           = 40e6;//
+        // VCC (min) to CS# Low
+        specparam        tdevice_PU                = 3e8;//tPU
+        // PPB Erase Time
+        specparam        tdevice_PPBERASE          = 15e9;//
+        // Password Unlock Time
+        specparam        tdevice_PASSULCK          = 1e6;//
+        // Password Unlock to Password Unlock Time
+        specparam        tdevice_PASSACC           = 100e6;
+        // Data In Setup Max time
+        specparam        tdevice_TSU               = 300e3;
+    `endif // SPEEDSIM
+
+///////////////////////////////////////////////////////////////////////////////
+// Input Port  Delays  don't require Verilog description
+///////////////////////////////////////////////////////////////////////////////
+// Path delays                                                               //
+///////////////////////////////////////////////////////////////////////////////
+  if (~ddr)           (SCK => SO) = tpd_SCK_SO_normal;
+  if (ddr || rd_fast) (SCK => SO) = tpd_SCK_SO_DDR;
+
+  if (~ddr && dual) (SCK => SI) = tpd_SCK_SO_normal;
+  if ( ddr && dual) (SCK => SI) = tpd_SCK_SO_DDR;
+
+  if (~ddr && QUAD)(SCK => HOLDNeg) = tpd_SCK_SO_normal;
+  if ( ddr && QUAD)(SCK => HOLDNeg) = tpd_SCK_SO_DDR;
+  if (~ddr && QUAD)(SCK => WPNeg)   = tpd_SCK_SO_normal;
+  if ( ddr && QUAD)(SCK => WPNeg)   = tpd_SCK_SO_DDR;
+
+  if (CSNeg)         (CSNeg => SO) = tpd_CSNeg_SO;
+  if (CSNeg && dual) (CSNeg => SI) = tpd_CSNeg_SO;
+
+  if (CSNeg && QUAD) (CSNeg => HOLDNeg) = tpd_CSNeg_SO;
+  if (CSNeg && QUAD) (CSNeg => WPNeg)   = tpd_CSNeg_SO;
+
+  if (~QUAD)          (HOLDNeg => SO) = tpd_HOLDNeg_SO;
+  if (~QUAD && dual)  (HOLDNeg => SI) = tpd_HOLDNeg_SO;
+
+   (RSTNeg => SO) = tpd_RSTNeg_SO;
+///////////////////////////////////////////////////////////////////////////////
+// Timing Violation                                                          //
+///////////////////////////////////////////////////////////////////////////////
+        $setup ( CSNeg          , posedge SCK &&& sdr_rd,
+                                                tsetup_CSNeg_SCK,       Viol);
+        $setup ( CSNeg          , posedge SCK &&& ddr_rd,
+                                                tsetup_CSNeg_SCK_DDR,   Viol);
+        $setup ( SI             , posedge SCK &&& deg_sin,
+                                                tsetup_SI_SCK_normal,   Viol);
+        $setup ( WPNeg          , negedge CSNeg &&& wr_prot,
+                                                tsetup_WPNeg_CSNeg,     Viol);
+        $setup ( HOLDNeg        , posedge SCK &&& quad_rd,
+                                                tsetup_HOLDNeg_SCK,     Viol);
+        $setup ( SI             , posedge SCK &&& ddro,
+                                                tsetup_SI_SCK_DDR,      Viol);
+        $setup ( SI             , negedge SCK &&& ddro,
+                                                tsetup_SI_SCK_DDR,      Viol);
+        $setup ( SI             , posedge SCK &&& ddro80,
+                                                tsetup_SI_SCK_DDR,      Viol);
+        $setup ( SI             , negedge SCK &&& ddro80,
+                                                tsetup_SI_SCK_DDR,      Viol);
+
+        $setup ( RSTNeg         , negedge CSNeg,
+                                                tsetup_RSTNeg_CSNeg,    Viol);
+
+        $hold  ( posedge SCK &&& sdr_rd   , CSNeg,
+                                                thold_CSNeg_SCK,        Viol);
+        $hold  ( posedge SCK &&& ddr_rd   , CSNeg,
+                                                thold_CSNeg_SCK_DDR,    Viol);
+        $hold  ( posedge SCK &&& deg_sin     , SI ,
+                                                thold_SI_SCK_normal,    Viol);
+        $hold  ( negedge SCK &&& deh_sout    , SO ,
+                                                thold_SO_SCK_normal,    Viol);
+        $hold  ( negedge SCK &&& deh_ddr_sout        , SO ,
+                                                thold_SO_SCK_normal,    Viol);
+        $hold  ( posedge SCK &&& deh_ddr_sout        , SO ,
+                                                thold_SO_SCK_normal,    Viol);
+        $hold  ( posedge CSNeg &&& wr_prot , WPNeg ,
+                                                thold_WPNeg_CSNeg,      Viol);
+        $hold  ( posedge SCK  &&& quad_rd  , HOLDNeg ,
+                                                thold_HOLDNeg_SCK,      Viol);
+        $hold  ( posedge SCK &&& ddro     , SI,
+                                                thold_SI_SCK_DDR,       Viol);
+        $hold  ( negedge SCK &&& ddro     , SI,
+                                                thold_SI_SCK_DDR,       Viol);
+        $hold  ( posedge SCK &&& ddro80     , SI,
+                                                thold_SI_SCK_DDR,       Viol);
+        $hold  ( negedge SCK &&& ddro80     , SI,
+                                                thold_SI_SCK_DDR,       Viol);
+
+        $hold  ( negedge RSTNeg  , CSNeg,
+                                                thold_CSNeg_RSTNeg,     Viol);
+
+        $width ( posedge SCK &&& rd        , tpw_SCK_serial_posedge);
+        $width ( negedge SCK &&& rd        , tpw_SCK_serial_negedge);
+        $width ( posedge SCK &&& dual_rd   , tpw_SCK_dual_posedge);
+        $width ( negedge SCK &&& dual_rd   , tpw_SCK_dual_negedge);
+        $width ( posedge SCK &&& fast_rd   , tpw_SCK_fast_posedge);
+        $width ( negedge SCK &&& fast_rd   , tpw_SCK_fast_negedge);
+        $width ( posedge SCK &&& ddrd      , tpw_SCK_DDR_posedge);
+        $width ( negedge SCK &&& ddrd      , tpw_SCK_DDR_negedge);
+        $width ( posedge SCK &&& ddrd80    , tpw_SCK_DDR80_posedge);
+        $width ( negedge SCK &&& ddrd80    , tpw_SCK_DDR80_negedge);
+        $width ( posedge SCK &&& quadpg    , tpw_SCK_quadpg_posedge);
+        $width ( negedge SCK &&& quadpg    , tpw_SCK_quadpg_negedge);
+
+        $width ( posedge CSNeg &&& RD_EQU_1, tpw_CSNeg_read_posedge);
+        $width ( posedge CSNeg &&& RD_EQU_0, tpw_CSNeg_pgers_posedge);
+        $width ( negedge RSTNeg            , tpw_RSTNeg_negedge);
+        $width ( posedge RSTNeg            , tpw_RSTNeg_posedge);
+
+        $period ( posedge SCK &&& rd       , tperiod_SCK_serial_rd);
+        $period ( posedge SCK &&& fast_rd  , tperiod_SCK_fast_rd);
+        $period ( posedge SCK &&& dual_rd  , tperiod_SCK_dual_rd);
+        $period ( posedge SCK &&& quadpg   , tperiod_SCK_quadpg);
+        $period ( posedge SCK &&& ddrd     , tperiod_SCK_DDR_rd);
+        $period ( posedge SCK &&& ddrd80   , tperiod_SCK_DDR80_rd);
+
+endspecify
+
+///////////////////////////////////////////////////////////////////////////////
+// Main Behavior Block                                                       //
+///////////////////////////////////////////////////////////////////////////////
+// FSM states
+ parameter IDLE            = 5'd0;
+ parameter RESET_STATE     = 5'd1;
+ parameter AUTOBOOT        = 5'd2;
+ parameter WRITE_SR        = 5'd3;
+ parameter PAGE_PG         = 5'd4;
+ parameter OTP_PG          = 5'd5;
+ parameter PG_SUSP         = 5'd6;
+ parameter SECTOR_ERS      = 5'd7;
+ parameter BULK_ERS        = 5'd8;
+ parameter ERS_SUSP        = 5'd9;
+ parameter ERS_SUSP_PG     = 5'd10;
+ parameter ERS_SUSP_PG_SUSP= 5'd11;
+ parameter PASS_PG         = 5'd12;
+ parameter PASS_UNLOCK     = 5'd13;
+ parameter PPB_PG          = 5'd14;
+ parameter PPB_ERS         = 5'd15;
+ parameter AUTOBOOT_PG     = 5'd16;
+ parameter ASP_PG          = 5'd17;
+ parameter PLB_PG          = 5'd18;
+ parameter DYB_PG          = 5'd19;
+ parameter NVDLR_PG        = 5'd20;
+
+ reg [4:0] current_state;
+ reg [4:0] next_state;
+
+// Instruction type
+ parameter NONE            = 7'd0;
+ parameter WRR             = 7'd1;
+ parameter PP              = 7'd2;
+ parameter READ            = 7'd3;
+ parameter WRDI            = 7'd4;
+ parameter RDSR            = 7'd5;
+ parameter WREN            = 7'd6;
+ parameter RDSR2           = 7'd7;
+ parameter FSTRD           = 7'd8;
+ parameter FSTRD4          = 7'd9;
+ parameter DDRFR           = 7'd10;
+ parameter DDRFR4          = 7'd11;
+ parameter PP4             = 7'd12;
+ parameter RD4             = 7'd13;
+ parameter ABRD            = 7'd14;
+ parameter ABWR            = 7'd15;
+ parameter BRRD            = 7'd16;
+ parameter BRWR            = 7'd17;
+ parameter P4E             = 7'd19;
+ parameter P4E4            = 7'd20;
+ parameter ASPRD           = 7'd21;
+ parameter ASPP            = 7'd22;
+ parameter CLSR            = 7'd23;
+ parameter QPP             = 7'd24;
+ parameter QPP4            = 7'd25;
+ parameter RDCR            = 7'd26;
+ parameter DOR             = 7'd27;
+ parameter DOR4            = 7'd28;
+ parameter DLPRD           = 7'd29;
+ parameter OTPP            = 7'd30;
+ parameter PNVDLR          = 7'd31;
+ parameter OTPR            = 7'd32;
+ parameter WVDLR           = 7'd33;
+ parameter BE              = 7'd34;
+ parameter QOR             = 7'd35;
+ parameter QOR4            = 7'd36;
+ parameter ERSP            = 7'd37;
+ parameter ERRS            = 7'd38;
+ parameter PGSP            = 7'd39;
+ parameter PGRS            = 7'd40;
+ parameter REMS            = 7'd41;
+ parameter RDID            = 7'd42;
+ parameter MPM             = 7'd43;
+ parameter PLBWR           = 7'd44;
+ parameter PLBRD           = 7'd45;
+ parameter RES             = 7'd46;
+ parameter DIOR            = 7'd47;
+ parameter DIOR4           = 7'd48;
+ parameter DDRDIOR         = 7'd49;
+ parameter DDRDIOR4        = 7'd50;
+ parameter SE              = 7'd51;
+ parameter SE4             = 7'd52;
+ parameter DYBRD           = 7'd53;
+ parameter DYBWR           = 7'd54;
+ parameter PPBRD           = 7'd55;
+ parameter PPBP            = 7'd56;
+ parameter PPBERS          = 7'd57;
+ parameter PASSRD          = 7'd58;
+ parameter PASSP           = 7'd59;
+ parameter PASSU           = 7'd60;
+ parameter QIOR            = 7'd61;
+ parameter QIOR4           = 7'd62;
+ parameter DDRQIOR         = 7'd63;
+ parameter DDRQIOR4        = 7'd64;
+ parameter RESET           = 7'd65;
+ parameter MBR             = 7'd66;
+ parameter BRAC            = 7'd67;
+ parameter ECCRD           = 7'd68;
+
+ reg [6:0] Instruct;
+
+//Bus cycle state
+ parameter STAND_BY        = 3'd0;
+ parameter OPCODE_BYTE     = 3'd1;
+ parameter ADDRESS_BYTES   = 3'd2;
+ parameter DUMMY_BYTES     = 3'd3;
+ parameter MODE_BYTE       = 3'd4;
+ parameter DATA_BYTES      = 3'd5;
+
+ reg [2:0] bus_cycle_state;
+
+ reg deq_pin;
+    always @(SO_in, SO_z)
+    begin
+      if (SO_in==SO_z)
+        deq_pin=1'b0;
+      else
+        deq_pin=1'b1;
+    end
+    // check when data is generated from model to avoid setuphold check in
+    // this occasion
+    assign deg_pin = deq_pin;
+    assign deh_pin = (deq_pin == 1'b0) && (SO_z != 1'bz);
+ reg deq_sin;
+    always @(SI_in, SIOut_z)
+    begin
+      if (SI_in==SIOut_z)
+        deq_sin=1'b0;
+      else
+        deq_sin=1'b1;
+    end
+    // check when data is generated from model to avoid setuphold check in
+    // this occasion
+    assign deg_sin=deq_sin
+           && (ddr == 1'b0) && (Instruct !== DDRFR)
+           && (Instruct !== DDRFR4) && (Instruct !== DDRDIOR)
+           && (Instruct !== DDRDIOR4) && (Instruct !== DDRQIOR)
+           && (Instruct !== DDRQIOR4) && (SIOut_z != 1'bz);
+ reg deq_sout;
+    always @(SO_out, SIOut_z)
+    begin
+      if (SO_out==SIOut_z)
+        deq_sout=1'b0;
+      else
+        deq_sout=1'b1;
+    end
+    // check when data is generated from model
+    assign deh_sout= (deq_sout == 1'b0)
+           && (ddr == 1'b0) && (SOut_z != 1'bz);
+    assign deh_ddr_sout= (deq_sout == 1'b0)
+           && (ddr == 1'b1) && (SOut_z != 1'bz);
+
+ reg deq_holdin;
+    always @(HOLDNeg_ipd, HOLDNegOut_zd)
+    begin
+      if (HOLDNeg_ipd==HOLDNegOut_zd)
+        deq_holdin=1'b0;
+      else
+        deq_holdin=1'b1;
+    end
+    // check when data is generated from model to avoid setuphold check in
+    // this occasion
+    assign deg_holdin=deq_holdin;
+    assign deh_holdin=(deq_holdin == 1'b0) && (HOLDNegOut_zd != 1'bz);
+
+    //Power Up time;
+    initial
+    begin
+        PoweredUp = 1'b0;
+	$display("%0t=>STATUS: SPI FLASH POWER UP Wait Time: %0d:%0d",$time,tdevice_PU,tdevice_PRGSUSP);
+        #tdevice_PU PoweredUp = 1'b1;
+	$display("%0t=>STATUS: SPI FLASH POWER UP",$time,);
+    end
+
+    initial
+    begin : Init
+        write       = 1'b0;
+        cfg_write   = 1'b0;
+        read_out    = 1'b0;
+        Address     = 0;
+        change_addr = 1'b0;
+        cnt         = 0;
+        RST         = 1'b0;
+        RST_in      = 1'b0;
+        RST_out     = 1'b1;
+        PDONE       = 1'b1;
+        PSTART      = 1'b0;
+        PGSUSP      = 1'b0;
+        PGRES       = 1'b0;
+        PRGSUSP_in  = 1'b0;
+        ERSSUSP_in  = 1'b0;
+        RES_TO_SUSP_MIN_TIME  = 1'b0;
+        RES_TO_SUSP_TYP_TIME  = 1'b0;
+
+        EDONE       = 1'b1;
+        ESTART      = 1'b0;
+        ESUSP       = 1'b0;
+        ERES        = 1'b0;
+
+        WDONE       = 1'b1;
+        WSTART      = 1'b0;
+
+        Reseted     = 1'b0;
+
+        Instruct        = NONE;
+        bus_cycle_state = STAND_BY;
+        current_state   = RESET_STATE;
+        next_state      = RESET_STATE;
+    end
+
+    // initialize memory and load preload files if any
+    initial
+    begin: InitMemory
+        integer i;
+
+        for (i=0;i<=AddrRANGE;i=i+1)
+        begin
+            Mem[i] = MaxData;
+        end
+
+        if ((UserPreload) && !(mem_file_name == "none"))
+        begin
+           // Memory Preload
+           //s25fl256s.mem, memory preload file
+           //  @aaaaaa - <aaaaaa> stands for address
+           //  dd      - <dd> is byte to be written at Mem(aaaaaa++)
+           // (aaaaaa is incremented at every load)
+	   $display("%m: Loading Memfile : %s",mem_file_name);
+           $readmemh(mem_file_name,Mem);
+        end
+
+        for (i=OTPLoAddr;i<=OTPHiAddr;i=i+1)
+        begin
+            OTPMem[i] = MaxData;
+        end
+
+        if (UserPreload && !(otp_file_name == "none"))
+        begin
+        //s25fl256s_otp memory file
+        //   /       - comment
+        //   @aaaaaa     - <aaaaaa> stands for address within last defined
+        //   sector
+        //   dd      - <dd> is byte to be written at OTPMem(aaa++)
+        //   (aa is incremented at every load)
+        //   only first 1-4 columns are loaded. NO empty lines !!!!!!!!!!!!!!!!
+           $readmemh(otp_file_name,OTPMem);
+        end
+
+        LOCK_BYTE1[7:0] = OTPMem[16];
+        LOCK_BYTE2[7:0] = OTPMem[17];
+        LOCK_BYTE3[7:0] = OTPMem[18];
+        LOCK_BYTE4[7:0] = OTPMem[19];
+    end
+
+    // initialize memory and load preload files if any
+    initial
+    begin: InitTimingModel
+    integer i;
+    integer j;
+        //UNIFORM OR HYBRID arch model is used
+        //assumptions:
+        //1. TimingModel has format as S25FL128SXXXXXXXX_X_XXpF
+        //it is important that 16-th character from first one is "0" or "1"
+        //2. TimingModel does not have more then 24 characters
+        tmp_timing = TimingModel;//copy of TimingModel
+
+        i = 23;
+        while ((i >= 0) && (found != 1'b1))//search for first non null character
+        begin        //i keeps position of first non null character
+            j = 7;
+            while ((j >= 0) && (found != 1'b1))
+            begin
+                if (tmp_timing[i*8+j] != 1'd0)
+                    found = 1'b1;
+                else
+                    j = j-1;
+            end
+            i = i - 1;
+        end
+        i = i +1;
+        if (found)//if non null character is found
+        begin
+            for (j=0;j<=7;j=j+1)
+            begin
+            //EHPLC/HPLC character is 15
+            tmp_char1[j] = TimingModel[(i-14)*8+j];
+            //256B/512B Page character is 16
+            tmp_char2[j] = TimingModel[(i-15)*8+j];
+            end
+        end
+        if (tmp_char1 == "0" || tmp_char1 == "2" || tmp_char1 == "3" ||
+            tmp_char1 == "R" || tmp_char1 == "A" || tmp_char1 == "B" ||
+            tmp_char1 == "C" || tmp_char1 == "D" || tmp_char1 == "Y" ||
+            tmp_char1 == "Z" || tmp_char1 == "S" || tmp_char1 == "T" ||
+            tmp_char1 == "K" || tmp_char1 == "L")
+        begin
+            EHP = 1;
+            if(tmp_char1 == "Z" || tmp_char1 == "S" || tmp_char1 == "T" ||
+               tmp_char1 == "K" || tmp_char1 == "L" || tmp_char1 == "Y")
+            begin
+                RdPswdProtEnable = 1;
+            end
+        end
+        else if (tmp_char1 == "4" || tmp_char1 == "6" || tmp_char1 == "7" ||
+                 tmp_char1 == "8" || tmp_char1 == "9" || tmp_char1 == "Q")
+        begin
+            EHP = 0;
+        end
+
+        if (tmp_char1 == "0" || tmp_char1 == "2" || tmp_char1 == "3" ||
+            tmp_char1 == "R" || tmp_char1 == "A" || tmp_char1 == "B" ||
+            tmp_char1 == "C" || tmp_char1 == "D" || tmp_char1 == "4" ||
+            tmp_char1 == "6" || tmp_char1 == "7" || tmp_char1 == "8" ||
+            tmp_char1 == "9" || tmp_char1 == "Q")
+        begin
+            ASP_reg    = 16'hFE7F;
+            ASP_reg_in = 16'hFE7F;
+        end
+        else if (tmp_char1 == "Y" || tmp_char1 == "Z" || tmp_char1 == "S" ||
+                 tmp_char1 == "T" || tmp_char1 == "K" || tmp_char1 == "L")
+        begin
+            ASP_reg    = 16'hFE4F;
+            ASP_reg_in = 16'hFE4F;
+        end
+
+        if (tmp_char2 == "0")
+        begin
+            PageSize = 255;
+            PageNum  = PageNum64;
+            SecSize  = SecSize64;
+        end
+        else if (tmp_char2 == "1")
+        begin
+            PageSize = 511;
+            PageNum  = PageNum256;
+            SecSize  = SecSize256;
+        end
+    end
+
+    //CFI
+    initial
+    begin: InitCFI
+    integer i;
+    integer j;
+        ///////////////////////////////////////////////////////////////////////
+        // ID-CFI array data
+        ///////////////////////////////////////////////////////////////////////
+        // Manufacturer and Device ID
+        CFI_array[8'h00] = Jedec_ID;
+        CFI_array[8'h01] = DeviceID1;
+        CFI_array[8'h02] = DeviceID2;
+        CFI_array[8'h03] = 8'h00;
+        if (tmp_char2 == "0")
+        // Uniform 64kB sectors
+            CFI_array[8'h04] = ExtendedID64;
+        else if (tmp_char2 == "1")
+        // Uniform 256kB sectors
+            CFI_array[8'h04] = ExtendedID256;
+        CFI_array[8'h05] = 8'h80;
+        CFI_array[8'h06] = 8'h00;
+        CFI_array[8'h07] = 8'h00;
+        CFI_array[8'h08] = 8'h00;
+        CFI_array[8'h09] = 8'h00;
+        CFI_array[8'h0A] = 8'h00;
+        CFI_array[8'h0B] = 8'h00;
+        CFI_array[8'h0C] = 8'h00;
+        CFI_array[8'h0D] = 8'h00;
+        CFI_array[8'h0E] = 8'h00;
+        CFI_array[8'h0F] = 8'h00;
+        // CFI Query Identification String
+        CFI_array[8'h10] = 8'h51;
+        CFI_array[8'h11] = 8'h52;
+        CFI_array[8'h12] = 8'h59;
+        CFI_array[8'h13] = 8'h02;
+        CFI_array[8'h14] = 8'h00;
+        CFI_array[8'h15] = 8'h40;
+        CFI_array[8'h16] = 8'h00;
+        CFI_array[8'h17] = 8'h53;
+        CFI_array[8'h18] = 8'h46;
+        CFI_array[8'h19] = 8'h51;
+        CFI_array[8'h1A] = 8'h00;
+        //CFI system interface string
+        CFI_array[8'h1B] = 8'h27;
+        CFI_array[8'h1C] = 8'h36;
+        CFI_array[8'h1D] = 8'h00;
+        CFI_array[8'h1E] = 8'h00;
+        CFI_array[8'h1F] = 8'h06;
+        if (tmp_char2 == "0")
+        begin
+        // 64kB sector and 256B page
+            CFI_array[8'h20] = 8'h08;
+            CFI_array[8'h21] = 8'h08;
+        end
+        else if (tmp_char2 == "1")
+        begin
+        // 256kB sector and 512B page
+            CFI_array[8'h20] = 8'h09;
+            CFI_array[8'h21] = 8'h09;
+        end
+        CFI_array[8'h22] = 8'h10;
+        CFI_array[8'h23] = 8'h02;
+        CFI_array[8'h24] = 8'h02;
+        CFI_array[8'h25] = 8'h03;
+        CFI_array[8'h26] = 8'h03;
+        // Device Geometry Definition(Uniform Sector Devices)
+        CFI_array[8'h27] = 8'h19;
+        CFI_array[8'h28] = 8'h02;
+        CFI_array[8'h29] = 8'h01;
+
+        if (tmp_char2 == "0")
+        // 64kB sectors
+            CFI_array[8'h2A] = 8'h08;
+        else if (tmp_char2 == "1")
+            CFI_array[8'h2A] = 8'h09;
+
+        CFI_array[8'h2B] = 8'h00;
+        if (tmp_char2 == "1")
+        begin
+            CFI_array[8'h2C] = 8'h01;
+            CFI_array[8'h2D] = 8'h7F;
+            CFI_array[8'h2E] = 8'h00;
+            CFI_array[8'h2F] = 8'h00;
+            CFI_array[8'h30] = 8'h04;
+            CFI_array[8'h31] = 8'hFF;
+            CFI_array[8'h32] = 8'hFF;
+            CFI_array[8'h33] = 8'hFF;
+            CFI_array[8'h34] = 8'hFF;
+        end
+        else
+        begin
+            CFI_array[8'h2C] = 8'h02;
+            if (TBPARM)
+            begin
+            // 4KB physical sectors at top
+                CFI_array[8'h2D] = 8'hFD;
+                CFI_array[8'h2E] = 8'h00;
+                CFI_array[8'h2F] = 8'h00;
+                CFI_array[8'h30] = 8'h01;
+                CFI_array[8'h31] = 8'h1F;
+                CFI_array[8'h32] = 8'h01;
+                CFI_array[8'h33] = 8'h10;
+                CFI_array[8'h34] = 8'h00;
+            end
+            else
+            begin
+            // 4KB physical sectors at bottom
+                CFI_array[8'h2D] = 8'h1F;
+                CFI_array[8'h2E] = 8'h00;
+                CFI_array[8'h2F] = 8'h10;
+                CFI_array[8'h30] = 8'h00;
+                CFI_array[8'h31] = 8'hFD;
+                CFI_array[8'h32] = 8'h01;
+                CFI_array[8'h33] = 8'h00;
+                CFI_array[8'h34] = 8'h01;
+            end
+        end
+        CFI_array[8'h35] = 8'hFF;
+        CFI_array[8'h36] = 8'hFF;
+        CFI_array[8'h37] = 8'hFF;
+        CFI_array[8'h38] = 8'hFF;
+        CFI_array[8'h39] = 8'hFF;
+        CFI_array[8'h3A] = 8'hFF;
+        CFI_array[8'h3B] = 8'hFF;
+        CFI_array[8'h3C] = 8'hFF;
+        CFI_array[8'h3D] = 8'hFF;
+        CFI_array[8'h3E] = 8'hFF;
+        CFI_array[8'h3F] = 8'hFF;
+        // CFI Primary Vendor-Specific Extended Query
+        CFI_array[8'h40] = 8'h50;
+        CFI_array[8'h41] = 8'h52;
+        CFI_array[8'h42] = 8'h49;
+        CFI_array[8'h43] = 8'h31;
+        CFI_array[8'h44] = 8'h33;
+        CFI_array[8'h45] = 8'h21;
+        CFI_array[8'h46] = 8'h02;
+        CFI_array[8'h47] = 8'h01;
+        CFI_array[8'h48] = 8'h00;
+        CFI_array[8'h49] = 8'h08;
+        CFI_array[8'h4A] = 8'h00;
+        CFI_array[8'h4B] = 8'h01;
+        CFI_array[8'h4C] = 8'h00;
+        CFI_array[8'h4D] = 8'h00;
+        CFI_array[8'h4E] = 8'h00;
+        CFI_array[8'h4F] = 8'h07;
+        CFI_array[8'h50] = 8'h01;
+
+        begin
+            for(i=80;i>=0;i=i-1)
+            begin
+                CFI_tmp = CFI_array[8'h00-i+80];
+                for(j=7;j>=0;j=j-1)
+                begin
+                    CFI_array_tmp[8*i+j] = CFI_tmp[j];
+                end
+            end
+        end
+
+    end
+
+    always @(next_state_event or PoweredUp or RST or RST_out or
+            RSTNeg_in or rising_edge_RSTNeg or falling_edge_RST)
+    begin: StateTransition
+        if (PoweredUp)
+        begin
+            if ((RSTNeg_in == 1'b1) && (RST_out == 1'b1))
+                current_state = #(1000) next_state;
+            else if ((~RSTNeg_in || rising_edge_RSTNeg) && falling_edge_RST)
+            begin
+            // no state transition while RESET# low
+                current_state = RESET_STATE;
+                RST_in = 1'b1;
+                #1000 RST_in = 1'b0;
+            end
+        end
+    end
+
+    always @(posedge RST_in)
+    begin:Threset
+        RST_out = 1'b0;
+        #(35000000-200000) RST_out = 1'b1;
+    end
+
+    always @(negedge CSNeg_ipd)
+    begin:CheckCEOnPowerUP
+        if (~PoweredUp)
+            $display ("%0t=> Device is selected during Power Up",$time);
+    end
+
+    ///////////////////////////////////////////////////////////////////////////
+    //// Internal Delays
+    ///////////////////////////////////////////////////////////////////////////
+
+    always @(posedge PRGSUSP_in)
+    begin:PRGSuspend
+        PRGSUSP_out = 1'b0;
+        #tdevice_PRGSUSP PRGSUSP_out = 1'b1;
+    end
+
+    always @(posedge PPBERASE_in)
+    begin:PPBErs
+        PPBERASE_out = 1'b0;
+        #tdevice_PPBERASE PPBERASE_out = 1'b1;
+    end
+
+    always @(posedge ERSSUSP_in)
+    begin:ERSSuspend
+        ERSSUSP_out = 1'b0;
+        #tdevice_ERSSUSP ERSSUSP_out = 1'b1;
+    end
+
+    always @(posedge PASSULCK_in)
+    begin:PASSULock
+        PASSULCK_out = 1'b0;
+        #tdevice_PASSULCK PASSULCK_out = 1'b1;
+    end
+
+    always @(posedge PASSACC_in)
+    begin:PASSAcc
+        PASSACC_out = 1'b0;
+        #tdevice_PASSACC PASSACC_out = 1'b1;
+    end
+
+///////////////////////////////////////////////////////////////////////////////
+// write cycle decode
+///////////////////////////////////////////////////////////////////////////////
+    integer opcode_cnt = 0;
+    integer addr_cnt   = 0;
+    integer mode_cnt   = 0;
+    integer dummy_cnt  = 0;
+    integer data_cnt   = 0;
+    integer bit_cnt    = 0;
+
+    reg [4095:0] Data_in = 4096'b0;
+    reg [7:0] opcode;
+    reg [7:0] opcode_in;
+    reg [7:0] opcode_tmp;
+    reg [31:0] addr_bytes;
+    reg [31:0] hiaddr_bytes;
+    reg [31:0] Address_in;
+    reg [7:0] mode_bytes;
+    reg [7:0] mode_in;
+    integer Latency_code;
+    integer quad_data_in [0:1023];
+    reg [3:0] quad_nybble = 4'b0;
+    reg [3:0] Quad_slv;
+    reg [7:0] Byte_slv;
+
+   always @(rising_edge_CSNeg_ipd or falling_edge_CSNeg_ipd or
+            rising_edge_SCK_ipd or falling_edge_SCK_ipd or
+            current_state)
+   begin: Buscycle
+        integer i;
+        integer j;
+        integer k;
+        time CLK_PER;
+        time LAST_CLK;
+
+        if (current_state == RESET_STATE)
+            bus_cycle_state = STAND_BY;
+        else
+        begin
+            if (falling_edge_CSNeg_ipd)
+            begin
+                if (bus_cycle_state==STAND_BY)
+                begin
+                    Instruct = NONE;
+                    write = 1'b1;
+                    cfg_write  = 0;
+                    opcode_cnt = 0;
+                    addr_cnt   = 0;
+                    mode_cnt   = 0;
+                    dummy_cnt  = 0;
+                    data_cnt   = 0;
+                    opcode_tmp = 0;
+                    start_dlp  = 0;
+                    DOUBLE     = 1'b0;
+                    QUADRD     = 1'b0;
+                    CLK_PER    = 1'b0;
+                    LAST_CLK   = 1'b0;
+                    if (current_state == AUTOBOOT)
+                    begin
+                        bus_cycle_state = DATA_BYTES;
+                    end
+                    else
+                    begin
+                        bus_cycle_state = OPCODE_BYTE;
+                    end
+                end
+            end
+
+            if (rising_edge_SCK_ipd) // Instructions, addresses or data present
+            begin                    // at SI are latched on the rising edge of SCK
+
+                CLK_PER = $time - LAST_CLK;
+                LAST_CLK = $time;
+                if (CHECK_FREQ)
+                begin
+                    if ((CLK_PER < 20000 && Latency_code == 3) ||
+                    (CLK_PER < 12500 && Latency_code == 0) ||
+                    (CLK_PER < 11100 && Latency_code == 1) ||
+                    (CLK_PER < 9600 && Latency_code == 2))
+                    begin
+                        $display ("More wait states are required for");
+                        $display ("this clock frequency value");
+                    end
+                    if (Instruct == DDRFR || Instruct == DDRFR4 || Instruct == DDRDIOR ||
+                        Instruct == DDRDIOR4 || Instruct == DDRQIOR || Instruct == DDRQIOR4)
+                    begin
+                       if   (CLK_PER < 12500)
+                       begin
+                           ddr80 = 1'b1;
+                       end
+                       else
+                       begin
+                           ddr80 = 1'b0;
+                       end
+                    end
+                    CHECK_FREQ = 0;
+                end
+
+                if (~CSNeg_ipd)
+                begin
+                    case (bus_cycle_state)
+                        OPCODE_BYTE:
+                        begin
+                            if ((HOLDNeg_in && ~QUAD) || QUAD)
+                            begin
+                                opcode_in[opcode_cnt] = SI_in;
+                                opcode_cnt = opcode_cnt + 1;
+                                Latency_code = Config_reg1[7:6];
+                                if (opcode_cnt == BYTE)
+                                begin
+                                    for(i=7;i>=0;i=i-1)
+                                    begin
+                                        opcode[i] = opcode_in[7-i];
+                                    end
+                                    case (opcode)
+                                        8'b00000110 : // 06h
+                                        begin
+                                            Instruct = WREN;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b00000100 : // 04h
+                                        begin
+                                            Instruct = WRDI;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b00000001 : // 01h
+                                        begin
+                                            Instruct = WRR;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b00000011 : // 03h
+                                        begin
+                                            Instruct = READ;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b00010011 : // 13h
+                                        begin
+                                            Instruct = RD4;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b01001011 : // 4Bh
+                                        begin
+                                            Instruct = OTPR;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b00000101 : // 05h
+                                        begin
+                                            Instruct = RDSR;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b00000111 : // 07h
+                                        begin
+                                            Instruct = RDSR2;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b00110101 : // 35h
+                                        begin
+                                            Instruct = RDCR;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b10010000 : // 90h
+                                        begin
+                                            Instruct = REMS;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b10011111 : // 9Fh
+                                        begin
+                                            Instruct = RDID;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b10101011 : // ABh
+                                        begin
+                                            Instruct = RES;
+                                            bus_cycle_state = DUMMY_BYTES;
+                                        end
+                                        8'b00001011 : // 0Bh
+                                        begin
+                                            Instruct = FSTRD;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b00001100 : // 0Ch
+                                        begin
+                                            Instruct = FSTRD4;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b00001101 : // 0Dh
+                                        begin
+                                            Instruct = DDRFR;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b00001110 : // 0Eh
+                                        begin
+                                            Instruct = DDRFR4;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b00111011 : // 3Bh
+                                        begin
+                                            Instruct = DOR;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b00111100 : // 3Ch
+                                        begin
+                                            Instruct = DOR4;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b10111011 : // BBh
+                                        begin
+                                            Instruct = DIOR;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b10111100 : // BCh
+                                        begin
+                                            Instruct = DIOR4;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b10111101 : // BDh
+                                        begin
+                                            Instruct = DDRDIOR;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b10111110 : // BEh
+                                        begin
+                                            Instruct = DDRDIOR4;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b01101011 : // 6Bh
+                                        begin
+                                            Instruct = QOR;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b01101100 : // 6Ch
+                                        begin
+                                            Instruct = QOR4;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b11101011 : // EBh
+                                        begin
+                                            Instruct = QIOR;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b11101100 : // ECh
+                                        begin
+                                            Instruct = QIOR4;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b11101101 : // EDh
+                                        begin
+                                            Instruct = DDRQIOR;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b11101110 : // EEh
+                                        begin
+                                            Instruct = DDRQIOR4;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            CHECK_FREQ = 1'b1;
+                                        end
+                                        8'b00000010 : // 02h
+                                        begin
+                                            Instruct = PP;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b00010010 : // 12h
+                                        begin
+                                            Instruct = PP4;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b00110010: // 32h
+                                        begin
+                                            Instruct = QPP;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            quad_pg = 1'b1;
+                                        end
+                                        8'b00111000: // 38h
+                                        begin
+                                            Instruct = QPP;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            quad_pg = 1'b1;
+                                        end
+                                        8'b00110100 : // 34h
+                                        begin
+                                            Instruct = QPP4;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                            quad_pg = 1'b1;
+                                        end
+                                        8'b01000010 : // 42h
+                                        begin
+                                            Instruct = OTPP;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b10000101 : // 85h
+                                        begin
+                                            Instruct = PGSP;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b10001010 : // 8Ah
+                                        begin
+                                            Instruct = PGRS;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b11000111 : // C7h
+                                        begin
+                                            Instruct = BE;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b01100000 : // 60h
+                                        begin
+                                            Instruct = BE;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b11011000 : // D8h
+                                        begin
+                                            Instruct = SE;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b11011100 : // DCh
+                                        begin
+                                            Instruct = SE4;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b01110101 : // 75h
+                                        begin
+                                            Instruct = ERSP;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b01111010 : // 7Ah
+                                        begin
+                                            Instruct = ERRS;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b00010100 : // 14h
+                                        begin
+                                            Instruct = ABRD;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b00010101 : // 15h
+                                        begin
+                                            Instruct = ABWR;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b00010110 : // 16h
+                                        begin
+                                            Instruct = BRRD;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b00010111 : // 17h
+                                        begin
+                                            Instruct = BRWR;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b00101011 : // 2Bh
+                                        begin
+                                            Instruct = ASPRD;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b00101111 : // 2Fh
+                                        begin
+                                            Instruct = ASPP;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b11100000 : // E0h
+                                        begin
+                                            Instruct = DYBRD;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b11100001 : // E1h
+                                        begin
+                                            Instruct = DYBWR;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b11100010 : // E2h
+                                        begin
+                                            Instruct = PPBRD;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b11100011 : // E3h
+                                        begin
+                                            Instruct = PPBP;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b11100100 : // E4h
+                                        begin
+                                            Instruct = PPBERS;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b10100110 : // A6h
+                                        begin
+                                            Instruct = PLBWR;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b10100111 : // A7h
+                                        begin
+                                            Instruct = PLBRD;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b11100111 : // E7h
+                                        begin
+                                            Instruct = PASSRD;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b11101000 : // E8h
+                                        begin
+                                            Instruct = PASSP;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b11101001 : // E9h
+                                        begin
+                                            Instruct = PASSU;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b11110000 : // F0h
+                                        begin
+                                            Instruct = RESET;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b00110000 : // 30h
+                                        begin
+                                            Instruct = CLSR;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b00100000 : // 20h
+                                        begin
+                                            Instruct = P4E;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b00100001 : // 21h
+                                        begin
+                                            Instruct = P4E4;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                        8'b01000001 : // 41h
+                                        begin
+                                            Instruct = DLPRD;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b01000011 : // 43h
+                                        begin
+                                            Instruct = PNVDLR;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b01001010 : // 4Ah
+                                        begin
+                                            Instruct = WVDLR;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b10111001 : // B9h
+                                        begin
+                                            Instruct = BRAC;
+                                            bus_cycle_state = DATA_BYTES;
+                                        end
+                                        8'b11111111 : // FFh
+                                        begin
+                                            Instruct = MBR;
+                                            bus_cycle_state = MODE_BYTE;
+                                        end
+                                        8'b00011000 : // 18h
+                                        begin
+                                            Instruct = ECCRD;
+                                            bus_cycle_state = ADDRESS_BYTES;
+                                        end
+                                    endcase
+                                end
+                            end
+                        end //end of OPCODE BYTE
+
+                        ADDRESS_BYTES :
+                        begin
+                            if ((Instruct == DDRFR)  || (Instruct == DDRFR4)  ||
+                                (Instruct == DDRDIOR) || (Instruct == DDRDIOR4) ||
+                                (Instruct == DDRQIOR) || (Instruct == DDRQIOR4))
+                                DOUBLE = 1'b1;
+                            else
+                                DOUBLE = 1'b0;
+                            if ((Instruct == QOR)  || (Instruct == QOR4)  ||
+                                (Instruct == QIOR) || (Instruct == QIOR4) ||
+                                (Instruct == DDRQIOR) || (Instruct == DDRQIOR4))
+                                QUADRD = 1'b1;
+                            else
+                                QUADRD = 1'b0;
+                            if (DOUBLE == 1'b0)
+                            begin
+                                if (((((Instruct == FSTRD) && (~EXTADD)) ||
+                                ((Instruct == DOR)  && (~EXTADD)) ||
+                                (Instruct == OTPR)) &&
+                                ((HOLDNeg_in && ~QUAD) || QUAD)) ||
+                                ((Instruct == QOR) && QUAD && (~EXTADD)))
+                                begin
+                                //Instruction + 3 Bytes Address + Dummy Byte
+                                    Address_in[addr_cnt] = SI_in;
+                                    addr_cnt = addr_cnt + 1;
+                                    if (addr_cnt == 3*BYTE)
+                                    begin
+                                        for(i=23;i>=0;i=i-1)
+                                        begin
+                                            addr_bytes[23-i] = Address_in[i];
+                                        end
+                                        addr_bytes[31:25] = 7'b0000000;
+                                        addr_bytes[24] = Bank_Addr_reg[0];
+                                        Address = addr_bytes ;
+                                        change_addr = 1'b1;
+                                        #1 change_addr = 1'b0;
+                                        if (Instruct==FSTRD || Instruct==DOR ||
+                                            Instruct == QOR)
+                                        begin
+                                            if (Latency_code == 3)
+                                                bus_cycle_state = DATA_BYTES;
+                                            else
+                                                bus_cycle_state = DUMMY_BYTES;
+                                        end
+                                        else
+                                            bus_cycle_state = DUMMY_BYTES;
+                                    end
+                                end
+                                else if (Instruct==ECCRD)
+                                begin
+                                //Instruction + 4 Bytes Address + Dummy Byte
+                                    Address_in[addr_cnt] = SI_in;
+                                    addr_cnt = addr_cnt + 1;
+                                    if (addr_cnt == 4*BYTE)
+                                    begin
+                                        for(i=31;i>=0;i=i-1)
+                                        begin
+                                            hiaddr_bytes[31-i] = Address_in[i];
+                                        end
+                                        //High order address bits are ignored
+                                        Address = {hiaddr_bytes[31:4],4'b0000};
+                                        change_addr = 1'b1;
+                                        #1 change_addr = 1'b0;
+                                        bus_cycle_state = DUMMY_BYTES;
+                                    end
+                                end
+                                else if ((((Instruct==FSTRD4) ||
+                                        (Instruct==DOR4) ||
+                                        ((Instruct==FSTRD) && EXTADD) ||
+                                        ((Instruct==DOR) && EXTADD)) &&
+                                        ((HOLDNeg_in && ~QUAD) || QUAD)) ||
+                                        ((Instruct==QOR4) && QUAD) ||
+                                        ((Instruct==QOR) && QUAD && EXTADD))
+                                begin
+                                //Instruction + 4 Bytes Address + Dummy Byte
+                                    Address_in[addr_cnt] = SI_in;
+                                    addr_cnt = addr_cnt + 1;
+                                    if (addr_cnt == 4*BYTE)
+                                    begin
+                                        for(i=31;i>=0;i=i-1)
+                                        begin
+                                            hiaddr_bytes[31-i] = Address_in[i];
+                                        end
+                                        //High order address bits are ignored
+                                        Address = {7'b0000000,hiaddr_bytes[24:0]};
+                                        change_addr = 1'b1;
+                                        #1 change_addr = 1'b0;
+                                        if (Latency_code == 3)
+                                            bus_cycle_state = DATA_BYTES;
+                                        else
+                                        begin
+                                            bus_cycle_state = DUMMY_BYTES;
+                                        end
+                                    end
+                                end
+                                else if ((Instruct==DIOR) && (~EXTADD) &&
+                                            ((HOLDNeg_in && ~QUAD) || QUAD))
+                                begin
+                                //DUAL I/O High Performance Read(3 Bytes Addr)
+                                    Address_in[2*addr_cnt]     = SO_in;
+                                    Address_in[2*addr_cnt + 1] = SI_in;
+                                    read_cnt = 0;
+                                    addr_cnt = addr_cnt + 1;
+                                    if (addr_cnt == 3*BYTE/2)
+                                    begin
+                                        addr_cnt = 0;
+                                        for(i=23;i>=0;i=i-1)
+                                        begin
+                                            addr_bytes[23-i]=Address_in[i];
+                                        end
+                                        addr_bytes[31:25] = 7'b0000000;
+                                        addr_bytes[24] = Bank_Addr_reg[0];
+                                        Address = addr_bytes;
+                                        change_addr = 1'b1;
+                                        #1 change_addr = 1'b0;
+                                        if (EHP)
+                                            bus_cycle_state = MODE_BYTE;
+                                        else
+                                            bus_cycle_state = DUMMY_BYTES;
+                                    end
+                                end
+                                else if (((Instruct==DIOR4) ||
+                                        ((Instruct==DIOR) && EXTADD)) &&
+                                        ((HOLDNeg_in && ~QUAD) || QUAD))
+                                begin //DUAL I/O High Performance Read(4Bytes Addr)
+                                    Address_in[2*addr_cnt]     = SO_in;
+                                    Address_in[2*addr_cnt + 1] = SI_in;
+                                    read_cnt = 0;
+                                    addr_cnt = addr_cnt + 1;
+                                    if (addr_cnt == 4*BYTE/2)
+                                    begin
+                                        addr_cnt = 0;
+                                        for(i=31;i>=0;i=i-1)
+                                        begin
+                                            addr_bytes[31-i] = Address_in[i];
+                                        end
+                                        Address = {7'b0000000,addr_bytes[24:0]};
+                                        change_addr = 1'b1;
+                                        #1 change_addr = 1'b0;
+                                        if (EHP)
+                                            bus_cycle_state = MODE_BYTE;
+                                        else
+                                            bus_cycle_state = DUMMY_BYTES;
+                                    end
+                                end
+                                else if ((Instruct == QIOR) && (~EXTADD))
+                                begin
+                                //QUAD I/O High Performance Read (3Bytes Address)
+                                    if (QUAD)
+                                    begin
+                                        Address_in[4*addr_cnt] = HOLDNeg_in;
+                                        Address_in[4*addr_cnt+1] = WPNeg_in;
+                                        Address_in[4*addr_cnt+2] = SO_in;
+                                        Address_in[4*addr_cnt+3] = SI_in;
+                                        read_cnt = 0;
+                                        addr_cnt = addr_cnt + 1;
+                                        if (addr_cnt == 3*BYTE/4)
+                                        begin
+                                            addr_cnt = 0;
+                                            for(i=23;i>=0;i=i-1)
+                                            begin
+                                                addr_bytes[23-i] = Address_in[i];
+                                            end
+                                            addr_bytes[31:25] = 7'b0000000;
+                                            addr_bytes[24] = Bank_Addr_reg[0];
+
+                                            Address = addr_bytes;
+                                            change_addr = 1'b1;
+                                            #1 change_addr = 1'b0;
+                                            bus_cycle_state = MODE_BYTE;
+                                        end
+                                    end
+                                    else
+                                        bus_cycle_state = STAND_BY;
+                                end
+                                else if ((Instruct==QIOR4) || ((Instruct==QIOR)
+                                        && EXTADD))
+                                begin
+                                    //QUAD I/O High Performance Read (4Bytes Addr)
+                                    if (QUAD)
+                                    begin
+                                        Address_in[4*addr_cnt] = HOLDNeg_in;
+                                        Address_in[4*addr_cnt+1] = WPNeg_in;
+                                        Address_in[4*addr_cnt+2] = SO_in;
+                                        Address_in[4*addr_cnt+3] = SI_in;
+                                        read_cnt = 0;
+                                        addr_cnt = addr_cnt +1;
+                                        if (addr_cnt == 4*BYTE/4)
+                                        begin
+                                            addr_cnt =0;
+                                            for(i=31;i>=0;i=i-1)
+                                            begin
+                                                hiaddr_bytes[31-i] = Address_in[i];
+                                            end
+                                            //High order address bits are ignored
+                                            Address = {7'b0000000,hiaddr_bytes[24:0]};
+                                            change_addr = 1'b1;
+                                            #1 change_addr = 1'b0;
+                                            bus_cycle_state = MODE_BYTE;
+                                        end
+                                    end
+                                    else
+                                        bus_cycle_state = STAND_BY;
+                                end
+                                else if ((((Instruct==RD4) || (Instruct==PP4) ||
+                                        (Instruct==SE4) ||(Instruct==PPBRD) ||
+                                        (Instruct==DYBRD) ||(Instruct==DYBWR) ||
+                                        (Instruct==PPBP) || (Instruct==P4E4) ||
+                                        ((Instruct==READ) && EXTADD) ||
+                                        ((Instruct==PP) && EXTADD) ||
+                                        ((Instruct==P4E) && EXTADD) ||
+                                        ((Instruct==SE) && EXTADD)) &&
+                                        ((HOLDNeg_in && ~QUAD) || QUAD)) ||
+                                        (QUAD && (Instruct==QPP4 ||
+                                        ((Instruct==QPP) && EXTADD))))
+                                begin
+                                    Address_in[addr_cnt] = SI_in;
+                                    addr_cnt = addr_cnt + 1;
+                                    if (addr_cnt == 4*BYTE)
+                                    begin
+                                        for(i=31;i>=0;i=i-1)
+                                        begin
+                                            hiaddr_bytes[31-i] = Address_in[i];
+                                        end
+                                        //High order address bits are ignored
+                                        Address = {7'b0000000,hiaddr_bytes[24:0]};
+                                        change_addr = 1'b1;
+                                        #1 change_addr = 1'b0;
+                                        bus_cycle_state = DATA_BYTES;
+                                    end
+                                end
+                                else if (((HOLDNeg_in && ~QUAD) || QUAD) &&
+                                        (~EXTADD))
+                                begin
+                                    Address_in[addr_cnt] = SI_in;
+                                    addr_cnt = addr_cnt + 1;
+                                    if (addr_cnt == 3*BYTE)
+                                    begin
+                                        for(i=23;i>=0;i=i-1)
+                                        begin
+                                            addr_bytes[23-i] = Address_in[i];
+                                        end
+                                        addr_bytes[31:25] = 7'b0000000;
+                                        addr_bytes[24] = Bank_Addr_reg[0];
+                                        Address = addr_bytes;
+                                        change_addr = 1'b1;
+                                        #1 change_addr = 1'b0;
+                                        bus_cycle_state = DATA_BYTES;
+                                    end
+                                end
+                            end
+                            else
+                            begin
+                                if ((Instruct==DDRFR) && (~EXTADD))
+                                //Fast DDR Read Mode
+                                begin
+                                    Address_in[addr_cnt] = SI_in;
+                                    if ((addr_cnt/2) <= 16)
+                                    begin
+                                        opcode_tmp[addr_cnt/2] = SI_in;
+                                    end
+                                    addr_cnt = addr_cnt + 1;
+                                    read_cnt = 0;
+                                end
+                                else if ((Instruct==DDRFR4) ||
+                                        ((Instruct==DDRFR) && EXTADD))
+                                begin
+                                    Address_in[addr_cnt] = SI_in;
+                                    if ((addr_cnt/2) <= 16)
+                                    begin
+                                        opcode_tmp[addr_cnt/2] = SI_in;
+                                    end
+                                    addr_cnt = addr_cnt + 1;
+                                    read_cnt = 0;
+                                end
+                                else if ((Instruct == DDRDIOR) && (~EXTADD))
+                                begin    //Dual I/O DDR Read Mode
+                                    Address_in[2*addr_cnt] = SO_in;
+                                    Address_in[2*addr_cnt+1]= SI_in;
+                                    if ((addr_cnt/2) <= 16)
+                                    begin
+                                        opcode_tmp[addr_cnt/2] = SI_in;
+                                    end
+                                    addr_cnt = addr_cnt + 1;
+                                    read_cnt = 0;
+                                end
+                                else if ((Instruct==DDRDIOR4) ||
+                                        ((Instruct==DDRDIOR) && EXTADD))
+                                begin    //Dual I/O DDR Read Mode
+                                    Address_in[2*addr_cnt]   = SO_in;
+                                    Address_in[2*addr_cnt+1] = SI_in;
+                                    if ((addr_cnt/2) <= 16)
+                                    begin
+                                        opcode_tmp[addr_cnt/2] = SI_in;
+                                    end
+                                    addr_cnt = addr_cnt + 1;
+                                    read_cnt = 0;
+                                end
+                                else if ((Instruct==DDRQIOR) && (~EXTADD) && QUAD)
+                                begin    //Quad I/O DDR Read Mode
+                                    Address_in[4*addr_cnt] = HOLDNeg_in;
+                                    Address_in[4*addr_cnt+1] = WPNeg_in;
+                                    Address_in[4*addr_cnt+2] = SO_in;
+                                    Address_in[4*addr_cnt+3] = SI_in;
+                                    opcode_tmp[addr_cnt/2] = SI_in;
+                                    addr_cnt = addr_cnt +1;
+                                    read_cnt = 0;
+                                end
+                                else if (QUAD && ((Instruct==DDRQIOR4) ||
+                                        ((Instruct==DDRQIOR) && EXTADD)))
+                                begin
+                                    Address_in[4*addr_cnt] = HOLDNeg_in;
+                                    Address_in[4*addr_cnt+1] = WPNeg_in;
+                                    Address_in[4*addr_cnt+2] = SO_in;
+                                    Address_in[4*addr_cnt+3] = SI_in;
+                                    opcode_tmp[addr_cnt/2] = SI_in;
+                                    addr_cnt = addr_cnt +1;
+                                    read_cnt = 0;
+                                end
+                            end
+                        end
+
+                        MODE_BYTE :
+                        begin
+                            if (((Instruct==DIOR) || (Instruct == DIOR4))
+                                && ((HOLDNeg_in && ~QUAD) || QUAD))
+                            begin
+                                mode_in[2*mode_cnt] = SO_in;
+                                mode_in[2*mode_cnt+1] = SI_in;
+                                mode_cnt = mode_cnt + 1;
+                                if (mode_cnt == BYTE/2)
+                                begin
+                                    mode_cnt = 0;
+                                    for(i=7;i>=0;i=i-1)
+                                    begin
+                                        mode_bytes[i] = mode_in[7-i];
+                                    end
+                                    if (Latency_code == 0 || Latency_code == 3)
+                                        bus_cycle_state = DATA_BYTES;
+                                    else
+                                        bus_cycle_state = DUMMY_BYTES;
+                                end
+                            end
+                            else if (((Instruct==QIOR) || (Instruct == QIOR4))
+                                    && QUAD)
+                            begin
+                                mode_in[4*mode_cnt] = HOLDNeg_in;
+                                mode_in[4*mode_cnt+1] = WPNeg_in;
+                                mode_in[4*mode_cnt+2] = SO_in;
+                                mode_in[4*mode_cnt+3] = SI_in;
+                                mode_cnt = mode_cnt + 1;
+                                if (mode_cnt == BYTE/4)
+                                begin
+                                    mode_cnt = 0;
+                                    for(i=7;i>=0;i=i-1)
+                                    begin
+                                        mode_bytes[i] = mode_in[7-i];
+                                    end
+                                    bus_cycle_state = DUMMY_BYTES;
+                                end
+                            end
+                            else if ((Instruct == DDRFR) || (Instruct == DDRFR4))
+                                mode_in[2*mode_cnt] = SI_in;
+                            else if ((Instruct==DDRDIOR) || (Instruct==DDRDIOR4))
+                            begin
+                                mode_in[4*mode_cnt]   = SO_in;
+                                mode_in[4*mode_cnt+1] = SI_in;
+                            end
+                            else if (((Instruct==DDRQIOR) || (Instruct == DDRQIOR4))
+                                    && QUAD)
+                            begin
+                                mode_in[0] = HOLDNeg_in;
+                                mode_in[1] = WPNeg_in;
+                                mode_in[2] = SO_in;
+                                mode_in[3] = SI_in;
+                            end
+                            dummy_cnt = 0;
+                        end
+
+                        DUMMY_BYTES :
+                        begin
+                            Return_DLP(Instruct, EHP, Latency_code,
+                                       dummy_cnt, start_dlp);
+                            if (DOUBLE == 1'b1 && (hold_mode==0) &&
+                               (VDLR_reg != 8'b00000000) && start_dlp)
+                            begin
+                                read_out = 1'b1;
+                                #10 read_out = 1'b0;
+                            end
+                            if ((((Instruct==FSTRD) || (Instruct==FSTRD4) ||
+                            (Instruct==DOR)  || (Instruct==DOR4)  ||
+                            (Instruct==OTPR)) &&
+                            ((HOLDNeg_in && ~QUAD) || QUAD)) ||
+                            (((Instruct==QOR)||(Instruct==QOR4)) && QUAD))
+                            begin
+                                dummy_cnt = dummy_cnt + 1;
+                                if (dummy_cnt == BYTE)
+                                begin
+                                    bus_cycle_state = DATA_BYTES;
+                                end
+                            end
+
+                            else if ((Instruct==DDRFR) || (Instruct==DDRFR4))
+                            begin
+                                dummy_cnt = dummy_cnt + 1;
+                                if (EHP)
+                                begin
+                                    if (((Latency_code == 3) && (dummy_cnt==1)) ||
+                                        ((Latency_code == 0) && (dummy_cnt==2)) ||
+                                        ((Latency_code == 1) && (dummy_cnt==4)) ||
+                                        ((Latency_code == 2) && (dummy_cnt==5)))
+                                    begin
+                                        bus_cycle_state = DATA_BYTES;
+                                    end
+                                end
+                                else
+                                begin
+                                    if (((Latency_code == 3) && (dummy_cnt==4)) ||
+                                        ((Latency_code == 0) && (dummy_cnt==5)) ||
+                                        ((Latency_code == 1) && (dummy_cnt==6)) ||
+                                        ((Latency_code == 2) && (dummy_cnt==7)))
+                                    begin
+                                        bus_cycle_state = DATA_BYTES;
+                                    end
+                                end
+                            end
+                            else if (Instruct==RES)
+                            begin
+                                dummy_cnt = dummy_cnt + 1;
+                                if (dummy_cnt == 3*BYTE)
+                                bus_cycle_state = DATA_BYTES;
+                            end
+                            else if (Instruct==ECCRD)
+                            begin
+                                dummy_cnt = dummy_cnt + 1;
+                                if (dummy_cnt == BYTE)
+                                bus_cycle_state = DATA_BYTES;
+                            end
+                            else if ((Instruct == DIOR) || (Instruct == DIOR4)
+                                    && ((HOLDNeg_in && ~QUAD) || QUAD))
+                            begin
+                                dummy_cnt = dummy_cnt + 1;
+                                if (EHP)
+                                begin
+                                    if (((Latency_code == 1) && (dummy_cnt==1)) ||
+                                        ((Latency_code == 2) && (dummy_cnt==2)))
+                                        bus_cycle_state = DATA_BYTES;
+                                end
+                                else
+                                begin
+                                    if (((Latency_code == 3) && (dummy_cnt==4)) ||
+                                        ((Latency_code == 0) && (dummy_cnt==4)) ||
+                                        ((Latency_code == 1) && (dummy_cnt==5)) ||
+                                        ((Latency_code == 2) && (dummy_cnt==6)))
+                                        bus_cycle_state = DATA_BYTES;
+                                end
+                            end
+                            else if ((Instruct==DDRDIOR) || (Instruct==DDRDIOR4))
+                            begin
+                                dummy_cnt = dummy_cnt + 1;
+                                if (EHP)
+                                begin
+                                    if (((Latency_code == 3) && (dummy_cnt==2)) ||
+                                        ((Latency_code == 0) && (dummy_cnt==4)) ||
+                                        ((Latency_code == 1) && (dummy_cnt==5)) ||
+                                        ((Latency_code == 2) && (dummy_cnt==6)))
+                                    begin
+                                        bus_cycle_state = DATA_BYTES;
+                                    end
+                                end
+                                else
+                                begin
+                                    if (((Latency_code == 3) && (dummy_cnt==4)) ||
+                                        ((Latency_code == 0) && (dummy_cnt==6)) ||
+                                        ((Latency_code == 1) && (dummy_cnt==7)) ||
+                                        ((Latency_code == 2) && (dummy_cnt==8)))
+                                    begin
+                                        bus_cycle_state = DATA_BYTES;
+                                    end
+                                end
+                            end
+                            else if (((Instruct == QIOR) || (Instruct == QIOR4))
+                                    && QUAD)
+                            begin
+                                dummy_cnt = dummy_cnt + 1;
+                                if (((Latency_code == 3) && (dummy_cnt==1)) ||
+                                    ((Latency_code == 0) && (dummy_cnt==4)) ||
+                                    ((Latency_code == 1) && (dummy_cnt==4)) ||
+                                    ((Latency_code == 2) && (dummy_cnt==5)))
+                                begin
+                                    bus_cycle_state = DATA_BYTES;
+                                end
+                            end
+                            else if (((Instruct==DDRQIOR) || (Instruct==DDRQIOR4))
+                                    && QUAD)
+                            begin
+                                dummy_cnt = dummy_cnt + 1;
+
+                                if (((Latency_code == 3) && (dummy_cnt==3)) ||
+                                    ((Latency_code == 0) && (dummy_cnt==6)) ||
+                                    ((Latency_code == 1) && (dummy_cnt==7)) ||
+                                    ((Latency_code == 2) && (dummy_cnt==8)))
+                                begin
+                                    bus_cycle_state = DATA_BYTES;
+                                end
+                            end
+                        end
+
+                        DATA_BYTES :
+                        begin
+
+                            if (DOUBLE == 1'b1 && (hold_mode==0))
+                            begin
+                                read_out = 1'b1;
+                                #10 read_out = 1'b0;
+                            end
+
+                            if ((QUAD) && ((Instruct==QPP) || (Instruct == QPP4)))
+                            begin
+                                quad_nybble = {HOLDNeg_in, WPNeg_in, SO_in, SI_in};
+                                if (data_cnt > ((PageSize+1)*2-1))
+                                begin
+                                //In case of quad mode and QPP,
+                                //if more than 512 bytes are sent to the device
+                                    for(i=0;i<=(PageSize*2-1);i=i+1)
+                                    begin
+                                        quad_data_in[i] = quad_data_in[i+1];
+                                    end
+                                    quad_data_in[(PageSize+1)*2-1] = quad_nybble;
+                                    data_cnt = data_cnt +1;
+                                end
+                                else
+                                begin
+                                    if (quad_nybble !== 4'bZZZZ)
+                                    begin
+                                        quad_data_in[data_cnt] = quad_nybble;
+                                    end
+                                    data_cnt = data_cnt +1;
+                                end
+                            end
+                            else if ((~QUADRD) && ((HOLDNeg_in && ~QUAD) || QUAD))
+                            begin
+                                if (data_cnt > ((PageSize+1)*8-1))
+                                begin
+                                //In case of serial mode and PP,
+                                //if more than PageSize are sent to the device
+                                //previously latched data are discarded and last
+                                //256/512 data bytes are guaranteed to be programmed
+                                //correctly within the same page.
+                                    if (bit_cnt == 0)
+                                    begin
+                                        for(i=0;i<=(PageSize*BYTE-1);i=i+1)
+                                        begin
+                                            Data_in[i] = Data_in[i+8];
+                                        end
+                                    end
+                                    Data_in[PageSize*BYTE + bit_cnt] = SI_in;
+                                    bit_cnt = bit_cnt + 1;
+                                    if (bit_cnt == 8)
+                                    begin
+                                        bit_cnt = 0;
+                                    end
+                                    data_cnt = data_cnt + 1;
+                                end
+                                else
+                                begin
+                                    Data_in[data_cnt] = SI_in;
+                                    data_cnt = data_cnt + 1;
+                                    bit_cnt = 0;
+                                end
+                            end
+                        end
+                    endcase
+                end
+            end
+
+            if (falling_edge_SCK_ipd)
+            begin
+                if (~CSNeg_ipd)
+                begin
+                    case (bus_cycle_state)
+                        ADDRESS_BYTES :
+                        begin
+                            if (DOUBLE == 1'b1)
+                            begin
+                                if ((Instruct==DDRFR) && (~EXTADD))
+                                //Fast DDR Read Mode
+                                begin
+                                    Address_in[addr_cnt] = SI_in;
+                                    if (addr_cnt != 0)
+                                    begin
+                                        addr_cnt = addr_cnt + 1;
+                                    end
+                                    read_cnt = 0;
+                                    if (addr_cnt == 3*BYTE)
+                                    begin
+                                        addr_cnt = 0;
+                                        for(i=23;i>=0;i=i-1)
+                                        begin
+                                            addr_bytes[23-i] = Address_in[i];
+                                        end
+                                        addr_bytes[31:25] = 7'b0000000;
+                                        addr_bytes[24] = Bank_Addr_reg[0];
+                                        Address = addr_bytes;
+                                        change_addr = 1'b1;
+                                        #1 change_addr = 1'b0;
+                                        if (EHP)
+                                            bus_cycle_state = MODE_BYTE;
+                                        else
+                                            bus_cycle_state = DUMMY_BYTES;
+                                    end
+                                end
+                                else if ((Instruct==DDRFR4) ||
+                                        ((Instruct==DDRFR) && EXTADD))
+                                begin
+                                    Address_in[addr_cnt] = SI_in;
+                                    if (addr_cnt != 0)
+                                    begin
+                                        addr_cnt = addr_cnt + 1;
+                                    end
+                                    read_cnt = 0;
+                                    if (addr_cnt == 4*BYTE)
+                                    begin
+                                        addr_cnt = 0;
+                                        for(i=31;i>=0;i=i-1)
+                                        begin
+                                            addr_bytes[31-i] = Address_in[i];
+                                        end
+                                        Address = {7'b0000000,addr_bytes[24:0]};
+                                        change_addr = 1'b1;
+                                        #1 change_addr = 1'b0;
+                                        if (EHP)
+                                            bus_cycle_state = MODE_BYTE;
+                                        else
+                                        begin
+                                            bus_cycle_state = DUMMY_BYTES;
+                                            if (DOUBLE == 1'b1 && (hold_mode==0)
+                                            && VDLR_reg != 8'b00000000)
+                                            begin
+                                                read_out = 1'b1;
+                                                #10 read_out = 1'b0;
+                                            end
+                                        end
+                                    end
+                                end
+                                else if ((Instruct == DDRDIOR) && (~EXTADD))
+                                begin    //Dual I/O DDR Read Mode
+                                    Address_in[2*addr_cnt] = SO_in;
+                                    Address_in[2*addr_cnt+1]= SI_in;
+                                    if (addr_cnt != 0)
+                                    begin
+                                        addr_cnt = addr_cnt + 1;
+                                    end
+                                    read_cnt = 0;
+                                    if (addr_cnt == 3*BYTE/2)
+                                    begin
+                                        addr_cnt = 0;
+                                        for(i=23;i>=0;i=i-1)
+                                        begin
+                                            addr_bytes[23-i] = Address_in[i];
+                                        end
+                                        addr_bytes[31:25] = 7'b0000000;
+                                        addr_bytes[24] = Bank_Addr_reg[0];
+                                        Address = addr_bytes;
+                                        change_addr = 1'b1;
+                                        #1 change_addr = 1'b0;
+                                        if (EHP)
+                                            bus_cycle_state = MODE_BYTE;
+                                        else
+                                            bus_cycle_state = DUMMY_BYTES;
+                                    end
+                                end
+                                else if ((Instruct==DDRDIOR4) ||
+                                        ((Instruct==DDRDIOR) && EXTADD))
+                                begin    //Dual I/O DDR Read Mode
+                                    Address_in[2*addr_cnt]   = SO_in;
+                                    Address_in[2*addr_cnt+1] = SI_in;
+                                    if (addr_cnt != 0)
+                                    begin
+                                        addr_cnt = addr_cnt + 1;
+                                    end
+                                    read_cnt = 0;
+                                    if (addr_cnt == 4*BYTE/2)
+                                    begin
+                                        addr_cnt = 0;
+                                        for(i=31;i>=0;i=i-1)
+                                        begin
+                                            addr_bytes[31-i] = Address_in[i];
+                                        end
+                                        Address = {7'b0000000,addr_bytes[24:0]};
+                                        change_addr = 1'b1;
+                                        #1 change_addr = 1'b0;
+                                        if (EHP)
+                                            bus_cycle_state = MODE_BYTE;
+                                        else
+                                        begin
+                                            bus_cycle_state = DUMMY_BYTES;
+                                            if (DOUBLE == 1'b1 && (hold_mode==0)
+                                            && VDLR_reg != 8'b00000000)
+                                            begin
+                                                read_out = 1'b1;
+                                                #10 read_out = 1'b0;
+                                            end
+                                        end
+                                    end
+                                end
+                                else if ((Instruct==DDRQIOR) && (~EXTADD) && QUAD)
+                                begin    //Quad I/O DDR Read Mode
+                                    Address_in[4*addr_cnt] = HOLDNeg_in;
+                                    Address_in[4*addr_cnt+1] = WPNeg_in;
+                                    Address_in[4*addr_cnt+2] = SO_in;
+                                    Address_in[4*addr_cnt+3] = SI_in;
+                                    if (addr_cnt != 0)
+                                    begin
+                                        addr_cnt = addr_cnt + 1;
+                                    end
+                                    read_cnt = 0;
+                                    if (addr_cnt == 3*BYTE/4)
+                                    begin
+                                        addr_cnt = 0;
+                                        for(i=23;i>=0;i=i-1)
+                                        begin
+                                            addr_bytes[23-i] = Address_in[i];
+                                        end
+                                        addr_bytes[31:25] = 7'b0000000;
+                                        addr_bytes[24] = Bank_Addr_reg[0];
+                                        Address = addr_bytes;
+                                        change_addr = 1'b1;
+                                    #1 change_addr = 1'b0;
+                                        bus_cycle_state = MODE_BYTE;
+                                    end
+                                end
+                                else if (QUAD && ((Instruct==DDRQIOR4) ||
+                                        ((Instruct==DDRQIOR) && EXTADD)))
+                                begin
+                                    Address_in[4*addr_cnt] = HOLDNeg_in;
+                                    Address_in[4*addr_cnt+1] = WPNeg_in;
+                                    Address_in[4*addr_cnt+2] = SO_in;
+                                    Address_in[4*addr_cnt+3] = SI_in;
+                                    if (addr_cnt != 0)
+                                    begin
+                                        addr_cnt = addr_cnt + 1;
+                                    end
+                                    read_cnt = 0;
+                                    if (addr_cnt == 4*BYTE/4)
+                                    begin
+                                        addr_cnt = 0;
+                                        for(i=31;i>=0;i=i-1)
+                                        begin
+                                            addr_bytes[31-i] = Address_in[i];
+                                        end
+                                        Address = {7'b0000000,addr_bytes[24:0]};
+                                        change_addr = 1'b1;
+                                        #1 change_addr = 1'b0;
+                                        bus_cycle_state = MODE_BYTE;
+                                    end
+                                end
+                            end
+                        end
+
+                        MODE_BYTE :
+                        begin
+                            if ((Instruct == DDRFR) || (Instruct == DDRFR4))
+                            begin
+                                mode_in[2*mode_cnt+1] = SI_in;
+                                mode_cnt = mode_cnt + 1;
+                                if (mode_cnt == BYTE/2)
+                                begin
+                                    mode_cnt = 0;
+                                    for(i=7;i>=0;i=i-1)
+                                    begin
+                                        mode_bytes[i] = mode_in[7-i];
+                                    end
+                                    bus_cycle_state = DUMMY_BYTES;
+                                    Return_DLP(Instruct, EHP, Latency_code,
+                                               dummy_cnt, start_dlp);
+                                    if (DOUBLE == 1'b1 && (hold_mode==0) &&
+                                       (VDLR_reg != 8'b00000000) && start_dlp)
+                                    begin
+                                        read_out = 1'b1;
+                                        #10 read_out = 1'b0;
+                                    end
+                                end
+                            end
+                            else if ((Instruct==DDRDIOR) || (Instruct==DDRDIOR4))
+                            begin
+                                mode_in[4*mode_cnt+2] = SO_in;
+                                mode_in[4*mode_cnt+3] = SI_in;
+                                mode_cnt = mode_cnt + 1;
+                                if (mode_cnt == BYTE/4)
+                                begin
+                                    mode_cnt = 0;
+                                    for(i=7;i>=0;i=i-1)
+                                    begin
+                                        mode_bytes[i] = mode_in[7-i];
+                                    end
+                                    bus_cycle_state = DUMMY_BYTES;
+                                    Return_DLP(Instruct, EHP, Latency_code,
+                                               dummy_cnt, start_dlp);
+                                    if (DOUBLE == 1'b1 && (hold_mode==0) &&
+                                       (VDLR_reg != 8'b00000000) && start_dlp)
+                                    begin
+                                        read_out = 1'b1;
+                                        #10 read_out = 1'b0;
+                                    end
+                                end
+                            end
+                            else if ((Instruct==DDRQIOR) || (Instruct==DDRQIOR4))
+                            begin
+                                mode_in[4] = HOLDNeg_in;
+                                mode_in[5] = WPNeg_in;
+                                mode_in[6] = SO_in;
+                                mode_in[7] = SI_in;
+                                for(i=7;i>=0;i=i-1)
+                                begin
+                                    mode_bytes[i] = mode_in[7-i];
+                                end
+                                bus_cycle_state = DUMMY_BYTES;
+                                Return_DLP(Instruct, EHP, Latency_code,
+                                               dummy_cnt, start_dlp);
+                                if (DOUBLE == 1'b1 && (hold_mode==0) &&
+                                    (VDLR_reg != 8'b00000000) && start_dlp)
+                                begin
+
+                                    read_out = 1'b1;
+                                    #10 read_out = 1'b0;
+                                end
+                            end
+                        end
+
+                        DATA_BYTES:
+                        begin
+                            if (hold_mode==0)
+                            begin
+                                if (DOUBLE == 1'b1 )
+                                begin
+                                    read_out = 1'b1;
+                                    #10 read_out = 1'b0;
+
+                                end
+                                else
+                                begin
+                                    if ((Instruct==READ) || (Instruct==RD4)   ||
+                                        (Instruct==FSTRD)|| (Instruct==FSTRD4)||
+                                        (Instruct==RDSR) || (Instruct==RDSR2) ||
+                                        (Instruct==RDCR) || (Instruct==OTPR)  ||
+                                        (Instruct==DOR) || (Instruct==DOR4) ||
+                                        (Instruct==DIOR)|| (Instruct==DIOR4)||
+                                        (Instruct==ABRD) || (Instruct==BRRD)  ||
+                                        (Instruct==ASPRD)|| (Instruct==DYBRD) ||
+                                        (Instruct==PPBRD)|| (Instruct == ECCRD) ||
+                                        (Instruct==PASSRD)|| (Instruct==RDID)||
+                                        (Instruct==RES) || (Instruct==REMS)  ||
+                                        (Instruct==PLBRD)|| (Instruct==DLPRD) ||
+                                        (current_state == AUTOBOOT &&
+                                        start_delay == 0) ||
+                                        (((Instruct==QOR) || (Instruct==QIOR) ||
+                                        (Instruct==QOR4) ||
+                                        (Instruct==QIOR4)) && QUAD))
+                                    begin
+                                        read_out = 1'b1;
+                                        #10 read_out = 1'b0;
+                                    end
+                                end
+                            end
+                        end
+
+                        DUMMY_BYTES:
+                        begin
+                            if (hold_mode==0)
+                            begin
+                                Return_DLP(Instruct, EHP, Latency_code,
+                                           dummy_cnt, start_dlp);
+
+                                if (DOUBLE == 1'b1 && VDLR_reg != 8'b00000000 &&
+                                    start_dlp)
+                                begin
+                                    read_out = 1'b1;
+                                    #10 read_out = 1'b0;
+                                end
+                            end
+                        end
+
+                    endcase
+                end
+            end
+
+            if (rising_edge_CSNeg_ipd)
+            begin
+                if (bus_cycle_state != DATA_BYTES)
+                begin
+                    if (bus_cycle_state == ADDRESS_BYTES && opcode_tmp == 8'hFF)
+                    begin
+                        Instruct = MBR;
+                    end
+                    bus_cycle_state = STAND_BY;
+                end
+                else
+                begin
+                    if (bus_cycle_state == DATA_BYTES)
+                    begin
+                        if (((mode_bytes[7:4] == 4'b1010) &&
+                            (Instruct==DIOR || Instruct==DIOR4 ||
+                            Instruct==QIOR || Instruct==QIOR4)) ||
+                            ((mode_bytes[7:4] == ~mode_bytes[3:0]) &&
+                            (Instruct == DDRFR  || Instruct == DDRFR4  ||
+                            Instruct == DDRDIOR || Instruct == DDRDIOR4 ||
+                            Instruct == DDRQIOR || Instruct == DDRQIOR4)))
+                            bus_cycle_state = ADDRESS_BYTES;
+                        else
+                            bus_cycle_state = STAND_BY;
+
+                        case (Instruct)
+                            WREN,
+                            WRDI,
+                            BE,
+                            SE,
+                            SE4,
+                            P4E,
+                            P4E4,
+                            CLSR,
+                            BRAC,
+                            RESET,
+                            PPBERS,
+                            PPBP,
+                            PLBWR,
+                            PGSP,
+                            PGRS,
+                            ERSP,
+                            ERRS:
+                            begin
+                                if ((HOLDNeg_in && ~QUAD) || QUAD)
+                                begin
+                                    if (data_cnt == 0)
+                                        write = 1'b0;
+                                end
+                            end
+
+                            WRR:
+                            begin
+                                if ((HOLDNeg_in && ~QUAD) || QUAD)
+                                begin
+                                    if (data_cnt == 8)
+                                    //If CS# is driven high after eight
+                                    //cycle,only the Status Register is
+                                    //written to.
+                                    begin
+                                        write = 1'b0;
+                                        if (BAR_ACC == 0)
+                                        begin
+                                            for(i=0;i<=7;i=i+1)
+                                            begin
+                                                Status_reg1_in[i]=
+                                                Data_in[7-i];
+                                            end
+                                        end
+                                        else
+                                        begin
+                                            if (P_ERR == 0 && E_ERR == 0)
+                                            begin
+                                                for(i=0;i<=7;i=i+1)
+                                                begin
+                                                    Bank_Addr_reg_in[i]=
+                                                    Data_in[7-i];
+                                                end
+                                            end
+                                        end
+                                    end
+                                    else if (data_cnt == 16)
+                                    //After the 16th cycle both the
+                                    //Status and Configuration Registers
+                                    //are written to.
+                                    begin
+                                        write = 1'b0;
+                                        if (BAR_ACC == 0)
+                                        begin
+                                            cfg_write = 1'b1;
+                                            for(i=0;i<=7;i=i+1)
+                                            begin
+                                                Status_reg1_in[i]=
+                                                Data_in[7-i];
+                                                Config_reg1_in[i]=
+                                                Data_in[15-i];
+                                            end
+                                        end
+                                        else
+                                        begin
+                                            if (P_ERR == 0 && E_ERR == 0)
+                                            begin
+                                                for(i=0;i<=7;i=i+1)
+                                                begin
+                                                    Bank_Addr_reg_in[i]=
+                                                    Data_in[7-i];
+                                                end
+                                            end
+                                        end
+                                    end
+                                end
+                            end
+
+                            PP,
+                            PP4,
+                            OTPP:
+                            begin
+                                if ((HOLDNeg_in && ~QUAD) || QUAD)
+                                begin
+                                    if (data_cnt > 0)
+                                    begin
+                                        if ((data_cnt % 8) == 0)
+                                        begin
+                                            write = 1'b0;
+                                            for(i=0;i<=PageSize;i=i+1)
+                                            begin
+                                                for(j=7;j>=0;j=j-1)
+                                                begin
+                                                    if ((Data_in[(i*8)+(7-j)])
+                                                        !== 1'bX)
+                                                    begin
+                                                        Byte_slv[j] =
+                                                        Data_in[(i*8)+(7-j)];
+                                                    end
+                                                end
+                                                WByte[i] = Byte_slv;
+						//$display("%m: Loc: %x Byte: %x",i,Byte_slv);
+                                            end
+
+                                            if (data_cnt > (PageSize+1)*BYTE)
+                                                Byte_number = PageSize;
+                                            else
+                                                Byte_number =
+                                                    ((data_cnt/8) - 1);
+                                        end
+                                    end
+                                end
+                            end
+
+                            QPP,
+                            QPP4:
+                            begin
+                                if (data_cnt >0)
+                                begin
+                                    if ((data_cnt % 2) == 0)
+                                    begin
+                                        write = 1'b0;
+                                        quad_pg = 1'b0;
+                                        for(i=0;i<=PageSize;i=i+1)
+                                        begin
+                                            for(j=1;j>=0;j=j-1)
+                                            begin
+                                                Quad_slv =
+                                                quad_data_in[(i*2)+(1-j)];
+                                                if (j==1)
+                                                    Byte_slv[7:4] = Quad_slv;
+                                                else if (j==0)
+                                                    Byte_slv[3:0] = Quad_slv;
+                                            end
+                                            WByte[i] = Byte_slv;
+                                        end
+                                        if (data_cnt > (PageSize+1)*2)
+                                            Byte_number = PageSize;
+                                        else
+                                            Byte_number = ((data_cnt/2)-1);
+                                    end
+                                end
+                            end
+
+                            ABWR:
+                            begin
+                                if ((HOLDNeg_in && ~QUAD) || QUAD)
+                                begin
+                                    if (data_cnt == 32)
+                                    begin
+                                        write = 1'b0;
+                                        for(j=0;j<=31;j=j+1)
+                                        begin
+                                            AutoBoot_reg_in[j] = Data_in[31-j];
+                                        end
+                                    end
+                                end
+                            end
+
+                            BRWR:
+                            begin
+                                if ((HOLDNeg_in && ~QUAD) || QUAD)
+                                begin
+                                    if (data_cnt == 8)
+                                    begin
+                                        write = 1'b0;
+                                        for(j=0;j<=7;j=j+1)
+                                        begin
+                                            Bank_Addr_reg_in[j] = Data_in[7-j];
+                                        end
+                                    end
+                                end
+                            end
+
+                            ASPP:
+                            begin
+                                if ((HOLDNeg_in && ~QUAD) || QUAD)
+                                begin
+                                    if (data_cnt == 16)
+                                    begin
+                                        write = 1'b0;
+                                        for(j=0;j<=15;j=j+1)
+                                        begin
+                                            ASP_reg_in[j] = Data_in[15-j];
+                                        end
+                                    end
+                                end
+                            end
+
+                            DYBWR:
+                            begin
+                                if ((HOLDNeg_in && ~QUAD) || QUAD)
+                                begin
+                                    if (data_cnt == 8)
+                                    begin
+                                        write = 1'b0;
+                                        for(j=0;j<=7;j=j+1)
+                                        begin
+                                            DYBAR_in[j] = Data_in[7-j];
+                                        end
+                                    end
+                                end
+                            end
+
+                            PNVDLR:
+                            begin
+                                if ((HOLDNeg_in && ~QUAD) || QUAD)
+                                begin
+                                    if (data_cnt == 8)
+                                    begin
+                                        write = 1'b0;
+                                        for(j=0;j<=7;j=j+1)
+                                        begin
+                                            NVDLR_reg_in[j] = Data_in[7-j];
+                                        end
+                                    end
+                                end
+                            end
+
+                            WVDLR:
+                            begin
+                                if ((HOLDNeg_in && ~QUAD) || QUAD)
+                                begin
+                                    if (data_cnt == 8)
+                                    begin
+                                        write = 1'b0;
+                                        for(j=0;j<=7;j=j+1)
+                                        begin
+                                            VDLR_reg_in[j] = Data_in[7-j];
+                                        end
+                                    end
+                                end
+                            end
+
+                            PASSP:
+                            begin
+                                if ((HOLDNeg_in && ~QUAD) || QUAD)
+                                begin
+                                    if (data_cnt == 64)
+                                    begin
+                                        write = 1'b0;
+                                        for(j=1;j<=8;j=j+1)
+                                        begin
+                                            for(k=1;k<=8;k=k+1)
+                                            begin
+                                                Password_reg_in[j*8-k] =
+                                                            Data_in[8*(j-1)+k-1];
+                                            end
+                                        end
+                                    end
+                                end
+                            end
+
+                            PASSU:
+                            begin
+                                if ((HOLDNeg_in && ~QUAD) || QUAD)
+                                begin
+                                    if (data_cnt == 64)
+                                    begin
+                                        write = 1'b0;
+                                        for(j=1;j<=8;j=j+1)
+                                        begin
+                                            for(k=1;k<=8;k=k+1)
+                                            begin
+                                                PASS_TEMP[j*8-k] =
+                                                            Data_in[8*(j-1)+k-1];
+                                            end
+                                        end
+                                    end
+                                end
+                            end
+                        endcase
+                    end
+                end
+            end
+        end
+    end
+
+///////////////////////////////////////////////////////////////////////////////
+// Timing control for the Page Program
+///////////////////////////////////////////////////////////////////////////////
+    time pob;
+    time elapsed_pgm;
+    time elapsed_tsu;
+    time start_pgm;
+    time start_tsu;
+    time duration_pgm;
+    time duration_tsu;
+    event pdone_event;
+
+    always @(rising_edge_PSTART)
+    begin
+        if ((Instruct == PP) || (Instruct == PP4) || (Instruct == OTPP) ||
+           (Instruct == QPP) || (Instruct == QPP4))
+            if (PageSize == 255)
+            begin
+                pob = tdevice_PP_256;
+            end
+            else
+            begin
+                pob = tdevice_PP_512;
+            end
+        else
+            pob = tdevice_BP;
+        if ((rising_edge_PSTART) && PDONE)
+        begin
+            elapsed_pgm = 0;
+            duration_pgm = pob;
+            PDONE = 1'b0;
+            ->pdone_event;
+            start_pgm = $time;
+        end
+    end
+
+    always @(posedge PGSUSP)
+    begin
+        if (PGSUSP && (~PDONE))
+        begin
+            disable pdone_process;
+            elapsed_pgm = $time - start_pgm;
+            duration_pgm = pob - elapsed_pgm;
+            PDONE = 1'b0;
+        end
+    end
+
+    always @(posedge PGRES)
+    begin
+        start_pgm = $time;
+        ->pdone_event;
+    end
+
+    always @(pdone_event)
+    begin:pdone_process
+        PDONE = 1'b0;
+        #duration_pgm PDONE = 1'b1;
+    end
+
+    always @(SI)
+    begin
+        if ((Instruct == PGSP) || (Instruct == PGRS) ||
+           (Instruct == ERSP) || (Instruct == ERRS))
+        begin
+            start_tsu = $time;
+        end
+    end
+
+    always @(posedge SCK)
+    begin
+        if ((Instruct == PGSP) || (Instruct == PGRS) ||
+           (Instruct == ERSP) || (Instruct == ERRS))
+        begin
+            elapsed_tsu = $time - start_tsu;
+            duration_tsu = tdevice_TSU - elapsed_tsu;
+            if (duration_tsu > 0)
+            begin
+                TSU = 1'b0;
+            end
+            else
+            begin
+                TSU = 1'b1;
+                $display("Warning at", $time);
+                $display("tSU max time violation");
+            end
+        end
+    end
+///////////////////////////////////////////////////////////////////////////////
+// Timing control for the Write Status Register
+///////////////////////////////////////////////////////////////////////////////
+    time wob;
+    always @(posedge WSTART)
+    begin:wdone_process
+        wob = tdevice_WRR;
+        if (WSTART && WDONE)
+        begin
+            WDONE = 1'b0;
+            #wob WDONE = 1'b1;
+        end
+    end
+
+///////////////////////////////////////////////////////////////////////////////
+// Reset Timing
+///////////////////////////////////////////////////////////////////////////////
+
+    time startlo;
+    time starthi;
+    time durationlo;
+    time durationhi;
+
+    always @(negedge RSTNeg_in or Instruct)
+    begin
+        if (~RSTNeg_in)
+        begin
+            RST = 1'b1;
+            #200000 RST = 1'b0;  // 200 ns
+        end
+        else if (Instruct == RESET)
+        begin
+            Reseted = 1'b0;
+            #10000 Reseted = 1'b1;   //  10 ns
+        end
+    end
+
+    always @(RST_in or rising_edge_Reseted) // Reset done,program terminated
+    begin
+        if ((RST_in && ~RST) || (rising_edge_Reseted))
+            disable pdone_process;
+            disable edone_process;
+            disable wdone_process;
+            PDONE = 1'b1;
+            EDONE = 1'b1;
+            WDONE = 1'b1;
+    end
+
+///////////////////////////////////////////////////////////////////////////////
+// Timing control for the Bulk Erase
+///////////////////////////////////////////////////////////////////////////////
+    time seo;
+    time beo;
+    event edone_event;
+    time elapsed_ers;
+    time start_ers;
+    time duration_ers;
+
+    always @(rising_edge_ESTART)
+    begin
+        if (UniformSec)
+        begin
+            seo = tdevice_SE256;
+        end
+        else
+        begin
+            seo = tdevice_SE64;
+        end
+        beo = tdevice_BE;
+        if ((rising_edge_ESTART) && EDONE)
+        begin
+            if (Instruct == BE)
+            begin
+                duration_ers = beo;
+            end
+            else
+            begin
+                duration_ers = seo;
+            end
+            elapsed_ers = 0;
+            EDONE = 1'b0;
+            ->edone_event;
+            start_ers = $time;
+        end
+    end
+
+    always @(posedge ESUSP)
+    begin
+        if (ESUSP && (~EDONE))
+        begin
+            disable edone_process;
+            elapsed_ers = $time - start_ers;
+            duration_ers = seo - elapsed_ers;
+            EDONE = 1'b0;
+        end
+    end
+
+    always @(posedge ERES)
+    begin
+        if  (ERES && (~EDONE))
+        begin
+            start_ers = $time;
+            ->edone_event;
+        end
+    end
+
+    always @(edone_event)
+    begin : edone_process
+        EDONE = 1'b0;
+        #duration_ers EDONE = 1'b1;
+    end
+
+    ///////////////////////////////////////////////////////////////////
+    // Process for clock frequency determination
+    ///////////////////////////////////////////////////////////////////
+    always @(posedge SCK_ipd)
+    begin : clock_period
+        if (SCK_ipd)
+        begin
+            SCK_cycle = $time - prev_SCK;
+            prev_SCK = $time;
+        end
+    end
+
+//    /////////////////////////////////////////////////////////////////////////
+//    // Main Behavior Process
+//    // combinational process for next state generation
+//    /////////////////////////////////////////////////////////////////////////
+
+    reg rising_edge_PDONE = 1'b0;
+    reg rising_edge_EDONE = 1'b0;
+    reg rising_edge_WDONE = 1'b0;
+    reg falling_edge_write = 1'b0;
+    reg falling_edge_PPBERASE_in = 1'b0;
+    reg falling_edge_PASSULCK_in = 1'b0;
+
+    integer i;
+    integer j;
+
+    always @(rising_edge_PoweredUp or falling_edge_write or
+             falling_edge_RSTNeg or rising_edge_PDONE or rising_edge_WDONE or
+             rising_edge_EDONE or ERSSUSP_out_event or rising_edge_RSTNeg or
+             PRGSUSP_out_event or rising_edge_CSNeg_ipd or rising_edge_RST_out
+             or falling_edge_PPBERASE_in or falling_edge_PASSULCK_in or RST_out)
+    begin: StateGen1
+
+        integer sect;
+
+        if (rising_edge_PoweredUp && RSTNeg_in && RST_out)
+        begin
+            if (ABE == 1 && RPME !== 0 )
+            begin
+                next_state     = AUTOBOOT;
+                read_cnt       = 0;
+                byte_cnt       = 1;
+                read_addr      = {AutoBoot_reg[31:9], 9'b0};
+                start_delay    = AutoBoot_reg[8:1];
+                start_autoboot = 0;
+                ABSD           = AutoBoot_reg[8:1];
+            end
+            else
+                next_state = IDLE;
+        end
+        else if (PoweredUp)
+        begin
+            if (RST_out == 1'b0)
+                next_state = current_state;
+            else if (falling_edge_write && Instruct == RESET)
+            begin
+                if (ABE == 1 && RPME !== 0)
+                begin
+                    read_cnt       = 0;
+                    byte_cnt       = 1;
+                    read_addr      = {AutoBoot_reg[31:9], 9'b0};
+                    start_delay    = AutoBoot_reg[8:1];
+                    ABSD           = AutoBoot_reg[8:1];
+                    start_autoboot = 0;
+                    next_state     = AUTOBOOT;
+                end
+                else
+                    next_state = IDLE;
+            end
+            else 
+            begin
+                case (current_state)
+                    RESET_STATE :
+                    begin
+                        if ((rising_edge_RST_out && RSTNeg_in) ||
+                        (rising_edge_RSTNeg && RST_out))
+                        begin
+                            if (ABE == 1 && RPME!== 0)
+                            begin
+                                next_state = AUTOBOOT;
+                                read_cnt       = 0;
+                                byte_cnt       = 1;
+                                read_addr      = {AutoBoot_reg[31:9],9'b0};
+                                start_delay    = AutoBoot_reg[8:1];
+                                start_autoboot = 0;
+                                ABSD           = AutoBoot_reg[8:1];
+                            end
+                            else
+                                next_state = IDLE;
+                        end
+                    end
+
+                    IDLE :
+                    begin
+                        if (falling_edge_write && RdPswdProtMode == 0)
+                        begin
+                            if (Instruct == WRR && WEL == 1 && BAR_ACC == 0
+                            && (((~(SRWD == 1 && ~WPNeg_in))&& ~QUAD) || QUAD))
+                            // can not execute if HPM is entered or
+                            // if WEL bit is zero
+                                if (((TBPROT==1 && Config_reg1_in[5]==1'b0) ||
+                                     (TBPARM==1 && Config_reg1_in[2]==1'b0) ||
+                                     (BPNV  ==1 && Config_reg1_in[3]==1'b0)) &&
+                                     cfg_write)
+                                begin
+                                    $display ("WARNING: Changing value of ");
+                                    $display ("Configuration Register OTP ");
+                                    $display ("bit from 1 to 0 is not");
+                                    $display ("allowed!!!");
+                                end
+                                else
+                                begin
+                                    next_state = WRITE_SR;
+                                end
+                            else if (Instruct == WRR && BAR_ACC == 1)
+                            begin
+                            // Write to the lower address bits of the BAR
+                                if (P_ERR == 0 && E_ERR == 0)
+                                begin
+                                    next_state = IDLE;
+                                end
+                            end
+                            else if ((Instruct == PP || Instruct == QPP ||
+                                      Instruct == PP4 || Instruct == QPP4) &&
+                                      WEL == 1)
+                            begin
+                                ReturnSectorID(sect,Address);
+                                pgm_page = Address / (PageSize+1);
+                                if (Sec_Prot[sect]== 0 && PPB_bits[sect]== 1 &&
+                                    DYB_bits[sect]== 1)
+                                begin
+                                    next_state = PAGE_PG;
+                                end
+                            end
+                            else if (Instruct==OTPP && WEL==1 && FREEZE==0)
+                            begin
+                                if (((((Address>=16'h0010 && Address<=16'h0013)
+                                    ||(Address>=16'h0020 && Address<=16'h00FF))
+                                    && LOCK_BYTE1[Address/32] == 1) ||
+                                    ((Address>=16'h0100 && Address<=16'h01FF)
+                                    && LOCK_BYTE2[(Address-16'h0100)/32]==1) ||
+                                    ((Address>=16'h0200 && Address<=16'h02FF)
+                                    && LOCK_BYTE3[(Address-16'h0200)/32]==1) ||
+                                    ((Address>=16'h0300 && Address<=16'h03FF)
+                                    && LOCK_BYTE4[(Address-16'h0300)/32] == 1))
+                                    && (Address + Byte_number <= OTPHiAddr))
+                                next_state =  OTP_PG;
+                            end
+                            else if ((Instruct == SE || Instruct == SE4)
+                                    && WEL == 1)
+                            begin
+                                ReturnSectorID(sect,Address);
+                                if (UniformSec || (TopBoot && sect < 510) ||
+                                   (BottomBoot && sect > 31))
+                                begin
+                                    if (Sec_Prot[sect]== 0 && PPB_bits[sect]== 1
+                                         && DYB_bits[sect]== 1)
+                                        next_state =  SECTOR_ERS;
+                                end
+                                else if ((TopBoot && sect >= 510) ||
+                                        (BottomBoot && sect <= 31))
+                                begin
+                                    if (Sec_ProtSE == 32 && ASP_ProtSE == 32)
+                                    //Sector erase command is applied to a
+                                    //64 KB range that includes 4 KB sectors.
+                                        next_state =  SECTOR_ERS;
+                                end
+                            end
+                            else if ((Instruct == P4E || Instruct == P4E4)
+                                    && WEL == 1)
+                            begin
+                                ReturnSectorID(sect,Address);
+                                if (UniformSec || (TopBoot && sect < 510) ||
+                                   (BottomBoot && sect > 31))
+                                begin
+                                    $display("The instruction is applied to");
+                                    $display("a sector that is larger than");
+                                    $display("4 KB.");
+                                    $display("Instruction is ignored!!!");
+                                end
+                                else
+                                begin
+                                     if (Sec_Prot[sect]== 0 &&
+                                      PPB_bits[sect]== 1 && DYB_bits[sect]== 1)
+                                        next_state =  SECTOR_ERS;
+                                end
+                            end
+                            else if (Instruct == BE && WEL == 1 &&
+                                (Status_reg1[4]== 0 && Status_reg1[3]== 0 &&
+                                    Status_reg1[2]== 0))
+                                next_state = BULK_ERS;
+                            else if (Instruct == ABWR && WEL == 1)
+                                //Autoboot Register Write Command
+                                next_state = AUTOBOOT_PG;
+                            else if (Instruct == BRWR)
+                                //Bank Register Write Command
+                                next_state = IDLE;
+                            else if (Instruct == ASPP && WEL == 1)
+                            begin
+                                //ASP Register Program Command
+                                if (~(ASPOTPFLAG))
+                                    next_state = ASP_PG;
+                            end
+                            else if (Instruct == PLBWR && WEL == 1 &&
+                                     RdPswdProtEnable == 0)
+                                next_state = PLB_PG;
+                            else if (Instruct == PASSP && WEL == 1)
+                            begin
+                                if (~(PWDMLB== 0 && PSTMLB== 1))
+                                    next_state = PASS_PG;
+                            end
+                            else if (Instruct == PASSU && WEL && ~WIP)
+                                next_state = PASS_UNLOCK;
+                            else if (Instruct == PPBP && WEL == 1)
+                                next_state <= PPB_PG;
+                            else if (Instruct == PPBERS && WEL && PPBOTP)
+                                next_state <= PPB_ERS;
+                            else if (Instruct == DYBWR && WEL == 1)
+                                next_state = DYB_PG;
+                            else if (Instruct == PNVDLR && WEL == 1)
+                                next_state = NVDLR_PG;
+                            else
+                                next_state = IDLE;
+                        end
+                        if (falling_edge_write && RdPswdProtMode == 1 && ~WIP)
+                        begin
+                            if (Instruct == PASSU)
+                                next_state = PASS_UNLOCK;
+                        end
+                    end
+
+                    AUTOBOOT :
+                    begin
+                        if (rising_edge_CSNeg_ipd)
+                            next_state = IDLE;
+                    end
+
+                    WRITE_SR :
+                    begin
+                        if (rising_edge_WDONE)
+                            next_state = IDLE;
+                    end
+
+                    PAGE_PG :
+                    begin
+                        if (PRGSUSP_out_event && PRGSUSP_out == 1)
+                            next_state = PG_SUSP;
+                        else if (rising_edge_PDONE)
+                            next_state = IDLE;
+                    end
+
+                    PG_SUSP :
+                    begin
+                        if (falling_edge_write)
+                        begin
+                            if (Instruct == BRWR)
+                                //Bank Register Write Command
+                                next_state = PG_SUSP;
+                            else if (Instruct == PGRS)
+                                next_state = PAGE_PG;
+                        end
+                    end
+
+                    OTP_PG :
+                    begin
+                        if (rising_edge_PDONE)
+                            next_state = IDLE;
+                    end
+
+                    BULK_ERS :
+                    begin
+                        if (rising_edge_EDONE)
+                            next_state = IDLE;
+                    end
+
+                    SECTOR_ERS :
+                    begin
+                        if (ERSSUSP_out_event && ERSSUSP_out == 1)
+                            next_state = ERS_SUSP;
+                        else if (rising_edge_EDONE)
+                            next_state = IDLE;
+                    end
+
+                    ERS_SUSP :
+                    begin
+                        if (falling_edge_write)
+                        begin
+                            if ((Instruct == PP || Instruct == QPP ||
+                                 Instruct == PP4 || Instruct == QPP4) &&
+                                 WEL == 1)
+                            begin
+                                if ((PARAM_REGION &&
+                                     SectorSuspend != Address/(SecSize+1)) ||
+                                   (~PARAM_REGION && SectorSuspend !=
+                                     Address/(SecSize+1)+30*b_act))
+                                begin
+                                    ReturnSectorID(sect,Address);
+                                    pgm_page = Address / (PageSize+1);
+                                    if (PPB_bits[sect]== 1 &&
+                                        DYB_bits[sect]== 1)
+                                    begin
+                                        next_state = ERS_SUSP_PG;
+                                    end
+                                end
+                            end
+                            else if (Instruct == BRWR)
+                            begin
+                                //Bank Register Write Command
+                                next_state = ERS_SUSP;
+                            end
+                            else if (Instruct == DYBWR && WEL == 1)
+                                next_state = DYB_PG;
+                            else if  (Instruct == ERRS)
+                                next_state = SECTOR_ERS;
+                        end
+                    end
+
+                    ERS_SUSP_PG :
+                    begin
+                        if (rising_edge_PDONE)
+                            next_state = ERS_SUSP;
+                        else if (PRGSUSP_out_event && PRGSUSP_out == 1)
+                            next_state = ERS_SUSP_PG_SUSP;
+                    end
+
+                    ERS_SUSP_PG_SUSP :
+                    begin
+                        if (rising_edge_PDONE)
+                            next_state = ERS_SUSP;
+                        if (falling_edge_write)
+                        begin
+                            if (Instruct == BRWR)
+                            begin
+                                next_state =  ERS_SUSP_PG_SUSP;
+                            end
+                            else if (Instruct == PGRS)
+                            begin
+                                next_state =  ERS_SUSP_PG;
+                            end
+                        end
+                    end
+
+                    PASS_PG :
+                    begin
+                    if (rising_edge_PDONE)
+                        next_state = IDLE;
+                    end
+
+                    PASS_UNLOCK :
+                    begin
+                    if (falling_edge_PASSULCK_in)
+                        next_state = IDLE;
+                    end
+
+                    PPB_PG :
+                    begin
+                    if (rising_edge_PDONE)
+                        next_state = IDLE;
+                    end
+
+                    PPB_ERS :
+                    begin
+                    if (falling_edge_PPBERASE_in)
+                        next_state = IDLE;
+                    end
+
+                    AUTOBOOT_PG :
+                    begin
+                    if (rising_edge_PDONE)
+                        next_state = IDLE;
+                    end
+
+                    PLB_PG :
+                    begin
+                    if (rising_edge_PDONE)
+                        next_state = IDLE;
+                    end
+
+                    DYB_PG :
+                    begin
+                    if (rising_edge_PDONE)
+                        if (ES)
+                            next_state = ERS_SUSP;
+                        else
+                            next_state = IDLE;
+                    end
+
+                    ASP_PG :
+                    begin
+                    if (rising_edge_PDONE)
+                        next_state = IDLE;
+                    end
+                                        
+                    NVDLR_PG :
+                    begin
+                    if (rising_edge_PDONE)
+                        next_state = IDLE;
+                    end
+
+                endcase
+            end
+        end
+    end
+
+    ///////////////////////////////////////////////////////////////////////////
+    //FSM Output generation and general functionality
+    ///////////////////////////////////////////////////////////////////////////
+    reg rising_edge_read_out = 1'b0;
+    reg Instruct_event       = 1'b0;
+    reg change_addr_event    = 1'b0;
+    reg current_state_event  = 1'b0;
+    reg rising_edge_DP_out   = 1'b0;
+
+    integer WData [0:511];
+    integer WOTPData;
+    integer Addr;
+    integer Addr_tmp;
+
+    always @(Instruct_event)
+    begin
+        read_cnt = 0;
+        byte_cnt = 1;
+        rd_fast  = 1'b1;
+        dual     = 1'b0;
+        rd_slow  = 1'b0;
+        any_read = 1'b0;
+    end
+
+    always @(rising_edge_read_out)
+    begin
+        if (rising_edge_read_out == 1'b1)
+        begin
+            if (PoweredUp == 1'b1)
+            begin
+                oe_z = 1'b1;
+                #1000 oe_z = 1'b0;
+                oe = 1'b1;
+                #1000 oe = 1'b0;
+            end
+        end
+    end
+
+    always @(change_addr_event)
+    begin
+        if (change_addr_event)
+        begin
+            read_addr = Address;
+        end
+    end
+
+    always @(posedge PASSACC_out)
+    begin
+        Status_reg1[0] = 1'b0; //WIP
+        PASSACC_in = 1'b0;
+    end
+
+    always @(Instruct or posedge start_autoboot or oe or current_state_event or
+             falling_edge_write or posedge PDONE or posedge WDONE or oe_z or
+             posedge EDONE or ERSSUSP_out or rising_edge_Reseted or
+             rising_edge_PoweredUp or rising_edge_CSNeg_ipd or PRGSUSP_out or
+             Address)
+    begin: Functionality
+    integer i,j;
+    integer sect;
+
+        if (rising_edge_PoweredUp)
+        begin
+            //the default condition after power-up
+            //The Bank Address Register is loaded to all zeroes
+            Bank_Addr_reg = 8'h0;
+            //The Configuration Register FREEZE bit is cleared.
+            Config_reg1[0] = 0;
+            //The WEL bit is cleared.
+            Status_reg1[1] = 0;
+            //When BPNV is set to '1'. the BP2-0 bits in Status Register are
+            //volatile and will be reset binary 111 after power-on reset
+            if (BPNV == 1  && FREEZE == 0 ) //&& LOCK == 0
+            begin
+                Status_reg1[4] = 1'b0;// BP2
+                Status_reg1[3] = 1'b0;// BP1
+                Status_reg1[2] = 1'b0;// BP0
+                BP_bits = {Status_reg1[4],Status_reg1[3],Status_reg1[2]};
+                change_BP = 1'b1;
+                #1000 change_BP = 1'b0;
+            end
+
+            //As shipped from the factory, all devices default ASP to the
+            //Persistent Protection mode, with all sectors unprotected,
+            //when power is applied. The device programmer or host system must
+            //then choose which sector protection method to use.
+            //For Persistent Protection mode, PPBLOCK defaults to "1"
+            PPBL[0] = 1'b1;
+
+            //All the DYB power-up in the unprotected state
+            DYB_bits = {542{1'b1}};
+
+        end
+
+        if (Instruct == RESET)
+        begin
+            //EXTADD is cleared to “0”
+            Bank_Addr_reg[7] = 1'b0;
+            //P_ERR bit is cleared
+            Status_reg1[6] = 1'b0;
+            //E_ERR bit is cleared
+            Status_reg1[5] = 1'b0;
+            //The WEL bit is cleared.
+            Status_reg1[1] = 1'b0;
+            //The WIP bit is cleared.
+            Status_reg1[0] = 1'b0;
+            //The ES bit is cleared.
+            Status_reg2[1] = 1'b0;
+            //The PS bit is cleared.
+            Status_reg2[0] = 1'b0;
+            //When BPNV is set to '1'. the BP2-0 bits in Status
+            //Register are volatile and will be reseted after
+            //reset command
+            if (BPNV == 1  && FREEZE == 0) //&& LOCK== 0
+            begin
+                Status_reg1[4] = 1'b1;
+                Status_reg1[3] = 1'b1;
+                Status_reg1[2] = 1'b1;
+
+                BP_bits = {Status_reg1[4],Status_reg1[3],
+                        Status_reg1[2]};
+                change_BP = 1'b1;
+                #1000 change_BP = 1'b0;
+            end
+        end
+
+        case (current_state)
+            IDLE :
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                ASP_ProtSE = 0;
+                Sec_ProtSE = 0;
+
+                if (BottomBoot)
+                begin
+                    for (j=31;j>=0;j=j-1)
+                    begin
+                        if (PPB_bits[j] == 1 && DYB_bits[j] == 1)
+                        begin
+                            ASP_ProtSE = ASP_ProtSE + 1;
+                        end
+                        if (Sec_Prot[j] == 0)
+                        begin
+                            Sec_ProtSE = Sec_ProtSE + 1;
+                        end
+                    end
+                end
+                else if (TopBoot)
+                begin
+                    for (j=541;j>=510;j=j-1)
+                    begin
+                        if (PPB_bits[j] == 1 && DYB_bits[j] == 1)
+                        begin
+                            ASP_ProtSE = ASP_ProtSE + 1;
+                        end
+                        if (Sec_Prot[j] == 0)
+                        begin
+                            Sec_ProtSE = Sec_ProtSE + 1;
+                        end
+                    end
+                end
+
+                if (falling_edge_write && RdPswdProtMode == 1)
+                begin
+                    if(Instruct == PASSU)
+                    begin
+                        if (~WIP)
+                        begin
+                            PASSULCK_in = 1;
+                            Status_reg1[0] = 1'b1; //WIP
+                        end
+                        else
+                        begin
+                            $display ("The PASSU command cannot be accepted");
+                            $display (" any faster than once every 100us");
+                        end
+                    end
+                    else if (Instruct == CLSR)
+                    begin
+                    //The Clear Status Register Command resets bit SR1[5]
+                    //(Erase Fail Flag) and bit SR1[6] (Program Fail Flag)
+                        Status_reg1[5] = 0;
+                        Status_reg1[6] = 0;
+                    end
+                end
+
+                if (falling_edge_write && RdPswdProtMode == 0)
+                begin
+                    read_cnt = 0;
+                    byte_cnt = 1;
+                    if (Instruct == WREN)
+                        Status_reg1[1] = 1'b1;
+                    else if (Instruct == WRDI)
+                        Status_reg1[1] = 0;
+                    else if ((Instruct == WRR) && WEL == 1 && WDONE == 1 &&
+                              BAR_ACC == 0)
+                    begin
+                        if (((~(SRWD == 1 && ~WPNeg_in))&& ~QUAD) || QUAD)
+                        begin
+                            if (((TBPROT==1 && Config_reg1_in[5]==1'b0) ||
+                                 (TBPARM==1 && Config_reg1_in[2]==1'b0) ||
+                                 (BPNV  ==1 && Config_reg1_in[3]==1'b0)) &&
+                                 cfg_write)
+                            begin
+                                // P_ERR bit is set to 1
+                                Status_reg1[6] = 1'b1;
+                            end
+                            else
+                            begin
+                            // can not execute if Hardware Protection Mode
+                            // is entered or if WEL bit is zero
+                                WSTART = 1'b1;
+                                WSTART <= #5 1'b0;
+                                Status_reg1[0] = 1'b1;
+                            end
+                        end
+                        else
+                            Status_reg1[1] = 0;
+                    end
+                    else if ((Instruct == PP || Instruct == PP4) && WEL ==1 &&
+                              PDONE == 1 )
+                    begin
+                        ReturnSectorID(sect,Address);
+                        if (Sec_Prot[sect] == 0 &&
+                            PPB_bits[sect]== 1 && DYB_bits[sect]== 1)
+                        begin
+                            PSTART  = 1'b1;
+                            PSTART <= #5 1'b0;
+                            PGSUSP  = 0;
+                            PGRES   = 0;
+                            INITIAL_CONFIG = 1;
+                            Status_reg1[0] = 1'b1;
+                            SA      = sect;
+                            Addr    = Address;
+                            Addr_tmp= Address;
+                            wr_cnt  = Byte_number;
+                            for (i=wr_cnt;i>=0;i=i-1)
+                            begin
+                                if (Viol != 0)
+                                    WData[i] = -1;
+			        else begin
+                                        WData[i] = WByte[i];
+					//$display("%m: Loc: %x WData: %x",i,WData[i]);
+			        end
+                            end
+                        end
+                        else
+                        begin
+                        //P_ERR bit will be set when the user attempts to
+                        //to program within a protected main memory sector
+                            Status_reg1[6] = 1'b1; //P_ERR
+                            Status_reg1[1] = 1'b0; //WEL
+                        end
+                    end
+                    else if ((Instruct == QPP || Instruct == QPP4) && WEL ==1 &&
+                              PDONE == 1 )
+                    begin
+                        ReturnSectorID(sect,Address);
+                        pgm_page = Address / (PageSize+1);
+                        if (Sec_Prot[sect] == 0 &&
+                            PPB_bits[sect]== 1 && DYB_bits[sect]== 1)
+                        begin
+                            PSTART  = 1'b1;
+                            PSTART <= #5 1'b0;
+                            PGSUSP  = 0;
+                            PGRES   = 0;
+                            INITIAL_CONFIG = 1;
+//                            QPP_page[pgm_page] = 1'b1;
+                            Status_reg1[0] = 1'b1;
+                            SA      = sect;
+                            Addr    = Address;
+                            Addr_tmp= Address;
+                            wr_cnt  = Byte_number;
+                            for (i=wr_cnt;i>=0;i=i-1)
+                            begin
+                                if (Viol != 0)
+                                    WData[i] = -1;
+                                else
+                                    WData[i] = WByte[i];
+                            end
+                        end
+                        else
+                        begin
+                        //P_ERR bit will be set when the user attempts to
+                        //to program within a protected main memory sector
+                            Status_reg1[6] = 1'b1; //P_ERR
+                            Status_reg1[1] = 1'b0; //WEL
+                        end
+                    end
+                    else if (Instruct == OTPP && WEL == 1)
+                    begin
+                        // As long as the FREEZE bit remains cleared to a logic
+                        // '0' the OTP address space is programmable.
+                        if (FREEZE == 0)
+                        begin
+                            if (((((Address>= 16'h0010 && Address<= 16'h0013) ||
+                                (Address >= 16'h0020 && Address <= 16'h00FF))
+                                && LOCK_BYTE1[Address/32] == 1) ||
+                                ((Address >= 16'h0100 && Address <= 16'h01FF)
+                                && LOCK_BYTE2[(Address-16'h0100)/32] == 1) ||
+                                ((Address >= 16'h0200 && Address <= 16'h02FF)
+                                && LOCK_BYTE3[(Address-16'h0200)/32] == 1) ||
+                                ((Address >= 16'h0300 && Address <= 16'h03FF)
+                                && LOCK_BYTE4[(Address-16'h0300)/32] == 1)) &&
+                                (Address + Byte_number <= OTPHiAddr))
+                            begin
+                                PSTART = 1'b1;
+                                PSTART <= #5 1'b0;
+                                Status_reg1[0] = 1'b1;
+                                Addr    = Address;
+                                Addr_tmp= Address;
+                                wr_cnt  = Byte_number;
+                                for (i=wr_cnt;i>=0;i=i-1)
+                                begin
+                                    if (Viol != 0)
+                                        WData[i] = -1;
+                                    else
+                                        WData[i] = WByte[i];
+                                end
+                            end
+                            else if ((Address < 8'h10 || (Address > 8'h13 &&
+                                    Address < 8'h20) || Address > 12'h3FF ))
+                            begin
+                                Status_reg1[6] = 1'b1;//P_ERR
+                                Status_reg1[1] = 1'b0;//WEL
+                                if (Address < 8'h20)
+                                begin
+                                    $display ("Given  address is ");
+                                    $display ("in reserved address range");
+                                end
+                                else if (Address > 12'h3FF)
+                                begin
+                                    $display ("Given  address is ");
+                                    $display ("out of OTP address range");
+                                end
+                            end
+                            else
+                            begin
+                            //P_ERR bit will be set when the user attempts to
+                            // to program within locked OTP region
+                                Status_reg1[6] = 1'b1;//P_ERR
+                                Status_reg1[1] = 1'b0;//WEL
+                            end
+                        end
+                        else
+                        begin
+                        //P_ERR bit will be set when the user attempts to
+                        //to program within locked OTP region
+                            Status_reg1[6] = 1'b1;//P_ERR
+                            Status_reg1[1] = 1'b0;//WEL
+                        end
+                    end
+                    else if ((Instruct == SE || Instruct == SE4) && WEL == 1)
+                    begin
+                        ReturnSectorID(sect,Address);
+                        if (UniformSec || (TopBoot && sect < 510) ||
+                           (BottomBoot && sect > 31))
+                        begin
+                            SectorSuspend = sect;
+                            PARAM_REGION  = 0;
+                            if (Sec_Prot[sect] == 0 &&
+                               PPB_bits[sect]== 1 && DYB_bits[sect]== 1)
+                            begin
+                                ESTART = 1'b1;
+                                ESTART <= #5 1'b0;
+                                ESUSP     = 0;
+                                ERES      = 0;
+                                INITIAL_CONFIG = 1;
+                                Status_reg1[0] = 1'b1;
+                                Addr = Address;
+                            end
+                            else
+                            begin
+                            //E_ERR bit will be set when the user attempts to
+                            //erase an individual protected main memory sector
+                                Status_reg1[5] = 1'b1;//E_ERR
+                                Status_reg1[1] = 1'b0;//WEL
+                            end
+                        end
+                        else if ((TopBoot && sect >= 510) ||
+                                (BottomBoot && sect <= 31))
+                        begin
+                            if (Sec_ProtSE == 32 && ASP_ProtSE == 32)
+                            //Sector erase command is applied to a 64 KB range
+                            //that includes 4 KB sectors
+                            begin
+                                if (TopBoot)
+                                begin
+                                    SectorSuspend = 510 + (541 - sect)/16;
+                                end
+                                else
+                                begin
+                                    SectorSuspend = sect/16;
+                                end
+                                PARAM_REGION  = 1;
+                                ESTART = 1'b1;
+                                ESTART <= #5 1'b0;
+                                ESUSP     = 0;
+                                ERES      = 0;
+                                INITIAL_CONFIG = 1;
+                                Status_reg1[0] = 1'b1;
+                                Addr = Address;
+                            end
+                            else
+                            begin
+                            //E_ERR bit will be set when the user attempts to
+                            //erase an individual protected main memory sector
+                                Status_reg1[5] = 1'b1;//E_ERR
+                                Status_reg1[1] = 1'b0;//WEL
+                            end
+                        end
+                    end
+                    else if ((Instruct == P4E || Instruct == P4E4) && WEL == 1)
+                    begin
+                        ReturnSectorID(sect,Address);
+                        if (UniformSec || (TopBoot && sect < 510) ||
+                           (BottomBoot && sect > 31))
+                        begin
+                            Status_reg1[1] = 1'b0;//WEL
+                        end
+                        else
+                        begin
+                            if (Sec_Prot[sect] == 0 &&
+                                PPB_bits[sect]== 1 && DYB_bits[sect]== 1)
+                            //A P4E instruction applied to a sector
+                            //that has been Write Protected through the
+                            //Block Protect Bits or ASP will not be
+                            //executed and will set the E_ERR status
+                            begin
+                                ESTART = 1'b1;
+                                ESTART <= #5 1'b0;
+                                ESUSP     = 0;
+                                ERES      = 0;
+                                INITIAL_CONFIG = 1;
+                                Status_reg1[0] = 1'b1;
+                                Addr = Address;
+                            end
+                            else
+                            begin
+                            //E_ERR bit will be set when the user attempts to
+                            //erase an individual protected main memory sector
+                                Status_reg1[5] = 1'b1;//E_ERR
+                                Status_reg1[1] = 1'b0;//WEL
+                            end
+                        end
+                    end
+                    else if (Instruct == BE && WEL == 1)
+                    begin
+                        if (Status_reg1[4]== 0 && Status_reg1[3]== 0 &&
+                            Status_reg1[2]== 0)
+                        begin
+                            ESTART = 1'b1;
+                            ESTART <= #5 1'b0;
+                            ESUSP  = 0;
+                            ERES   = 0;
+                            INITIAL_CONFIG = 1;
+                            Status_reg1[0] = 1'b1;
+                        end
+                        else
+                        begin
+                        //The Bulk Erase command will not set E_ERR if a
+                        //protected sector is found during the command
+                        //execution.
+                            Status_reg1[1] = 1'b0;//WEL
+                        end
+                    end
+                    else if (Instruct == PASSP && WEL == 1)
+                    begin
+                        if (~(PWDMLB== 0 && PSTMLB== 1))
+                        begin
+                            PSTART = 1'b1;
+                            PSTART <= #5 1'b0;
+                            Status_reg1[0] = 1'b1;
+                        end
+                        else
+                        begin
+                            $display ("Password programming is not allowed");
+                            $display (" in Password Protection Mode.");
+                        end
+                    end
+                    else if (Instruct == PASSU  && WEL)
+                    begin
+                        if (~WIP)
+                        begin
+                            PASSULCK_in = 1;
+                            Status_reg1[0] = 1'b1; //WIP
+                        end
+                        else
+                        begin
+                            $display ("The PASSU command cannot be accepted");
+                            $display (" any faster than once every 100us");
+                        end
+                    end
+                    else if (Instruct == BRWR)
+                    begin
+                        Bank_Addr_reg[7] = Bank_Addr_reg_in[7];
+                        Bank_Addr_reg[0] = Bank_Addr_reg_in[0];
+                        if(Bank_Addr_reg_in[1] == 1)
+                        begin
+                            $display ("WARNING: Changing values of ");
+                            $display ("Bank Address Register");
+                            $display ("BA25 is not allowed!!!");
+                        end
+                    end
+                    else if (Instruct == WRR && BAR_ACC == 1)
+                    begin
+                    // Write to the lower address bits of the BAR
+                        if (P_ERR == 0 && E_ERR == 0)
+                        begin
+                            Bank_Addr_reg[0] = Bank_Addr_reg_in[0];
+                            if(Bank_Addr_reg_in[1] == 1)
+                            begin
+                                $display ("WARNING: Changing values of ");
+                                $display ("Bank Address Register");
+                                $display ("BA25 is not allowed!!!");
+                            end
+                        end
+                    end
+                    else if (Instruct == ASPP  && WEL == 1)
+                    begin
+                        if (~(ASPOTPFLAG))
+                        begin
+                            PSTART = 1'b1;
+                            PSTART <= #5 1'b0;
+                            Status_reg1[0]    = 1'b1;
+                        end
+                        else
+                        begin
+                            Status_reg1[1]   = 1'b0;
+                            Status_reg1[6] = 1'b1;
+                            $display ("Once the Protection Mode is selected,");
+                            $display ("no further changes to the ASP ");
+                            $display ("register is allowed.");
+                        end
+                    end
+                    else if (Instruct == ABWR  && WEL == 1)
+                    begin
+                        PSTART = 1'b1;
+                        PSTART <= #5 1'b0;
+                        Status_reg1[0] = 1'b1;
+                    end
+                    else if (Instruct == PPBP  && WEL == 1)
+                    begin
+                        ReturnSectorID(sect,Address);
+                        PSTART = 1'b1;
+                        PSTART <= #5 1'b0;
+                        Status_reg1[0] = 1'b1;
+                    end
+                    else if (Instruct == PPBERS  && WEL == 1)
+                    begin
+                        if (PPBOTP)
+                        begin
+                            PPBERASE_in = 1'b1;
+                            Status_reg1[0] = 1'b1;
+                        end
+                        else
+                        begin
+                             Status_reg1[5] = 1'b1;
+                        end
+                    end
+                    else if (Instruct == PLBWR  && WEL == 1 &&
+                             RdPswdProtEnable == 0)
+                    begin
+                        PSTART = 1'b1;
+                        PSTART <= #5 1'b0;
+                        Status_reg1[0] = 1'b1;
+                    end
+                    else if (Instruct == DYBWR  && WEL == 1)
+                    begin
+                        ReturnSectorID(sect,Address);
+                        pgm_page = Address / (PageSize+1);
+                        PSTART = 1'b1;
+                        PSTART <= #5 1'b0;
+                        Status_reg1[0]    = 1'b1;
+                    end
+                    else if (Instruct == PNVDLR  && WEL == 1)
+                    begin
+                        PSTART = 1'b1;
+                        PSTART <= #5 1'b0;
+                        Status_reg1[0]    = 1'b1;
+                    end
+                    else if (Instruct == WVDLR  && WEL == 1)
+                    begin
+                        VDLR_reg = VDLR_reg_in;
+                        Status_reg1[1] = 1'b0;
+                    end
+                    else if (Instruct == CLSR)
+                    begin
+                    //The Clear Status Register Command resets bit SR1[5]
+                    //(Erase Fail Flag) and bit SR1[6] (Program Fail Flag)
+                        Status_reg1[5] = 0;
+                        Status_reg1[6] = 0;
+                    end
+
+                    if (Instruct == BRAC && P_ERR == 0 && E_ERR == 0)
+                    begin
+                        BAR_ACC = 1;
+                    end
+                    else
+                    begin
+                        BAR_ACC = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    if (Instruct == READ || Instruct == RD4 ||
+                        Instruct == RES  ||
+                       (Instruct == DLPRD && RdPswdProtMode == 0))
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b1;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                    end
+                    else if (Instruct == DDRFR || Instruct == DDRFR4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b1;
+                    end
+                    else if (Instruct == DDRDIOR || Instruct == DDRDIOR4 ||
+                           ((Instruct == DDRQIOR || Instruct == DDRQIOR4)
+                             && QUAD))
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b1;
+                        ddr     = 1'b1;
+                    end
+                    else if (Instruct == DOR  || Instruct == DOR4  ||
+                             Instruct == DIOR || Instruct == DIOR4 ||
+                           ((Instruct == QOR  || Instruct == QOR4  ||
+                             Instruct == QIOR || Instruct == QIOR4)
+                             && QUAD))
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b1;
+                        ddr     = 1'b0;
+                    end
+                    else
+                    begin
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                    end
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+                else if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == ECCRD)
+                    begin
+                        //Read ECC Register
+                        SOut_zd = ECCSR[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == READ || Instruct == RD4 ||
+                            Instruct == FSTRD || Instruct == FSTRD4 ||
+                            Instruct == DDRFR || Instruct == DDRFR4 )
+                    begin
+                        //Read Memory array
+                        if (Instruct == READ || Instruct == RD4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b1;
+                            dual    = 1'b0;
+                            ddr     = 1'b0;
+                        end
+                        else if (Instruct == DDRFR || Instruct == DDRFR4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b0;
+                            ddr     = 1'b1;
+                        end
+                        else
+                        begin
+                            rd_fast = 1'b1;
+                            rd_slow = 1'b0;
+                            dual    = 1'b0;
+                            ddr     = 1'b0;
+                        end
+                        if ((Instruct == DDRFR || Instruct == DDRFR4) &&
+                            (VDLR_reg != 8'b00000000) && start_dlp)
+                        begin
+                            // Data Learning Pattern (DLP) is enabled
+                            // Optional DLP
+                            data_out[7:0] = VDLR_reg;
+                            SOut_zd  = data_out[7-read_cnt];
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 8)
+                            begin
+                                read_cnt  = 0;
+                                start_dlp = 1'b0;
+                            end
+
+                        end
+                        else
+                        begin
+                            read_addr_tmp = read_addr;
+                            SecAddr = read_addr/(SecSize+1) ;
+                            Sec_addr = read_addr - SecAddr*(SecSize+1);
+                            SecAddr = ReturnSectorIDRdPswdMd(TBPROT);
+                            read_addr = Sec_addr + SecAddr*(SecSize+1);
+                            if (RdPswdProtMode == 0)
+                            begin
+                                read_addr = read_addr_tmp;
+                            end
+                            if (Mem[read_addr] !== -1)
+                            begin
+                                data_out[7:0] = Mem[read_addr];
+                                SOut_zd  = data_out[7-read_cnt];
+                            end
+                            else
+                            begin
+                                SOut_zd  = 8'bx;
+                            end
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 8)
+                            begin
+                                read_cnt = 0;
+                                if (read_addr == AddrRANGE)
+                                    read_addr = 0;
+                                else
+                                    read_addr = read_addr + 1;
+                            end
+                        end
+                    end
+                    else if (Instruct == DOR  || Instruct == DOR4  ||
+                            Instruct == DIOR || Instruct == DIOR4 ||
+                            Instruct == DDRDIOR || Instruct == DDRDIOR4 )
+                    begin
+                        //Read Memory array
+                        if (Instruct == DDRDIOR || Instruct == DDRDIOR4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b1;
+                        end
+                        else
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b0;
+                        end
+                        if ((Instruct == DDRDIOR || Instruct == DDRDIOR4) &&
+                            (VDLR_reg != 8'b00000000) && start_dlp)
+                        begin
+
+                            data_out[7:0] = VDLR_reg;
+                            SOut_zd  = data_out[7-read_cnt];
+                            SIOut_zd = data_out[7-read_cnt];
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 8)
+                            begin
+                                read_cnt  = 0;
+                                start_dlp = 0;
+                            end
+                        end
+                        else
+                        begin
+                            read_addr_tmp = read_addr;
+                            SecAddr = read_addr/(SecSize+1) ;
+                            Sec_addr = read_addr - SecAddr*(SecSize+1);
+                            SecAddr = ReturnSectorIDRdPswdMd(TBPROT);
+                            read_addr = Sec_addr + SecAddr*(SecSize+1);
+                            if (RdPswdProtMode == 0)
+                                read_addr = read_addr_tmp;
+
+                            data_out[7:0] = Mem[read_addr];
+                            SOut_zd = data_out[7-2*read_cnt];
+                            SIOut_zd = data_out[6-2*read_cnt];
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 4)
+                            begin
+                                read_cnt = 0;
+                                if (read_addr == AddrRANGE)
+                                    read_addr = 0;
+                                else
+                                    read_addr = read_addr + 1;
+                            end
+                        end
+                    end
+                    else if ((Instruct == QOR  || Instruct == QOR4 ||
+                            Instruct == QIOR || Instruct == QIOR4 ||
+                            Instruct == DDRQIOR || Instruct == DDRQIOR4 )
+                            && QUAD)
+                    begin
+                        //Read Memory array
+                        if (Instruct == DDRQIOR || Instruct == DDRQIOR4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b1;
+                        end
+                        else
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b0;
+                        end
+                        if ((Instruct == DDRQIOR || Instruct == DDRQIOR4) &&
+                            (VDLR_reg != 8'b00000000) && start_dlp)
+                        begin
+                            // Data Learning Pattern (DLP) is enabled
+                            // Optional DLP
+                            data_out[7:0] = VDLR_reg;
+                            HOLDNegOut_zd = data_out[7-read_cnt];
+                            WPNegOut_zd   = data_out[7-read_cnt];
+                            SOut_zd   = data_out[7-read_cnt];
+                            SIOut_zd   = data_out[7-read_cnt];
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 8)
+                            begin
+                                read_cnt  = 0;
+                                start_dlp = 1'b0;
+                            end
+                        end
+                        else
+                        begin
+                            read_addr_tmp = read_addr;
+                            SecAddr = read_addr/(SecSize+1) ;
+                            Sec_addr = read_addr - SecAddr*(SecSize+1);
+                            SecAddr = ReturnSectorIDRdPswdMd(TBPROT);
+                            read_addr = Sec_addr + SecAddr*(SecSize+1);
+                            if (RdPswdProtMode == 0)
+                                read_addr = read_addr_tmp;
+
+                            data_out[7:0] = Mem[read_addr];
+                            HOLDNegOut_zd = data_out[7-4*read_cnt];
+                            WPNegOut_zd   = data_out[6-4*read_cnt];
+                            SOut_zd   = data_out[5-4*read_cnt];
+                            SIOut_zd   = data_out[4-4*read_cnt];
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 2)
+                            begin
+                                read_cnt = 0;
+                                if (read_addr == AddrRANGE)
+                                    read_addr = 0;
+                                else
+                                    read_addr = read_addr + 1;
+                            end
+                        end
+                    end
+                    else if (Instruct == OTPR)
+                    begin
+                        if(read_addr>=OTPLoAddr && read_addr<=OTPHiAddr
+                        && RdPswdProtMode == 0)
+                        begin
+                        //Read OTP Memory array
+                            rd_fast = 1'b1;
+                            rd_slow = 1'b0;
+                            data_out[7:0] = OTPMem[read_addr];
+                            SOut_zd  = data_out[7-read_cnt];
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 8)
+                            begin
+                                read_cnt = 0;
+                                read_addr = read_addr + 1;
+                            end
+                        end
+                        else if ((read_addr > OTPHiAddr)||(RdPswdProtMode==1))
+                        begin
+                        //OTP Read operation will not wrap to the
+                        //starting address after the OTP address is at
+                        //its maximum or Read Password Protection Mode
+                        //is selected instead, the data beyond the
+                        //maximum OTP address will be undefined.
+                            SOut_zd = 1'bX;
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 8)
+                                read_cnt = 0;
+                        end
+                    end
+                    else if (Instruct == REMS)
+                    begin
+                        //Read Manufacturer and Device ID
+                        if (read_addr % 2 == 0)
+                        begin
+                            data_out[7:0] = Manuf_ID;
+                            SOut_zd = data_out[7-read_cnt];
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 8)
+                            begin
+                                read_cnt = 0;
+                                read_addr = read_addr + 1;
+                            end
+                        end
+                        else
+                        begin
+                            data_out[7:0] = DeviceID;
+                            SOut_zd = data_out[7-read_cnt];
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 8)
+                            begin
+                                read_cnt = 0;
+                                read_addr = 0;
+                            end
+                        end
+                    end
+                    else if (Instruct == RDID)
+                    begin
+                        ident_out = CFI_array_tmp;
+                        if(read_cnt < 648)
+                        begin
+                            SOut_zd = ident_out[647-read_cnt];
+                            read_cnt  = read_cnt + 1;
+                        end
+                        else
+                        begin
+                        //Continued shifting of output beyond the end of
+                        //the defined ID-CFI address space will
+                        //provide undefined data.
+                            SOut_zd = 1'bX;
+                        end
+                    end
+                    else if (Instruct == RES)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b1;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                        data_out = ESignature;
+                        SOut_zd = data_out[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == DLPRD && RdPswdProtMode == 0)
+                    begin
+                    //Read DLP
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b1;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                        SOut_zd = VDLR_reg[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == ABRD && RdPswdProtMode == 0)
+                    begin
+                    //Read AutoBoot register
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                        SOut_zd = AutoBoot_reg_in[31-read_cnt];
+                        read_cnt  = read_cnt + 1;
+                        if (read_cnt == 32)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == BRRD && RdPswdProtMode == 0)
+                    begin
+                    //Read Bank Address Register
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                        SOut_zd = Bank_Addr_reg[7-read_cnt];
+                        read_cnt  = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == ASPRD && RdPswdProtMode == 0)
+                    begin
+                    //Read ASP Register
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                        SOut_zd = ASP_reg[15-read_cnt];
+                        read_cnt  = read_cnt + 1;
+                        if (read_cnt == 16)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == PASSRD && RdPswdProtMode == 0)
+                    begin
+                    //Read Password Register
+                        if (~(PWDMLB == 0 && PSTMLB == 1))
+                        begin
+                            rd_fast = 1'b1;
+                            rd_slow = 1'b0;
+                            dual    = 1'b0;
+                            ddr     = 1'b0;
+                            SOut_zd =
+                                        Password_reg[(8*byte_cnt-1)-read_cnt];
+                            read_cnt  = read_cnt + 1;
+                            if (read_cnt == 8)
+                            begin
+                                read_cnt = 0;
+                                byte_cnt = byte_cnt + 1;
+                                if (byte_cnt == 9)
+                                    byte_cnt = 1;
+                            end
+                        end
+                    end
+                    else if (Instruct == PLBRD)
+                    begin
+                    //Read PPB Lock Register
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                        SOut_zd = PPBL[7-read_cnt];
+                        read_cnt  = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == DYBRD)
+                    begin
+                    //Read DYB Access Register
+                        ReturnSectorID(sect,Address);
+                        pgm_page = Address / (PageSize+1);
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                        DYBAR[7:0] = 8'bXXXXXXXX;
+
+                        if (RdPswdProtMode == 0)
+                        begin
+                            if (DYB_bits[sect] == 1)
+                                DYBAR[7:0] = 8'hFF;
+                            else
+                            begin
+                                DYBAR[7:0] = 8'h0;
+                            end
+                        end
+                        SOut_zd = DYBAR[7-read_cnt];
+                        read_cnt  = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == PPBRD)
+                    begin
+                    //Read PPB Access Register
+                        ReturnSectorID(sect,Address);
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                        PPBAR[7:0] = 8'bXXXXXXXX;
+                        if (RdPswdProtMode == 0)
+                        begin
+                            if (PPB_bits[sect] == 1)
+                                PPBAR[7:0] = 8'hFF;
+                            else
+                            begin
+                                PPBAR[7:0] = 8'h0;
+                            end
+                        end
+                        SOut_zd = PPBAR[7-read_cnt];
+                        read_cnt  = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+            end
+
+            AUTOBOOT:
+            begin
+                if (start_autoboot == 1)
+                begin
+                    if (oe)
+                    begin
+                        any_read = 1'b1;
+                        if (QUAD == 1)
+                        begin
+                            if (ABSD > 0)      //If ABSD > 0,
+                            begin              //max SCK frequency is 104MHz
+                                rd_fast = 1'b0;
+                                rd_slow = 1'b0;
+                                dual    = 1'b1;
+                                ddr     = 1'b0;
+                            end
+                            else // If ABSD = 0, max SCK frequency is 50 MHz
+                            begin
+                                rd_fast = 1'b0;
+                                rd_slow = 1'b1;
+                                dual    = 1'b0;
+                                ddr     = 1'b0;
+                            end
+                            data_out[7:0] = Mem[read_addr];
+                            HOLDNegOut_zd = data_out[7-4*read_cnt];
+                            WPNegOut_zd   = data_out[6-4*read_cnt];
+                            SOut_zd   = data_out[5-4*read_cnt];
+                            SIOut_zd   = data_out[4-4*read_cnt];
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 2)
+                            begin
+                                read_cnt = 0;
+                                read_addr = read_addr + 1;
+                            end
+                        end
+                        else
+                        begin
+                            if (ABSD > 0)      //If ABSD > 0,
+                            begin              //max SCK frequency is 133MHz
+                                rd_fast = 1'b1;
+                                rd_slow = 1'b0;
+                                dual    = 1'b0;
+                                ddr     = 1'b0;
+                            end
+                            else // If ABSD = 0, max SCK frequency is 50 MHz
+                            begin
+                                rd_fast = 1'b0;
+                                rd_slow = 1'b1;
+                                dual    = 1'b0;
+                                ddr     = 1'b0;
+                            end
+                            data_out[7:0] = Mem[read_addr];
+                            SOut_zd = data_out[7-read_cnt];
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 8)
+                            begin
+                                read_cnt = 0;
+                                read_addr = read_addr + 1;
+                            end
+                        end
+                    end
+                    else if (oe_z)
+                    begin
+                        if (QUAD == 1)
+                        begin
+                            if (ABSD > 0)      //If ABSD > 0,
+                            begin              //max SCK frequency is 104MHz
+                                rd_fast = 1'b0;
+                                rd_slow = 1'b0;
+                                dual    = 1'b1;
+                                ddr     = 1'b0;
+                            end
+                            else // If ABSD = 0, max SCK frequency is 50 MHz
+                            begin
+                                rd_fast = 1'b0;
+                                rd_slow = 1'b1;
+                                dual    = 1'b0;
+                                ddr     = 1'b0;
+                            end
+                        end
+                        else
+                        begin
+                            if (ABSD > 0)      //If ABSD > 0,
+                            begin              //max SCK frequency is 133MHz
+                                rd_fast = 1'b1;
+                                rd_slow = 1'b0;
+                                dual    = 1'b0;
+                                ddr     = 1'b0;
+                            end
+                            else // If ABSD = 0, max SCK frequency is 50 MHz
+                            begin
+                                rd_fast = 1'b0;
+                                rd_slow = 1'b1;
+                                dual    = 1'b0;
+                                ddr     = 1'b0;
+                            end
+                        end
+                        HOLDNegOut_zd = 1'bZ;
+                        WPNegOut_zd   = 1'bZ;
+                        SOut_zd       = 1'bZ;
+                        SIOut_zd      = 1'bZ;
+                    end
+                end
+            end
+
+            WRITE_SR:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register 2
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if (WDONE == 1)
+                begin
+                    Status_reg1[0] = 1'b0; //WIP
+                    Status_reg1[1] = 1'b0; //WEL
+                    //SRWD bit
+                    Status_reg1[7] = Status_reg1_in[7]; //MSB first
+
+//                     if (LOCK == 0)
+//                     begin
+                        if (FREEZE == 0)
+                        //The Freeze Bit, when set to 1, locks the current
+                        //state of the BP2-0 bits in Status Register,
+                        //the TBPROT and TBPARM bits in the Config Register
+                        //As long as the FREEZE bit remains cleared to logic
+                        //'0', the other bits of the Configuration register
+                        //including FREEZE are writeable.
+                        begin
+                            Status_reg1[4] = Status_reg1_in[4];//BP2
+                            Status_reg1[3] = Status_reg1_in[3];//BP1
+                            Status_reg1[2] = Status_reg1_in[2];//BP0
+
+                            BP_bits = {Status_reg1[4],Status_reg1[3],
+                                       Status_reg1[2]};
+                            if (TBPROT == 1'b0 && INITIAL_CONFIG == 1'b0)
+                            begin
+                                Config_reg1[5] = Config_reg1_in[5];//TBPROT
+                            end
+                            if (TBPARM == 1'b0 && INITIAL_CONFIG == 1'b0 &&
+                                tmp_char2 == "0")
+                            begin
+                                Config_reg1[2] = Config_reg1_in[2];//TBPARM
+                                change_TBPARM = 1'b1;
+                                #1000 change_TBPARM = 1'b0;
+                            end
+                            change_BP = 1'b1;
+                            #1000 change_BP = 1'b0;
+                        end
+//                     end
+
+                    Config_reg1[7] = Config_reg1_in[7];//LC1
+                    Config_reg1[6] = Config_reg1_in[6];//LC0
+                    Config_reg1[1] = Config_reg1_in[1];//QUAD
+
+                    if (FREEZE == 1'b0)
+                    begin
+                        Config_reg1[0] = Config_reg1_in[0];//FREEZE
+                    end
+
+//                     if (WRLOCKENABLE== 1'b1 && LOCK == 1'b0)
+//                     begin
+//                         Config_reg1[4] = Config_reg1_in[4];//LOCK
+//                         WRLOCKENABLE = 1'b0;
+//                     end
+                    if (BPNV == 1'b0)
+                    begin
+                        Config_reg1[3] = Config_reg1_in[3];//BPNV
+                    end
+                end
+            end
+
+            PAGE_PG :
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register 2
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if(current_state_event && current_state == PAGE_PG)
+                begin
+                    if (~PDONE)
+                    begin
+                        ADDRHILO_PG(AddrLo, AddrHi, Addr);
+                        cnt = 0;
+
+                        for (i=0;i<=wr_cnt;i=i+1)
+                        begin
+                            new_int = WData[i];
+                            old_int = Mem[Addr + i - cnt];
+			    //$display("%m: New Loc: %x New Data: %x Old Data: %x",i,new_int,old_int);
+                            if (new_int > -1)
+                            begin
+                                new_bit = new_int;
+                                if (old_int > -1)
+                                begin
+                                    old_bit = old_int;
+                                    for(j=0;j<=7;j=j+1)
+                                    begin
+                                        if (~old_bit[j])
+                                            new_bit[j]=1'b0;
+                                    end
+                                    new_int=new_bit;
+                                end
+                                WData[i]= new_int;
+                            end
+                            else
+                            begin
+                                WData[i] = -1;
+                            end
+
+                            Mem[Addr + i - cnt] = - 1;
+                            if ((Addr + i) == AddrHi)
+                            begin
+
+                                Addr = AddrLo;
+                                cnt = i + 1;
+                            end
+                        end
+                    end
+                    cnt = 0;
+                end
+
+                if (PDONE)
+                begin
+                    Status_reg1[0] = 1'b0;
+                    Status_reg1[1] = 1'b0;
+                    quad_pg        = 0;
+                    for (i=0;i<=wr_cnt;i=i+1)
+                    begin
+                        Mem[Addr_tmp + i - cnt] = WData[i];
+			//$display("%m => SFLASH WR Address: %x Data: %x",Addr_tmp + i - cnt, WData[i]);
+                        if ((Addr_tmp + i) == AddrHi)
+                        begin
+                            Addr_tmp = AddrLo;
+                            cnt = i + 1;
+                        end
+                    end
+                end
+
+                if (Instruct)
+                begin
+                    if (Instruct == PGSP && ~PRGSUSP_in)
+                    begin
+                        if (~RES_TO_SUSP_MIN_TIME)
+                        begin
+                            PGSUSP = 1'b1;
+                            PGSUSP <= #5 1'b0;
+                            PRGSUSP_in = 1'b1;
+                            if (RES_TO_SUSP_TYP_TIME)
+                            begin
+                                $display("Typical periods are needed for ",
+                                         "Program to progress to completion");
+                            end
+                        end
+                        else
+                        begin
+                            $display("Minimum for tPRS is not satisfied! ",
+                                     "PGSP command is ignored");
+                        end
+                    end
+                end
+            end
+
+            PG_SUSP:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+
+                if (PRGSUSP_out && PRGSUSP_in)
+                begin
+                    PRGSUSP_in = 1'b0;
+                    //The RDY/BSY bit in the Status Register will indicate that
+                    //the device is ready for another operation.
+                    Status_reg1[0] = 1'b0;
+                    //The Program Suspend (PS) bit in the Status Register will
+                    //be set to the logical “1” state to indicate that the
+                    //program operation has been suspended.
+                    Status_reg2[0] = 1'b1;
+                    PDONE = 1'b1;
+                end
+
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register 2
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == BRRD)
+                    begin
+                    //Read Bank Address Register
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                        SOut_zd = Bank_Addr_reg[7-read_cnt];
+                        read_cnt  = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    //Read Array Operations
+                    else if (Instruct == READ || Instruct == RD4 ||
+                            Instruct == FSTRD || Instruct == FSTRD4 ||
+                            Instruct == DDRFR || Instruct == DDRFR4 )
+                    begin
+                        //Read Memory array
+                        if (Instruct == READ || Instruct == RD4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b1;
+                            dual    = 1'b0;
+                            ddr     = 1'b0;
+                        end
+                        else if (Instruct == DDRFR || Instruct == DDRFR4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b0;
+                            ddr     = 1'b1;
+                        end
+                        else
+                        begin
+                            rd_fast = 1'b1;
+                            rd_slow = 1'b0;
+                            dual    = 1'b0;
+                            ddr     = 1'b0;
+                        end
+                        if (pgm_page != read_addr / (PageSize+1))
+                        begin
+                            if ((Instruct == DDRFR || Instruct == DDRFR4) &&
+                                (VDLR_reg != 8'b00000000) && start_dlp)
+                            begin
+                                data_out[7:0] = VDLR_reg;
+                                SOut_zd  = data_out[7-read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 8)
+                                begin
+                                    read_cnt  = 0;
+                                    start_dlp = 1'b0;
+                                end
+                            end
+                            else
+                            begin
+                                data_out[7:0] = Mem[read_addr];
+                                SOut_zd  = data_out[7-read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 8)
+                                begin
+                                    read_cnt = 0;
+                                    if (read_addr == AddrRANGE)
+                                        read_addr = 0;
+                                    else
+                                        read_addr = read_addr + 1;
+                                end
+
+                            end
+                        end
+                        else
+                        begin
+                            SOut_zd  = 8'bxxxxxxxx;
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 8)
+                            begin
+                                read_cnt = 0;
+                                if (read_addr == AddrRANGE)
+                                    read_addr = 0;
+                                else
+                                    read_addr = read_addr + 1;
+                            end
+                        end
+                    end
+                    else if (Instruct == DOR || Instruct == DOR4  ||
+                            Instruct == DIOR || Instruct == DIOR4 ||
+                            Instruct == DDRDIOR || Instruct == DDRDIOR4 )
+                    begin
+                        //Read Memory array
+                        if (Instruct == DDRDIOR || Instruct == DDRDIOR4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b1;
+                        end
+                        else
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b0;
+                        end
+                        if (pgm_page != read_addr / (PageSize+1))
+                        begin
+                            if ((Instruct == DDRDIOR || Instruct == DDRDIOR4) &&
+                               (VDLR_reg != 8'b00000000) && start_dlp)
+                            begin
+                                data_out[7:0] = VDLR_reg;
+                                SOut_zd = data_out[7-read_cnt];
+                                SIOut_zd = data_out[7-read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 8)
+                                begin
+                                    read_cnt  = 0;
+                                    start_dlp = 1'b0;
+                                end
+                            end
+                            else
+                            begin
+                                data_out[7:0] = Mem[read_addr];
+                                SOut_zd = data_out[7-2*read_cnt];
+                                SIOut_zd = data_out[6-2*read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 4)
+                                begin
+                                    read_cnt = 0;
+                                    if (read_addr == AddrRANGE)
+                                        read_addr = 0;
+                                    else
+                                        read_addr = read_addr + 1;
+                                end
+                            end
+                        end
+                        else
+                        begin
+                            SOut_zd = 1'bx;
+                            SIOut_zd = 1'bx;
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 4)
+                            begin
+                                read_cnt = 0;
+                                if (read_addr == AddrRANGE)
+                                    read_addr = 0;
+                                else
+                                    read_addr = read_addr + 1;
+                            end
+                        end
+                    end
+                    else if (Instruct == QOR || Instruct == QOR4  ||
+                            Instruct == QIOR || Instruct == QIOR4 ||
+                            Instruct == DDRQIOR || Instruct == DDRQIOR4 )
+                    begin
+                        //Read Memory array
+                        if (Instruct == DDRQIOR || Instruct == DDRQIOR4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b1;
+                        end
+                        else
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b0;
+                        end
+                        if (pgm_page != read_addr / (PageSize+1))
+                        begin
+                            if ((Instruct == DDRQIOR || Instruct == DDRQIOR4) &&
+                                (VDLR_reg != 8'b00000000) && start_dlp)
+                            begin
+                                // Data Learning Pattern (DLP)
+                                // is enabled Optional DLP
+                                data_out[7:0] = VDLR_reg;
+                                HOLDNegOut_zd= data_out[7-read_cnt];
+                                WPNegOut_zd  = data_out[7-read_cnt];
+                                SOut_zd  = data_out[7-read_cnt];
+                                SIOut_zd  = data_out[7-read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 8)
+                                begin
+                                    read_cnt  = 0;
+                                    start_dlp = 1'b0;
+                                end
+                            end
+                            else
+                            begin
+                                data_out[7:0] = Mem[read_addr];
+                                HOLDNegOut_zd = data_out[7-4*read_cnt];
+                                WPNegOut_zd   = data_out[6-4*read_cnt];
+                                SOut_zd   = data_out[5-4*read_cnt];
+                                SIOut_zd   = data_out[4-4*read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 2)
+                                begin
+                                    read_cnt = 0;
+                                    if (read_addr == AddrRANGE)
+                                        read_addr = 0;
+                                    else
+                                        read_addr = read_addr + 1;
+                                end
+                            end
+                        end
+                        else
+                        begin
+                            HOLDNegOut_zd = 1'bx;
+                            WPNegOut_zd   = 1'bx;
+                            SOut_zd   = 1'bx;
+                            SIOut_zd   = 1'bx;
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 2)
+                            begin
+                                read_cnt = 0;
+                                if (read_addr == AddrRANGE)
+                                    read_addr = 0;
+                                else
+                                    read_addr = read_addr + 1;
+                            end
+                        end
+                    end
+                end
+                else if (oe_z)
+                begin
+                    if (Instruct == READ || Instruct == RD4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b1;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                    end
+                    else if (Instruct == DDRFR || Instruct == DDRFR4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b1;
+                    end
+                    else if (Instruct == DDRDIOR || Instruct == DDRDIOR4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b1;
+                        ddr     = 1'b1;
+                    end
+                    else if (Instruct == DOR || Instruct == DOR4  ||
+                             Instruct == DIOR || Instruct == DIOR4 ||
+                             Instruct == QOR || Instruct == QOR4  ||
+                             Instruct == QIOR || Instruct == QIOR4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b1;
+                        ddr     = 1'b0;
+                    end
+                    else if (Instruct == DDRQIOR || Instruct == DDRQIOR4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b1;
+                        ddr     = 1'b1;
+                    end
+                    else
+                    begin
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                    end
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if (falling_edge_write)
+                begin
+                    if (Instruct == BRWR)
+                    begin
+                        Bank_Addr_reg[7] = Bank_Addr_reg_in[7];
+                        Bank_Addr_reg[0] = Bank_Addr_reg_in[0];
+                        if(Bank_Addr_reg_in[1] == 1)
+                        begin
+                            $display ("WARNING: Changing values of ");
+                            $display ("Bank Address Register");
+                            $display ("BA25 is not allowed!!!");
+                        end
+                    end
+                    else if (Instruct == WRR && BAR_ACC == 1)
+                    begin
+                    // Write to the lower address bits of the BAR
+                        if (P_ERR == 0 && E_ERR == 0)
+                        begin
+                            Bank_Addr_reg[0] = Bank_Addr_reg_in[0];
+                            if(Bank_Addr_reg_in[1] == 1)
+                            begin
+                                $display ("WARNING: Changing values of ");
+                                $display ("Bank Address Register");
+                                $display ("BA25 is not allowed!!!");
+                            end
+                        end
+                    end
+                    else if (Instruct == PGRS)
+                    begin
+                        Status_reg2[0] = 1'b0;
+                        Status_reg1[0] = 1'b1;
+                        PGRES = 1'b1;
+                        PGRES <= #5 1'b0;
+                        RES_TO_SUSP_MIN_TIME = 1'b1;
+                        RES_TO_SUSP_MIN_TIME <= #60000 1'b0;//60 ns
+                        RES_TO_SUSP_TYP_TIME = 1'b1;
+                        RES_TO_SUSP_TYP_TIME <= #100000000 1'b0;//100us
+                    end
+
+                    if (Instruct == BRAC && P_ERR == 0 && E_ERR == 0 &&
+                        RdPswdProtMode == 0)
+                    begin
+                        BAR_ACC = 1;
+                    end
+                    else
+                    begin
+                        BAR_ACC = 0;
+                    end
+                end
+            end
+
+            ERS_SUSP_PG_SUSP:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+
+                if (PRGSUSP_out && PRGSUSP_in)
+                begin
+                    PRGSUSP_in = 1'b0;
+                    //The RDY/BSY bit in the Status Register will indicate that
+                    //the device is ready for another operation.
+                    Status_reg1[0] = 1'b0;
+                    //The Program Suspend (PS) bit in the Status Register will
+                    //be set to the logical “1” state to indicate that the
+                    //program operation has been suspended.
+                    Status_reg2[0] = 1'b1;
+                end
+
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register 2
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == BRRD)
+                    begin
+                    //Read Bank Address Register
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                        SOut_zd = Bank_Addr_reg[7-read_cnt];
+                        read_cnt  = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    //Read Array Operations
+                    else if (Instruct == READ || Instruct == RD4 ||
+                            Instruct == FSTRD || Instruct == FSTRD4 ||
+                            Instruct == DDRFR || Instruct == DDRFR4 )
+                    begin
+                        //Read Memory array
+                        if (Instruct == READ || Instruct == RD4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b1;
+                            dual    = 1'b0;
+                            ddr     = 1'b0;
+                        end
+                        else if (Instruct == DDRFR || Instruct == DDRFR4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b0;
+                            ddr     = 1'b1;
+                        end
+                        else
+                        begin
+                            rd_fast = 1'b1;
+                            rd_slow = 1'b0;
+                            dual    = 1'b0;
+                            ddr     = 1'b0;
+                        end
+                        if ((SectorSuspend != read_addr/(SecSize+1)) &&
+                        (pgm_page != read_addr / (PageSize+1)))
+                        begin
+                            if ((Instruct == DDRFR || Instruct == DDRFR4) &&
+                                (VDLR_reg != 8'b00000000) && start_dlp)
+                            begin
+                                data_out[7:0] = VDLR_reg;
+                                SOut_zd  = data_out[7-read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 8)
+                                begin
+                                    read_cnt  = 0;
+                                    start_dlp = 1'b0;
+                                end
+                            end
+                            else
+                            begin
+                                data_out[7:0] = Mem[read_addr];
+                                SOut_zd  = data_out[7-read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 8)
+                                begin
+                                    read_cnt = 0;
+                                    if (read_addr == AddrRANGE)
+                                        read_addr = 0;
+                                    else
+                                        read_addr = read_addr + 1;
+                                end
+
+                            end
+                        end
+                        else
+                        begin
+                            SOut_zd  = 8'bxxxxxxxx;
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 8)
+                            begin
+                                read_cnt = 0;
+                                if (read_addr == AddrRANGE)
+                                    read_addr = 0;
+                                else
+                                    read_addr = read_addr + 1;
+                            end
+                        end
+                    end
+                    else if (Instruct == DOR || Instruct == DOR4  ||
+                            Instruct == DIOR || Instruct == DIOR4 ||
+                            Instruct == DDRDIOR || Instruct == DDRDIOR4 )
+                    begin
+                        //Read Memory array
+                        if (Instruct == DDRDIOR || Instruct == DDRDIOR4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b1;
+                        end
+                        else
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b0;
+                        end
+                        if ((SectorSuspend != read_addr/(SecSize+1)) &&
+                        (pgm_page != read_addr / (PageSize+1)))
+                        begin
+                            if ((Instruct == DDRDIOR || Instruct == DDRDIOR4) &&
+                                (VDLR_reg != 8'b00000000) && start_dlp)
+                            begin
+                                // Data Learning Pattern (DLP)
+                                // is enabled Optional DLP
+                                data_out[7:0] = VDLR_reg;
+                                SOut_zd = data_out[7-read_cnt];
+                                SIOut_zd = data_out[7-read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 8)
+                                begin
+                                    read_cnt  = 0;
+                                    start_dlp = 1'b0;
+                                end
+                            end
+                            else
+                            begin
+                                data_out[7:0] = Mem[read_addr];
+                                SOut_zd = data_out[7-2*read_cnt];
+                                SIOut_zd = data_out[6-2*read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 4)
+                                begin
+                                    read_cnt = 0;
+                                    if (read_addr == AddrRANGE)
+                                        read_addr = 0;
+                                    else
+                                        read_addr = read_addr + 1;
+                                end
+                            end
+                        end
+                        else
+                        begin
+                            SOut_zd = 1'bx;
+                            SIOut_zd = 1'bx;
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 4)
+                            begin
+                                read_cnt = 0;
+                                if (read_addr == AddrRANGE)
+                                    read_addr = 0;
+                                else
+                                    read_addr = read_addr + 1;
+                            end
+                        end
+                    end
+                    else if (Instruct == QOR || Instruct == QOR4  ||
+                            Instruct == QIOR || Instruct == QIOR4 ||
+                            Instruct == DDRQIOR || Instruct == DDRQIOR4 )
+                    begin
+                        //Read Memory array
+                        if (Instruct == DDRQIOR || Instruct == DDRQIOR4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b1;
+                        end
+                        else
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b0;
+                        end
+                        if ((SectorSuspend != read_addr/(SecSize+1)) &&
+                        (pgm_page != read_addr / (PageSize+1)))
+                        begin
+                            if ((Instruct == DDRQIOR || Instruct == DDRQIOR4) &&
+                                (VDLR_reg != 8'b00000000) && start_dlp)
+                            begin
+                                // Data Learning Pattern (DLP)
+                                // is enabled Optional DLP
+                                data_out[7:0] = VDLR_reg;
+                                HOLDNegOut_zd =data_out[7-read_cnt];
+                                WPNegOut_zd = data_out[7-read_cnt];
+                                SOut_zd = data_out[7-read_cnt];
+                                SIOut_zd = data_out[7-read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 8)
+                                begin
+                                    read_cnt = 0;
+                                    start_dlp = 1'b0;
+                                end
+                            end
+                            else
+                            begin
+                                data_out[7:0] = Mem[read_addr];
+                                HOLDNegOut_zd = data_out[7-4*read_cnt];
+                                WPNegOut_zd   = data_out[6-4*read_cnt];
+                                SOut_zd   = data_out[5-4*read_cnt];
+                                SIOut_zd   = data_out[4-4*read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 2)
+                                begin
+                                    read_cnt = 0;
+                                    if (read_addr == AddrRANGE)
+                                        read_addr = 0;
+                                    else
+                                        read_addr = read_addr + 1;
+                                end
+                            end
+                        end
+                        else
+                        begin
+                            HOLDNegOut_zd = 1'bx;
+                            WPNegOut_zd   = 1'bx;
+                            SOut_zd   = 1'bx;
+                            SIOut_zd   = 1'bx;
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 2)
+                            begin
+                                read_cnt = 0;
+                                if (read_addr == AddrRANGE)
+                                    read_addr = 0;
+                                else
+                                    read_addr = read_addr + 1;
+                            end
+                        end
+                    end
+                end
+                else if (oe_z)
+                begin
+                    if (Instruct == READ || Instruct == RD4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b1;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                    end
+                    else if (Instruct == DDRFR || Instruct == DDRFR4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b1;
+                    end
+                    else if (Instruct == DDRDIOR || Instruct == DDRDIOR4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b1;
+                        ddr     = 1'b1;
+                    end
+                    else if (Instruct == DOR || Instruct == DOR4  ||
+                             Instruct == DIOR || Instruct == DIOR4 ||
+                             Instruct == QOR || Instruct == QOR4  ||
+                             Instruct == QIOR || Instruct == QIOR4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b1;
+                        ddr     = 1'b0;
+                    end
+                    else if (Instruct == DDRQIOR || Instruct == DDRQIOR4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b1;
+                        ddr     = 1'b1;
+                    end
+                    else
+                    begin
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                    end
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if (falling_edge_write)
+                begin
+                    if (Instruct == BRWR)
+                    begin
+                        Bank_Addr_reg[7] = Bank_Addr_reg_in[7];
+                        Bank_Addr_reg[0] = Bank_Addr_reg_in[0];
+                        if(Bank_Addr_reg_in[1] == 1)
+                        begin
+                            $display ("WARNING: Changing values of ");
+                            $display ("Bank Address Register");
+                            $display ("BA25 is not allowed!!!");
+                        end
+                    end
+                    else if (Instruct == WRR && BAR_ACC == 1)
+                    begin
+                    // Write to the lower address bits of the BAR
+                        if (P_ERR == 0 && E_ERR == 0)
+                        begin
+                            Bank_Addr_reg[0] = Bank_Addr_reg_in[0];
+                            if(Bank_Addr_reg_in[1] == 1)
+                            begin
+                                $display ("WARNING: Changing values of ");
+                                $display ("Bank Address Register");
+                                $display ("BA25 is not allowed!!!");
+                            end
+                        end
+                    end
+                    else if (Instruct == PGRS)
+                    begin
+                        Status_reg2[0] = 1'b0;
+                        Status_reg1[0] = 1'b1;
+                        PGRES = 1'b1;
+                        PGRES <= #5 1'b0;
+                        RES_TO_SUSP_MIN_TIME = 1'b1;
+                        RES_TO_SUSP_MIN_TIME <= #60000 1'b0;//60 ns
+                        RES_TO_SUSP_TYP_TIME = 1'b1;
+                        RES_TO_SUSP_TYP_TIME <= #100000000 1'b0;//100us
+                    end
+
+                    if (Instruct == BRAC && P_ERR == 0 && E_ERR == 0 &&
+                        RdPswdProtMode == 0)
+                    begin
+                        BAR_ACC = 1;
+                    end
+                    else
+                    begin
+                        BAR_ACC = 0;
+                    end
+                end
+            end
+
+            OTP_PG:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register 2
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if(current_state_event && current_state == OTP_PG)
+                begin
+                    if (~PDONE)
+                    begin
+                        if (Address + wr_cnt <= OTPHiAddr)
+                        begin
+                            for (i=0;i<=wr_cnt;i=i+1)
+                            begin
+                                new_int = WData[i];
+                                old_int = OTPMem[Addr + i];
+                                if (new_int > -1)
+                                begin
+                                    new_bit = new_int;
+                                    if (old_int > -1)
+                                    begin
+                                        old_bit = old_int;
+                                        for(j=0;j<=7;j=j+1)
+                                        begin
+                                            if (~old_bit[j])
+                                                new_bit[j] = 1'b0;
+                                        end
+                                        new_int = new_bit;
+                                    end
+                                    WData[i] = new_int;
+                                end
+                                else
+                                begin
+                                    WData[i] = -1;
+                                end
+                                OTPMem[Addr + i] =  -1;
+                            end
+                        end
+                        else
+                        begin
+                            $display ("Programming will reach over ");
+                            $display ("address limit of OTP array");
+                        end
+                    end
+                end
+
+                if (PDONE)
+                begin
+                    Status_reg1[0] = 1'b0;
+                    Status_reg1[1] = 1'b0;
+                    for (i=0;i<=wr_cnt;i=i+1)
+                    begin
+                        OTPMem[Addr + i] = WData[i];
+                    end
+                    LOCK_BYTE1 = OTPMem[16];
+                    LOCK_BYTE2 = OTPMem[17];
+                    LOCK_BYTE3 = OTPMem[18];
+                    LOCK_BYTE4 = OTPMem[19];
+                end
+            end
+
+            SECTOR_ERS:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register 2
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if(current_state_event && current_state == SECTOR_ERS)
+                begin
+                    if (~EDONE)
+                    begin
+                        ADDRHILO_SEC(AddrLo, AddrHi, Addr);
+			$display("%m: Sector Erase Address: %x Start: %x End: %x",Addr,AddrLo,AddrHi);
+                        for (i=AddrLo;i<=AddrHi;i=i+1)
+                        begin
+                            Mem[i] = -1;
+                        end
+                    end
+                end
+
+                if (EDONE == 1)
+                begin
+                    Status_reg1[0] = 1'b0;
+                    Status_reg1[1] = 1'b0;
+                    for (i=AddrLo;i<=AddrHi;i=i+1)
+                    begin
+                        Mem[i] = MaxData;
+
+                        pgm_page = i / (PageSize+1);
+//                        QPP_page[pgm_page] = 1'b0;
+                    end
+                end
+                else if (Instruct == ERSP && ~ERSSUSP_in)
+                begin
+                    ESUSP = 1'b1;
+                    ESUSP <= #5 1'b0;
+                    ERSSUSP_in = 1'b1;
+                    if (RES_TO_SUSP_TYP_TIME)
+                    begin
+                        $display("Typical periods are needed for ",
+                                 "Program to progress to completion");
+                    end
+                end
+            end
+
+            BULK_ERS:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register 2
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if(current_state_event && current_state == BULK_ERS)
+                begin
+                    if (~EDONE)
+                    begin
+                        for (i=0;i<=AddrRANGE;i=i+1)
+                        begin
+                            ReturnSectorID(sect,i);
+                            if (PPB_bits[sect] == 1 && DYB_bits[sect] == 1)
+                            begin
+                                Mem[i] = -1;
+                            end
+                        end
+
+                    end
+                end
+
+                if (EDONE == 1)
+                begin
+                    Status_reg1[0] = 1'b0;
+                    Status_reg1[1] = 1'b0;
+                    for (i=0;i<=AddrRANGE;i=i+1)
+                    begin
+                        ReturnSectorID(sect,i);
+                        if (PPB_bits[sect] == 1 && DYB_bits[sect] == 1)
+                        begin
+                            Mem[i] = MaxData;
+
+                            pgm_page = i / (PageSize+1);
+//                            QPP_page[pgm_page] = 1'b0;
+                        end
+                    end
+                end
+            end
+
+            ERS_SUSP:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (ERSSUSP_out == 1)
+                begin
+                    ERSSUSP_in = 0;
+                    //The Erase Suspend (ES) bit in the Status Register will
+                    //be set to the logical “1” state to indicate that the
+                    //erase operation has been suspended.
+                    Status_reg2[1] = 1'b1;
+                    //The WIP bit in the Status Register will indicate that
+                    //the device is ready for another operation.
+                    Status_reg1[0] = 1'b0;
+                end
+
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register 2
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == DYBRD)
+                    begin
+                    //Read DYB Access Register
+                        ReturnSectorID(sect,Address);
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                        if (DYB_bits[sect] == 1)
+                            DYBAR[7:0] = 8'hFF;
+                        else
+                        begin
+                            DYBAR[7:0] = 8'h0;
+                        end
+                        SOut_zd = DYBAR[7-read_cnt];
+                        read_cnt  = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == BRRD)
+                    begin
+                    //Read Bank Address Register
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                        SOut_zd = Bank_Addr_reg[7-read_cnt];
+                        read_cnt  = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == PPBRD)
+                    begin
+                    //Read PPB Access Register
+                        ReturnSectorID(sect,Address);
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                        PPBAR[7:0] = 8'bXXXXXXXX;
+                        if (RdPswdProtMode == 0)
+                        begin
+                            if (PPB_bits[sect] == 1)
+                                PPBAR[7:0] = 8'hFF;
+                            else
+                            begin
+                                PPBAR[7:0] = 8'h0;
+                            end
+                        end
+                        SOut_zd = PPBAR[7-read_cnt];
+                        read_cnt  = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == READ || Instruct == RD4 ||
+                            Instruct == FSTRD || Instruct == FSTRD4 ||
+                            Instruct == DDRFR || Instruct == DDRFR4 )
+                    begin
+                        //Read Memory array
+                        if (Instruct == READ || Instruct == RD4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b1;
+                            dual    = 1'b0;
+                            ddr     = 1'b0;
+                        end
+                        else if (Instruct == DDRFR || Instruct == DDRFR4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b0;
+                            ddr     = 1'b1;
+                        end
+                        else
+                        begin
+                            rd_fast = 1'b1;
+                            rd_slow = 1'b0;
+                            dual    = 1'b0;
+                            ddr     = 1'b0;
+                        end
+                        if ((PARAM_REGION &&
+                             SectorSuspend != read_addr/(SecSize+1)) ||
+                            (~PARAM_REGION &&
+                             SectorSuspend != read_addr/(SecSize+1)+30*b_act))
+                        begin
+                            if ((Instruct == DDRFR || Instruct == DDRFR4) &&
+                                (VDLR_reg != 8'b00000000) && start_dlp)
+                            begin
+                                // Data Learning Pattern (DLP)
+                                // is enabled Optional DLP
+                                data_out[7:0] = VDLR_reg;
+                                SOut_zd  = data_out[7-read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 8)
+                                begin
+                                    read_cnt  = 0;
+                                    start_dlp = 1'b0;
+                                end
+                            end
+                            else
+                            begin
+                                data_out[7:0] = Mem[read_addr];
+                                SOut_zd  = data_out[7-read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 8)
+                                begin
+                                    read_cnt = 0;
+                                    if (read_addr == AddrRANGE)
+                                        read_addr = 0;
+                                    else
+                                        read_addr = read_addr + 1;
+                                end
+                            end
+                        end
+                        else
+                        begin
+                            SOut_zd  = 1'bx;
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 8)
+                            begin
+                                read_cnt = 0;
+                                if (read_addr == AddrRANGE)
+                                    read_addr = 0;
+                                else
+                                    read_addr = read_addr + 1;
+                            end
+                        end
+                    end
+                    else if (Instruct == DOR || Instruct == DOR4  ||
+                            Instruct == DIOR || Instruct == DIOR4 ||
+                            Instruct == DDRDIOR || Instruct == DDRDIOR4 )
+                    begin
+                        //Read Memory array
+                        if (Instruct == DDRDIOR || Instruct == DDRDIOR4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b1;
+                        end
+                        else
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b0;
+                        end
+                        if ((PARAM_REGION &&
+                             SectorSuspend != read_addr/(SecSize+1)) ||
+                            (~PARAM_REGION &&
+                             SectorSuspend != read_addr/(SecSize+1)+30*b_act))
+                        begin
+                            if ((Instruct == DDRDIOR || Instruct == DDRDIOR4) &&
+                                (VDLR_reg != 8'b00000000) && start_dlp)
+                            begin
+                                // Data Learning Pattern (DLP)
+                                // is enabled Optional DLP
+                                data_out[7:0] = VDLR_reg;
+                                SOut_zd = data_out[7-read_cnt];
+                                SIOut_zd = data_out[7-read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 8)
+                                begin
+                                    read_cnt  = 0;
+                                    start_dlp = 1'b0;
+                                end
+                            end
+                            else
+                            begin
+                                data_out[7:0] = Mem[read_addr];
+                                SOut_zd = data_out[7-2*read_cnt];
+                                SIOut_zd = data_out[6-2*read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 4)
+                                begin
+                                    read_cnt = 0;
+                                    if (read_addr == AddrRANGE)
+                                        read_addr = 0;
+                                    else
+                                        read_addr = read_addr + 1;
+                                end
+                            end
+                        end
+                        else
+                        begin
+                            SOut_zd = 1'bx;
+                            SIOut_zd = 1'bx;
+                            read_cnt = read_cnt + 1;
+                            if (read_cnt == 4)
+                            begin
+                                read_cnt = 0;
+                                if (read_addr == AddrRANGE)
+                                    read_addr = 0;
+                                else
+                                    read_addr = read_addr + 1;
+                            end
+                        end
+                    end
+                    else if (Instruct == QOR  || Instruct == QOR4  ||
+                            Instruct == QIOR || Instruct == QIOR4 ||
+                            Instruct == DDRQIOR || Instruct == DDRQIOR4 )
+                    begin
+                        //Read Memory array
+                        if (Instruct == DDRQIOR || Instruct == DDRQIOR4)
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b1;
+                        end
+                        else
+                        begin
+                            rd_fast = 1'b0;
+                            rd_slow = 1'b0;
+                            dual    = 1'b1;
+                            ddr     = 1'b0;
+                        end
+                        if ((PARAM_REGION &&
+                             SectorSuspend != read_addr/(SecSize+1)) ||
+                            (~PARAM_REGION &&
+                             SectorSuspend != read_addr/(SecSize+1)+30*b_act))
+                        begin
+                            if ((Instruct == DDRQIOR || Instruct == DDRQIOR4) &&
+                                (VDLR_reg != 8'b00000000) && start_dlp)
+                            begin
+                                // Data Learning Pattern (DLP)
+                                // is enabled Optional DLP
+                                data_out[7:0] = VDLR_reg;
+                                HOLDNegOut_zd= data_out[7-read_cnt];
+                                WPNegOut_zd  = data_out[7-read_cnt];
+                                SOut_zd  = data_out[7-read_cnt];
+                                SIOut_zd  = data_out[7-read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 8)
+                                begin
+                                    read_cnt  = 0;
+                                    start_dlp = 1'b0;
+                                end
+                            end
+                            else
+                            begin
+                                data_out[7:0] = Mem[read_addr];
+                                HOLDNegOut_zd = data_out[7-4*read_cnt];
+                                WPNegOut_zd   = data_out[6-4*read_cnt];
+                                SOut_zd   = data_out[5-4*read_cnt];
+                                SIOut_zd   = data_out[4-4*read_cnt];
+                                read_cnt = read_cnt + 1;
+                                if (read_cnt == 2)
+                                begin
+                                    read_cnt = 0;
+                                    if (read_addr == AddrRANGE)
+                                        read_addr = 0;
+                                    else
+                                        read_addr = read_addr + 1;
+                                end
+                            end
+                        end
+                        else
+                        begin
+                            HOLDNegOut_zd = 1'bx;
+                            WPNegOut_zd   = 1'bx;
+                            SOut_zd   = 1'bx;
+                            SIOut_zd   = 1'bx;
+                            if (read_cnt == 2)
+                            begin
+                                read_cnt = 0;
+                                if (read_addr == AddrRANGE)
+                                    read_addr = 0;
+                                else
+                                    read_addr = read_addr + 1;
+                            end
+                        end
+                    end
+                end
+                else if (oe_z)
+                begin
+                    if (Instruct == READ || Instruct == RD4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b1;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                    end
+                    else if (Instruct == DDRFR || Instruct == DDRFR4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b1;
+                    end
+                    else if (Instruct == DDRDIOR || Instruct == DDRDIOR4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b1;
+                        ddr     = 1'b1;
+                    end
+                    else if (Instruct == DOR || Instruct == DOR4  ||
+                             Instruct == DIOR || Instruct == DIOR4 ||
+                             Instruct == QOR || Instruct == QOR4  ||
+                             Instruct == QIOR || Instruct == QIOR4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b1;
+                        ddr     = 1'b0;
+                    end
+                    else if (Instruct == DDRQIOR || Instruct == DDRQIOR4)
+                    begin
+                        rd_fast = 1'b0;
+                        rd_slow = 1'b0;
+                        dual    = 1'b1;
+                        ddr     = 1'b1;
+                    end
+                    else
+                    begin
+                        rd_fast = 1'b1;
+                        rd_slow = 1'b0;
+                        dual    = 1'b0;
+                        ddr     = 1'b0;
+                    end
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if (falling_edge_write)
+                begin
+                    if ((Instruct == PP || Instruct == PP4) && WEL == 1)
+                    begin
+                        if ((PARAM_REGION &&
+                             SectorSuspend != Address/(SecSize+1)) ||
+                            (~PARAM_REGION &&
+                             SectorSuspend != Address/(SecSize+1)+30*b_act))
+                        begin
+                            ReturnSectorID(sect,Address);
+                            if (Sec_Prot[sect] == 0 &&
+                                PPB_bits[sect]== 1 && DYB_bits[sect]== 1)
+                            begin
+                                PSTART = 1'b1;
+                                PSTART <= #5 1'b0;
+                                PGSUSP  = 0;
+                                PGRES   = 0;
+                                Status_reg1[0] = 1'b1;
+                                SA      = sect;
+                                Addr    = Address;
+                                Addr_tmp= Address;
+                                wr_cnt  = Byte_number;
+                                for (i=wr_cnt;i>=0;i=i-1)
+                                begin
+                                    if (Viol != 0)
+                                        WData[i] = -1;
+                                    else
+                                        WData[i] = WByte[i];
+                                end
+                            end
+                            else
+                            begin
+                                Status_reg1[1] = 1'b0;
+                                Status_reg1[6] = 1'b1;
+                            end
+                        end
+                        else
+                        begin
+                            Status_reg1[1] = 1'b0;
+                            Status_reg1[6] = 1'b1;
+                        end
+                    end
+                    else if ((Instruct == QPP || Instruct == QPP4) && WEL == 1)
+                    begin
+                        if ((PARAM_REGION &&
+                             SectorSuspend != Address/(SecSize+1)) ||
+                            (~PARAM_REGION &&
+                             SectorSuspend != Address/(SecSize+1)+30*b_act))
+                        begin
+                            ReturnSectorID(sect,Address);
+                            pgm_page = Address / (PageSize+1);
+
+                            if (Sec_Prot[sect] == 0 &&
+                                PPB_bits[sect]== 1 && DYB_bits[sect]== 1)
+                            begin
+                                PSTART = 1'b1;
+                                PSTART <= #5 1'b0;
+                                PGSUSP  = 0;
+                                PGRES   = 0;
+                                Status_reg1[0] = 1'b1;
+//                                QPP_page[pgm_page] = 1'b1;
+                                SA      = sect;
+                                Addr    = Address;
+                                Addr_tmp= Address;
+                                wr_cnt  = Byte_number;
+                                for (i=wr_cnt;i>=0;i=i-1)
+                                begin
+                                    if (Viol != 0)
+                                        WData[i] = -1;
+                                    else
+                                        WData[i] = WByte[i];
+                                end
+                            end
+                            else
+                            begin
+                                Status_reg1[1] = 1'b0;
+                                Status_reg1[6] = 1'b1;
+                            end
+                        end
+                        else
+                        begin
+                            Status_reg1[1] = 1'b0;
+                            Status_reg1[6] = 1'b1;
+                        end
+                    end
+                    else if (Instruct == WREN)
+                        Status_reg1[1] = 1'b1;
+                    else if (Instruct == CLSR)
+                    begin
+                    //The Clear Status Register Command resets bit SR1[5]
+                    //(Erase Fail Flag) and bit SR1[6] (Program Fail Flag)
+                        Status_reg1[5] = 0;
+                        Status_reg1[6] = 0;
+                    end
+                    else if (Instruct == BRWR)
+                    begin
+                        Bank_Addr_reg[7] = Bank_Addr_reg_in[7];
+                        Bank_Addr_reg[0] = Bank_Addr_reg_in[0];
+                        if(Bank_Addr_reg_in[1] == 1)
+                        begin
+                            $display ("WARNING: Changing values of ");
+                            $display ("Bank Address Register");
+                            $display ("BA25 is not allowed!!!");
+                        end
+                    end
+                    else if (Instruct == WRR && BAR_ACC == 1)
+                    begin
+                    // Write to the lower address bits of the BAR
+                        if (P_ERR == 0 && E_ERR == 0)
+                        begin
+                            Bank_Addr_reg[0] = Bank_Addr_reg_in[0];
+                            if(Bank_Addr_reg_in[1] == 1)
+                            begin
+                                $display ("WARNING: Changing values of ");
+                                $display ("Bank Address Register");
+                                $display ("BA25 is not allowed!!!");
+                            end
+                        end
+                    end
+                    else if (Instruct == DYBWR  && WEL == 1)
+                    begin
+                        ReturnSectorID(sect,Address);
+                        pgm_page = Address / (PageSize+1);
+                        PSTART = 1'b1;
+                        PSTART <= #5 1'b0;
+                        Status_reg1[0]    = 1'b1;
+                    end
+                    else if (Instruct == ERRS)
+                    begin
+                        Status_reg2[1]  = 1'b0;
+                        Status_reg1[0] = 1'b1;
+                        if (BottomBoot)
+                        begin
+                            if (PARAM_REGION)
+                            begin
+                                Addr = SectorSuspend*(SecSize+1);
+                            end
+                            else
+                            begin
+                                Addr = (SectorSuspend-30)*(SecSize+1);
+                            end
+                        end
+                        else
+                        begin
+                            Addr = SectorSuspend*(SecSize+1);
+                        end
+                        ADDRHILO_SEC(AddrLo, AddrHi, Addr);
+                        ERES = 1'b1;
+                        ERES <= #5 1'b0;
+                        RES_TO_SUSP_TYP_TIME = 1'b1;
+                        RES_TO_SUSP_TYP_TIME <= #100000000 1'b0;//100us
+                    end
+
+                    if (Instruct == BRAC && P_ERR == 0 && E_ERR == 0 &&
+                        RdPswdProtMode == 0)
+                    begin
+                        BAR_ACC = 1;
+                    end
+                    else
+                    begin
+                        BAR_ACC = 0;
+                    end
+                end
+            end
+
+            ERS_SUSP_PG:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register 2
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if(current_state_event && current_state == ERS_SUSP_PG)
+                begin
+                    if (~PDONE)
+                    begin
+                        ADDRHILO_PG(AddrLo, AddrHi, Addr);
+                        cnt = 0;
+                        for (i=0;i<=wr_cnt;i=i+1)
+                        begin
+                            new_int = WData[i];
+                            old_int = Mem[Addr + i - cnt];
+                            if (new_int > -1)
+                            begin
+                                new_bit = new_int;
+                                if (old_int > -1)
+                                begin
+                                    old_bit = old_int;
+                                    for(j=0;j<=7;j=j+1)
+                                    begin
+                                        if (~old_bit[j])
+                                            new_bit[j] = 1'b0;
+                                    end
+                                    new_int = new_bit;
+                                end
+                                WData[i] = new_int;
+                            end
+                            else
+                            begin
+                                WData[i] = -1;
+                            end
+
+                            if ((Addr + i) == AddrHi)
+                            begin
+                                Addr = AddrLo;
+                                cnt = i + 1;
+                            end
+                        end
+                    end
+                    cnt =0;
+                end
+
+                if(PDONE == 1)
+                begin
+                    Status_reg1[0] = 1'b0;//WIP
+                    Status_reg1[1] = 1'b0;//WEL
+                    for (i=0;i<=wr_cnt;i=i+1)
+                    begin
+                        Mem[Addr_tmp + i - cnt] = WData[i];
+                        if ((Addr_tmp + i) == AddrHi )
+                        begin
+                            Addr_tmp = AddrLo;
+                            cnt = i + 1;
+                        end
+                    end
+                end
+
+                if (Instruct)
+                begin
+                    if (Instruct == PGSP && ~PRGSUSP_in)
+                    begin
+                        if (~RES_TO_SUSP_MIN_TIME)
+                        begin
+                            PGSUSP = 1'b1;
+                            PGSUSP <= #5 1'b0;
+                            PRGSUSP_in = 1'b1;
+                            if (RES_TO_SUSP_TYP_TIME)
+                            begin
+                                $display("Typical periods are needed for ",
+                                         "Program to progress to completion");
+                            end
+                        end
+                        else
+                        begin
+                            $display("Minimum for tPRS is not satisfied! ",
+                                     "PGSP command is ignored");
+                        end
+                    end
+                end
+            end
+
+            PASS_PG:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                new_pass = Password_reg_in;
+                old_pass = Password_reg;
+                for (i=0;i<=63;i=i+1)
+                begin
+                    if (old_pass[j] == 0)
+                        new_pass[j] = 0;
+                end
+
+                if (PDONE == 1)
+                begin
+                    Password_reg = new_pass;
+                    Status_reg1[0] = 1'b0;
+                    Status_reg1[1] = 1'b0;
+                end
+            end
+
+            PASS_UNLOCK:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if (PASS_TEMP == Password_reg)
+                begin
+                    PASS_UNLOCKED = 1'b1;
+                end
+                else
+                begin
+                    PASS_UNLOCKED = 1'b0;
+                end
+                if (PASSULCK_out == 1'b1)
+                begin
+                    if ((PASS_UNLOCKED == 1'b1) && (~PWDMLB))
+                    begin
+                        PPBL[0] = 1'b1;
+                        Status_reg1[0] = 1'b0; //WIP
+                    end
+                    else
+                    begin
+                        Status_reg1[6] = 1'b1;
+                        $display ("Incorrect Password");
+                        PASSACC_in = 1'b1;
+                    end
+                    Status_reg1[1] = 1'b0;
+                    PASSULCK_in = 1'b0;
+                end
+            end
+
+            PPB_PG:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if (PDONE)
+                begin
+                    if (PPB_LOCK !== 0)
+                    begin
+                        PPB_bits[sect]= 1'b0;
+                        Status_reg1[0] = 1'b0;
+                        Status_reg1[1] = 1'b0;
+                    end
+                    else
+                    begin
+                        Status_reg1[5] = 1'b0;
+                        Status_reg1[0] = 1'b0;
+                        Status_reg1[1] = 1'b0;
+                    end
+                end
+            end
+
+            PPB_ERS:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if (PPBERASE_out == 1'b1)
+                begin
+                    if ((PPB_LOCK !== 0) && PPBOTP)
+                    begin
+                        PPB_bits = {542{1'b1}};
+                    end
+                    else
+                    begin
+                        Status_reg1[5] = 1'b1;
+                    end
+                    Status_reg1[0] = 1'b0;
+                    Status_reg1[1] = 1'b0;
+                    PPBERASE_in = 1'b0;
+                end
+            end
+
+            AUTOBOOT_PG:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register 2
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if (PDONE)
+                begin
+                    for(i=0;i<=3;i=i+1)
+                        for(j=0;j<=7;j=j+1)
+                            AutoBoot_reg[i*8+j] =
+                            AutoBoot_reg_in[(3-i)*8+j];
+                    Status_reg1[0] = 1'b0;
+                    Status_reg1[1] = 1'b0;
+                end
+            end
+
+            PLB_PG:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if (PDONE)
+                begin
+                    PPBL[0] = 1'b0;
+                    Status_reg1[0] = 1'b0;
+                    Status_reg1[1] = 1'b0;
+                end
+            end
+
+            DYB_PG:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if (PDONE)
+                begin
+                    DYBAR = DYBAR_in;
+                    if (DYBAR == 8'hFF)
+                    begin
+                        DYB_bits[sect]= 1'b1;
+                    end
+                    else if (DYBAR == 8'h00)
+                    begin
+                        DYB_bits[sect]= 1'b0;
+                    end
+                    else
+                    begin
+                        Status_reg1[6] = 1'b1;
+                    end
+                    Status_reg1[0] = 1'b0;
+                    Status_reg1[1] = 1'b0;
+                end
+            end
+
+            ASP_PG:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if (PDONE)
+                begin
+
+                    if (RPME == 1'b0 && ASP_reg_in[5] == 1'b1)
+                    begin
+                       Status_reg1[6] = 1'b1; //P_ERR
+                       $display("RPME bit is allready programmed");
+                    end
+                    else
+                    begin
+                        ASP_reg[5] = ASP_reg_in[5];//RPME
+                    end
+
+                    if (PPBOTP == 1'b0 && ASP_reg_in[3] == 1'b1)
+                    begin
+                       Status_reg1[6] = 1'b1; //P_ERR
+                       $display("PPBOTP bit is allready programmed");
+                    end
+                    else
+                    begin
+                        ASP_reg[3] = ASP_reg_in[3];//PPBOTP
+                    end
+
+                    if (PWDMLB == 1'b1 && PSTMLB == 1'b1)
+                    begin
+                        if (ASP_reg_in[2] == 1'b0 && ASP_reg_in[1] == 1'b0)
+                        begin
+                            $display("ASPR[2:1] = 00  Illegal condition");
+                            Status_reg1[6] = 1'b1; //P_ERR
+                        end
+                        else
+                        begin
+                            if (ASP_reg_in[2]!==1'b1 || ASP_reg_in[1]!==1'b1)
+                            begin
+                                ASPOTPFLAG = 1'b1;
+                            end
+                            ASP_reg[2] = ASP_reg_in[2];//PWDMLB
+                            ASP_reg[1] = ASP_reg_in[1];//PSTMLB
+                        end
+                    end
+
+                    Status_reg1[0] = 1'b0;
+                    Status_reg1[1] = 1'b0;
+                end
+            end
+
+            NVDLR_PG:
+            begin
+                rd_fast = 1'b1;
+                rd_slow = 1'b0;
+                dual    = 1'b0;
+                ddr     = 1'b0;
+                if (oe)
+                begin
+                    any_read = 1'b1;
+                    if (Instruct == RDSR)
+                    begin
+                    //Read Status Register 1
+                        SOut_zd = Status_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDSR2)
+                    begin
+                    //Read Status Register
+                        SOut_zd = Status_reg2[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                    else if (Instruct == RDCR)
+                    begin
+                        //Read Configuration Register 1
+                        SOut_zd = Config_reg1[7-read_cnt];
+                        read_cnt = read_cnt + 1;
+                        if (read_cnt == 8)
+                            read_cnt = 0;
+                    end
+                end
+                else if (oe_z)
+                begin
+                    HOLDNegOut_zd = 1'bZ;
+                    WPNegOut_zd   = 1'bZ;
+                    SOut_zd       = 1'bZ;
+                    SIOut_zd      = 1'bZ;
+                end
+
+                if (PDONE)
+                begin
+                    if (NVDLR_reg == 0)
+                    begin
+                        NVDLR_reg = NVDLR_reg_in;
+                        VDLR_reg = NVDLR_reg_in;
+                        Status_reg1[0] = 1'b0;
+                        Status_reg1[1] = 1'b0;
+                    end
+                    else
+                    begin
+                        Status_reg1[0] = 1'b0;
+                        Status_reg1[1] = 1'b0;
+                        Status_reg1[6] = 1'b1; //P_ERR
+                        $display("NVDLR bits allready programmed");
+                    end
+                end
+            end
+
+            RESET_STATE:
+            begin
+            //the default condition hardware reset
+            //The Bank Address Register is loaded to all zeroes
+                Bank_Addr_reg = 8'h0;
+                if (BPNV && ~FREEZE) //&& ~LOCK 
+                begin
+                    Status_reg1[2] = 1'b1;// BP0
+                    Status_reg1[3] = 1'b1;// BP1
+                    Status_reg1[4] = 1'b1;// BP2
+                    BP_bits = 3'b111;
+                    change_BP = 1'b1;
+                    #1000 change_BP = 1'b0;
+                end
+                //Resets the volatile bits in the Status register 1
+                Status_reg1[6] = 1'b0;
+                Status_reg1[5] = 1'b0;
+                Status_reg1[1] = 1'b0;
+                Status_reg1[0] = 1'b0;
+                //Resets the volatile bits in the Status register 2
+                Status_reg2[1] = 1'b0;
+                Status_reg2[0] = 1'b0;
+                //Resets the volatile bits in the Configuration register 1
+                Config_reg1[0] = 1'b0;
+                //On reset cycles the data pattern reverts back
+                //to what is in the NVDLR
+                VDLR_reg = NVDLR_reg;
+                start_dlp = 1'b0;
+                //Loads the Program Buffer with all ones
+                for(i=0;i<=511;i=i+1)
+                begin
+                    WData[i] = MaxData;
+                end
+                if (~PWDMLB)
+                    PPBL[0] = 1'b0;
+                else
+                    PPBL[0] = 1'b1;
+            end
+
+        endcase
+
+        //Output Disable Control
+        if (CSNeg_ipd )
+        begin
+            SOut_zd = 1'bZ;
+            SIOut_zd = 1'bZ;
+            HOLDNegOut_zd = 1'bZ;
+            WPNegOut_zd = 1'bZ;
+        end
+    end
+
+    assign fast_rd = rd_fast;
+    assign rd = rd_slow;
+    assign ddrd = ddr && ~ddr80;
+    assign ddrd80 = ddr && ddr80;
+    assign fast_ddr = ddr_fast;
+
+    always @(change_TBPARM, posedge PoweredUp)
+    begin
+        if (tmp_char2 == "0")
+        begin
+            if (TBPARM == 0)
+            begin
+                BottomBoot = 1;
+                b_act = 1;
+            end
+            else
+            begin
+                TopBoot     = 1;
+                BottomBoot  = 0;
+                b_act = 0;
+            end
+        end
+        else if (tmp_char2 == "1")
+        begin
+            UniformSec = 1;
+        end
+    end
+
+    always @(posedge change_BP)
+    begin
+        case (Status_reg1[4:2])
+
+            3'b000:
+            begin
+                Sec_Prot[541:0] = {542{1'b0}};
+            end
+            3'b001:
+            begin
+                if (tmp_char2 == "1")
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum256:(SecNum256+1)*63/64] = 2'b11;
+                        Sec_Prot[(SecNum256+1)*63/64-1 : 0] = 126'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum256+1)/64-1 : 0] = 2'b11;
+                        Sec_Prot[SecNum256 : (SecNum256+1)/64] = 126'h0;
+                    end
+                end
+                else if (tmp_char2 == "0" && TBPARM == 1)
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum64:(SecNum64-29)*63/64] = {38{1'b1}};
+                        Sec_Prot[(SecNum64-29)*63/64-1 : 0]    = 504'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum64-29)/64-1 : 0] = {8{1'b1}};
+                        Sec_Prot[SecNum64 : (SecNum64-29)/64] = 534'h0;
+                    end
+                end
+                else
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum64:(SecNum64-29)*63/64+30] = {8{1'b1}};
+                        Sec_Prot[(SecNum64-29)*63/64+29 : 0] = 534'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum64-29)/64+29 : 0]        = {38{1'b1}};
+                        Sec_Prot[SecNum64 : (SecNum64-29)/64+30] = 504'h0;
+                    end
+                end
+            end
+
+            3'b010:
+            begin
+                if (tmp_char2 == "1")
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum256 : (SecNum256+1)*31/32] = {4{1'b1}};
+                        Sec_Prot[(SecNum256+1)*31/32-1 : 0] = 124'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum256+1)/32-1 : 0] = {4{1'b1}};
+                        Sec_Prot[SecNum256 : (SecNum256+1)/32] = 124'h0;
+                    end
+                end
+                else if (tmp_char2 == "0" && TBPARM == 1)
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum64 : (SecNum64-29)*31/32] = {46{1'b1}};
+                        Sec_Prot[(SecNum64-29)*31/32-1 : 0] = 496'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum64-29)/32-1 : 0] = {16{1'b1}};
+                        Sec_Prot[SecNum64 : (SecNum64-29)/32] = 526'h0;
+                    end
+                end
+                else
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum64:(SecNum64-29)*31/32+30] = {16{1'b1}};
+                        Sec_Prot[(SecNum64-29)*31/32+29 : 0] = 526'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum64-29)/32+29 : 0] = {46{1'b1}};
+                        Sec_Prot[SecNum64 : (SecNum64-29)/32+30] = 496'h0;
+                    end
+                end
+            end
+
+            3'b011:
+            begin
+                if (tmp_char2 == "1")
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum256 : (SecNum256+1)*15/16] = 8'hFF;
+                        Sec_Prot[(SecNum256+1)*15/16-1 : 0] = 120'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum256+1)/16-1 : 0] = 8'hFF;
+                        Sec_Prot[SecNum256 : (SecNum256+1)/16] = 120'h0;
+                    end
+                end
+                else if (tmp_char2 == "0" && TBPARM == 1)
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum64 : (SecNum64-29)*15/16] = {62{1'b1}};
+                        Sec_Prot[(SecNum64-29)*15/16-1 : 0] = 480'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum64-29)/16-1 : 0] = {32{1'b1}};
+                        Sec_Prot[SecNum64 : (SecNum64-29)/16] = 510'h0;
+                    end
+                end
+                else
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum64 : (SecNum64-29)*15/16+30]={32{1'b1}};
+                        Sec_Prot[(SecNum64-29)*15/16+29 : 0] = 510'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum64-29)/16+29 : 0] ={62{1'b1}};
+                        Sec_Prot[SecNum64 : (SecNum64-29)/16+30] = 480'h0;
+                    end
+                end
+            end
+
+            3'b100:
+            begin
+                if (tmp_char2 == "1")
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum256 : (SecNum256+1)*7/8] = {16{1'b1}};
+                        Sec_Prot[(SecNum256+1)*7/8-1 : 0] = 112'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum256+1)/8-1 : 0] = {16{1'b1}};
+                        Sec_Prot[SecNum256 : (SecNum256+1)/8] = 112'h0;
+                    end
+                end
+                else if (tmp_char2 == "0" && TBPARM == 1)
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum64 : (SecNum64-29)*7/8] = {94{1'b1}};
+                        Sec_Prot[(SecNum64-29)*7/8-1 : 0] = 448'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum64-29)/8-1 : 0] = {64{1'b1}};
+                        Sec_Prot[SecNum64 : (SecNum64-29)/8] = 478'h0;
+                    end
+                end
+                else
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum64 : (SecNum64-29)*7/8+30] ={64{1'b1}};
+                        Sec_Prot[(SecNum64-29)*7/8+29 : 0] = 478'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum64-29)/8+29 : 0] = {94{1'b1}};
+                        Sec_Prot[SecNum64 : (SecNum64-29)/8+30] = 448'h0;
+                    end
+                end
+            end
+
+            3'b101:
+            begin
+                if (tmp_char2 == "1")
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum256 : (SecNum256+1)*3/4] = {32{1'b1}};
+                        Sec_Prot[(SecNum256+1)*3/4-1 : 0] = 96'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum256+1)/4-1 : 0] = {32{1'b1}};
+                        Sec_Prot[SecNum256 : (SecNum256+1)/4] = 96'h0;
+                    end
+                end
+                else if (tmp_char2 == "0" && TBPARM == 1)
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum64 : (SecNum64-29)*3/4] = {158{1'b1}};
+                        Sec_Prot[(SecNum64-29)*3/4-1 : 0] = 384'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum64-29)/4-1 : 0] = {128{1'b1}};
+                        Sec_Prot[SecNum64 : (SecNum64-29)/4] = 414'h0;
+                    end
+                end
+                else
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum64 : (SecNum64-29)*3/4+30] = {128{1'b1}};
+                        Sec_Prot[(SecNum64-29)*3/4+29 : 0] = 414'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum64-29)/4+29 : 0] = {158{1'b1}};
+                        Sec_Prot[SecNum64 : (SecNum64-29)/4+30] = 384'h0;
+                    end
+                end
+            end
+
+            3'b110:
+            begin
+                if (tmp_char2 == "1")
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum256 : (SecNum256+1)/2] = {64{1'b1}};
+                        Sec_Prot[(SecNum256+1)/2-1 : 0] = 64'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum256+1)/2-1 : 0] = {64{1'b1}};
+                        Sec_Prot[SecNum256 : (SecNum256+1)/2] = 64'h0;
+                    end
+                end
+                else if (tmp_char2 == "0" && TBPARM == 1)
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum64 : (SecNum64-29)/2] = {286{1'b1}};
+                        Sec_Prot[(SecNum64-29)/2-1 : 0] = 256'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum64-29)/2-1 : 0] = {256{1'b1}};
+                        Sec_Prot[SecNum64 : (SecNum64-29)/2] = 286'h0;
+                    end
+                end
+                else
+                begin
+                    if (~TBPROT)
+                    begin
+                        Sec_Prot[SecNum64 : (SecNum64-29)/2+30] = {256{1'b1}};
+                        Sec_Prot[(SecNum64-29)/2+29 : 0] = 286'h0;
+                    end
+                    else
+                    begin
+                        Sec_Prot[(SecNum64-29)/2+29 : 0] = {286{1'b1}};
+                        Sec_Prot[SecNum64 : (SecNum64-29)/2+30] = 256'h0;
+                    end
+                end
+            end
+
+            3'b111:
+            begin
+                Sec_Prot[SecNum64:0] =  {542{1'b1}};
+            end
+        endcase
+    end
+
+    always @(SOut_zd or HOLDNeg_in or SIOut_zd)
+    begin
+        if (HOLDNeg_in == 0 && ~QUAD)
+        begin
+            hold_mode = 1'b1;
+            SIOut_z   = 1'bZ;
+            SOut_z    = 1'bZ;
+        end
+        else
+        begin
+            if (hold_mode == 1)
+            begin
+                SIOut_z <= #(tpd_HOLDNeg_SO) SIOut_zd;
+                SOut_z  <= #(tpd_HOLDNeg_SO) SOut_zd;
+                hold_mode = #(tpd_HOLDNeg_SO) 1'b0;
+            end
+            else
+            begin
+                SIOut_z = SIOut_zd;
+                SOut_z  = SOut_zd;
+                hold_mode = 1'b0;
+            end
+        end
+    end
+
+    ////////////////////////////////////////////////////////////////////////
+    // autoboot control logic
+    ////////////////////////////////////////////////////////////////////////
+    always @(rising_edge_SCK_ipd or current_state_event)
+    begin
+        if(current_state == AUTOBOOT)
+        begin
+            if (rising_edge_SCK_ipd)
+            begin
+                if (start_delay > 0)
+                    start_delay = start_delay - 1;
+            end
+
+            if (start_delay == 0)
+            begin
+                start_autoboot = 1;
+            end
+        end
+    end
+
+    ////////////////////////////////////////////////////////////////////////
+    // functions & tasks
+    ////////////////////////////////////////////////////////////////////////
+    // Procedure FDDR_DPL
+task Return_DLP;
+    input integer Instruct;
+    input integer EHP;
+    input integer Latency_code;
+    input integer dummy_cnt;
+    inout start_dlp;
+    begin
+        if (Instruct == DDRFR || Instruct == DDRFR4)
+        begin
+            if (EHP)
+            begin
+                if (Latency_code == 1)
+                    start_dlp = 1'b1;
+                else if (Latency_code == 2 && dummy_cnt >= 1)
+                    start_dlp = 1'b1;
+                else if(Latency_code == 3 || Latency_code == 0)
+                begin
+                    start_dlp = 1'b0;
+                    $display("Warning at", $time);
+                    $display("Inappropriate latency is set during DPL mode");
+                end
+            end
+            else
+            begin
+
+                if (Latency_code == 3)
+                    start_dlp = 1'b1;
+                else if (Latency_code == 0 && dummy_cnt >= 1)
+                    start_dlp = 1'b1;
+                else if(Latency_code == 1 && dummy_cnt >= 2)
+                    start_dlp = 1'b1;
+                else if(Latency_code == 2 && dummy_cnt >= 3)
+                    start_dlp = 1'b1;
+                else
+                    start_dlp = 1'b0;
+            end
+        end
+        if (Instruct == DDRDIOR || Instruct == DDRDIOR4)
+        begin
+            if (EHP)
+            begin
+                if (Latency_code == 1 && dummy_cnt >= 1)
+                    start_dlp = 1'b1;
+                else if (Latency_code == 2 && dummy_cnt >= 2)
+                    start_dlp = 1'b1;
+                else if( Latency_code == 3 || Latency_code == 0)
+                begin
+                    start_dlp = 1'b0;
+                    $display("Warning at", $time);
+                    $display("Inappropriate latency is set during DPL mode");
+                end
+                else
+                    start_dlp = 1'b0;
+            end
+            else
+            begin
+                if (Latency_code == 0 && dummy_cnt >= 2)
+                    start_dlp = 1'b1;
+                else if (Latency_code == 1 && dummy_cnt >= 3)
+                    start_dlp = 1'b1;
+                else if(Latency_code == 2 && dummy_cnt >= 4)
+                    start_dlp = 1'b1;
+                else
+                    start_dlp = 1'b0;
+            end
+        end
+        if ((Instruct == DDRQIOR || Instruct == DDRQIOR4) && QUAD)
+        begin
+            if (EHP)
+            begin
+                if (Latency_code == 0 && dummy_cnt >= 2)
+                    start_dlp = 1'b1;
+                else if (Latency_code == 1 && dummy_cnt >= 3)
+                    start_dlp = 1'b1;
+                else if (Latency_code == 2 && dummy_cnt >= 4)
+                    start_dlp = 1'b1;
+                else if( Latency_code == 3)
+                begin
+                    start_dlp = 1'b0;
+                    $display("Warning at", $time);
+                    $display("Inappropriate latency is");
+                    $display("set during DPL mode");
+                end
+                else
+                    start_dlp  = 1'b0;
+
+            end
+            else
+            begin
+                if (Latency_code == 0 && dummy_cnt >= 2)
+                    start_dlp = 1'b1;
+                else if (Latency_code == 1 && dummy_cnt >= 3)
+                    start_dlp = 1'b1;
+                else if (Latency_code == 2 && dummy_cnt >= 4)
+                    start_dlp = 1'b1;
+                else if( Latency_code == 3)
+                begin
+                    start_dlp = 1'b0;
+                    $display("Warning at", $time);
+                    $display("Inappropriate latency is");
+                    $display("set during DPL mode");
+                end
+                else
+                    start_dlp = 1'b0;
+            end
+        end
+    end
+    endtask
+
+    function integer ReturnSectorIDRdPswdMd;
+        input reg TBPROT;
+    begin
+        if(TBPROT == 0)
+        begin
+            ReturnSectorIDRdPswdMd = 0;
+        end
+        else
+        begin
+            if (UniformSec)
+            begin
+                ReturnSectorIDRdPswdMd = SecNum256;
+            end
+            else
+            begin
+                ReturnSectorIDRdPswdMd = 511;
+            end
+        end
+    end
+    endfunction
+
+    // Procedure ADDRHILO_SEC
+    task ADDRHILO_SEC;
+    inout  AddrLOW;
+    inout  AddrHIGH;
+    input   Addr;
+    integer AddrLOW;
+    integer AddrHIGH;
+    integer Addr;
+    integer sector;
+    begin
+        if (tmp_char2 == "0")
+        begin
+            if (TBPARM == 0)
+            begin
+                if (Addr/(SecSize64+1) <= 1 &&
+                   (Instruct == P4E || Instruct == P4E4))  //4KB Sectors
+                begin
+                    sector   = Addr/(SecSize4+1);
+                    AddrLOW  = sector*(SecSize4+1);
+                    AddrHIGH = sector*(SecSize4+1) + SecSize4;
+                end
+                else
+                begin
+                    sector   = Addr/(SecSize64+1);
+                    AddrLOW  = sector*(SecSize64+1);
+                    AddrHIGH = sector*(SecSize64+1) + SecSize64;
+                end
+            end
+            else
+            begin
+                if (Addr/(SecSize64+1) >= 510 &&
+                   (Instruct == P4E || Instruct == P4E4)) //4KB Sectors
+                begin
+                    sector   = 510 + (Addr-(SecSize64+1)*510)/(SecSize4+1);
+                    AddrLOW  = 510*(SecSize64+1)+(sector-510)*(SecSize4+1);
+                    AddrHIGH = 510*(SecSize64+1)+
+                                   (sector-510)*(SecSize4+1) + SecSize4;
+                end
+                else
+                begin
+                    sector   = Addr/(SecSize64+1);
+                    AddrLOW  = sector*(SecSize64+1);
+                    AddrHIGH = sector*(SecSize64+1) + SecSize64;
+                end
+            end
+        end
+        else if (tmp_char2 == "1")
+        begin
+            sector   = Addr/(SecSize256+1);
+            AddrLOW  = sector*(SecSize256+1);
+            AddrHIGH = sector*(SecSize256+1) + SecSize256;
+        end
+    end
+    endtask
+
+    // Procedure ADDRHILO_PG
+    task ADDRHILO_PG;
+    inout  AddrLOW;
+    inout  AddrHIGH;
+    input   Addr;
+    integer AddrLOW;
+    integer AddrHIGH;
+    integer Addr;
+    integer page;
+    begin
+        page = Addr / (PageSize + 1);
+        AddrLOW = page * (PageSize + 1);
+        AddrHIGH = page * (PageSize + 1) + PageSize ;
+    end
+    endtask
+
+    // Procedure ReturnSectorID
+    task ReturnSectorID;
+    inout   sect;
+    input   Address;
+    integer sect;
+    integer Address;
+    integer conv;
+    begin
+        if (tmp_char2 == "0")
+        begin
+            conv = Address / (SecSize64+1);
+            if (BottomBoot)
+            begin
+                if (conv <= 1)      //4KB Sectors
+                begin
+                    sect = Address/(SecSize4+1);
+                end
+                else
+                begin
+                    sect = conv + 30;
+                end
+            end
+            else if (TopBoot)
+            begin
+                if (conv >= 510)       //4KB Sectors
+                begin
+                    sect = 510 + (Address-(SecSize64+1)*510)/(SecSize4+1);
+                end
+                else
+                begin
+                    sect = conv;
+                end
+            end
+        end
+        else
+        begin
+            sect = Address/(SecSize256+1);
+        end
+    end
+    endtask
+
+    always @(PPBL[0], ASP_reg)
+    begin
+        if (PPBL[0] == 0 && PWDMLB == 0 && RPME == 0 && RdPswdProtEnable)
+        begin
+            RdPswdProtMode = 1;
+            AutoBoot_reg[0] = 0;//AUTOBOOT is disabled when Read Password
+        end                     //Protection is enabled
+        else
+        begin
+            RdPswdProtMode = 0;
+        end
+    end
+
+    ///////////////////////////////////////////////////////////////////////////
+    // edge controll processes
+    ///////////////////////////////////////////////////////////////////////////
+
+    always @(posedge PoweredUp)
+    begin
+        rising_edge_PoweredUp = 1;
+        #1000 rising_edge_PoweredUp = 0;
+    end
+
+    always @(posedge SCK_ipd)
+    begin
+       rising_edge_SCK_ipd = 1'b1;
+       #1000 rising_edge_SCK_ipd = 1'b0;
+    end
+
+    always @(negedge SCK_ipd)
+    begin
+       falling_edge_SCK_ipd = 1'b1;
+       #1000 falling_edge_SCK_ipd = 1'b0;
+    end
+
+    always @(posedge read_out)
+    begin
+        rising_edge_read_out = 1'b1;
+        #1000 rising_edge_read_out = 1'b0;
+    end
+
+    always @(negedge write)
+    begin
+        falling_edge_write = 1;
+        #1000 falling_edge_write = 0;
+    end
+
+    always @(posedge PRGSUSP_out)
+    begin
+        PRGSUSP_out_event = 1;
+        #1000 PRGSUSP_out_event = 0;
+    end
+
+    always @(posedge ERSSUSP_out)
+    begin
+        ERSSUSP_out_event = 1;
+        #1000 ERSSUSP_out_event = 0;
+    end
+
+    always @(posedge CSNeg_ipd)
+    begin
+        rising_edge_CSNeg_ipd = 1'b1;
+        #1000 rising_edge_CSNeg_ipd = 1'b0;
+    end
+
+    always @(negedge CSNeg_ipd)
+    begin
+        falling_edge_CSNeg_ipd = 1'b1;
+        #1000 falling_edge_CSNeg_ipd = 1'b0;
+    end
+
+    always @(negedge RSTNeg_in)
+    begin
+        falling_edge_RSTNeg = 1'b1;
+        #50000 falling_edge_RSTNeg = 1'b0;
+    end
+
+    always @(posedge RSTNeg_in)
+    begin
+        rising_edge_RSTNeg = 1'b1;
+        #10000 rising_edge_RSTNeg = 1'b0;
+    end
+
+    always @(negedge RST)
+    begin
+        falling_edge_RST = 1'b1;
+        #10000 falling_edge_RST = 1'b0;
+    end
+
+    always @(posedge RST)
+    begin
+        rising_edge_RST = 1'b1;
+        #1000 rising_edge_RST = 1'b0;
+    end
+
+    always @(posedge PDONE)
+    begin
+        rising_edge_PDONE = 1'b1;
+        #1000 rising_edge_PDONE = 1'b0;
+    end
+
+    always @(posedge WDONE)
+    begin
+        rising_edge_WDONE = 1'b1;
+        #1000 rising_edge_WDONE = 1'b0;
+    end
+
+    always @(posedge WSTART)
+    begin
+        rising_edge_WSTART = 1'b1;
+        #1000 rising_edge_WSTART = 1'b0;
+    end
+
+    always @(posedge EDONE)
+    begin
+        rising_edge_EDONE = 1'b1;
+        #1000 rising_edge_EDONE = 1'b0;
+    end
+
+    always @(posedge ESTART)
+    begin
+        rising_edge_ESTART = 1'b1;
+        #1000 rising_edge_ESTART = 1'b0;
+    end
+
+    always @(posedge PSTART)
+    begin
+        rising_edge_PSTART = 1'b1;
+        #1000 rising_edge_PSTART = 1'b0;
+    end
+
+    always @(posedge Reseted)
+    begin
+        rising_edge_Reseted = 1'b1;
+        #1000 rising_edge_Reseted = 1'b0;
+    end
+
+    always @(negedge PASSULCK_in)
+    begin
+        falling_edge_PASSULCK_in = 1'b1;
+        #1000 falling_edge_PASSULCK_in = 1'b0;
+    end
+
+    always @(negedge PPBERASE_in)
+    begin
+        falling_edge_PPBERASE_in = 1'b1;
+        #1000 falling_edge_PPBERASE_in = 1'b0;
+    end
+
+    always @(Instruct)
+    begin
+        Instruct_event = 1'b1;
+        #1000 Instruct_event = 1'b0;
+    end
+
+    always @(change_addr)
+    begin
+        change_addr_event = 1'b1;
+        #1000 change_addr_event = 1'b0;
+    end
+
+    always @(next_state)
+    begin
+        next_state_event = 1'b1;
+        #1000 next_state_event = 1'b0;
+    end
+
+    always @(current_state)
+    begin
+        current_state_event = 1'b1;
+        #1000 current_state_event = 1'b0;
+    end
+
+    always @(posedge RST_out)
+    begin
+        rising_edge_RST_out = 1'b1;
+        #1000 rising_edge_RST_out = 1'b0;
+    end
+
+endmodule
diff --git a/verilog/dv/model/spiram.v b/verilog/dv/model/spiram.v
new file mode 100644
index 0000000..cd33c11
--- /dev/null
+++ b/verilog/dv/model/spiram.v
@@ -0,0 +1,329 @@
+`default_nettype none
+/*
+ *  SPDX-FileCopyrightText: 2022 <Dinesh Annayya>
+ *
+ *  Riscdunio 
+ *
+ *  Copyright (C) 2022  Dinesh Annayya <dinesha.opencore.org>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ *  SPDX-License-Identifier: ISC
+ */
+
+`timescale 1 ns / 1 ps
+
+//
+// Simple SPI Ram simulation model for 128Kx8 LOW VOLTAGE, FAST SERIAL SRAM
+// (IS62/65WVS1288GALL)
+//
+// This model samples io input signals 1ns before the SPI clock edge and
+// updates output signals 1ns after the SPI clock edge.
+//
+// Supported commands:
+//    0x03, 0x02, 0x3B , 0x38, 0xFF, 0x05 , 0x01
+//    Instruction   Hex     Description
+//    READ          0x03    Read data from memory array beginning at selected address
+//    WRITE         0x02    Write data to memory array beginning at selected address
+//    ESDI          0x3B    Enter SDI mode
+//    ESQI          0x38    Enter SQI mode
+//    RSTDQI        0xFF    Reset SDI/SQI mode
+//    RDMR          0x05    Read Mode Register
+//    WRMR          0x01    Write Mode Register
+//
+
+module spiram #(
+	parameter mem_file_name = "firmware.hex"
+)(
+	input csb,
+	input clk,
+	inout io0, // MOSI
+	inout io1, // MISO
+	inout io2,
+	inout io3
+);
+	localparam verbose = 0;
+	localparam integer latency = 8;
+	
+	reg [7:0] buffer;
+	reg [3:0] reset_count = 0;
+	reg [3:0] reset_monitor = 0;
+	integer bitcount = 0;
+	integer bytecount = 0;
+	integer dummycount = 0;
+
+	reg [7:0] spi_cmd;
+	reg [23:0] spi_addr;
+
+	reg [7:0] spi_in;
+	reg [7:0] spi_out;
+	reg spi_io_vld;
+
+
+	localparam [1:0] sspi     = 1;
+	localparam [1:0] dspi     = 2;
+	localparam [1:0] qspi     = 3;
+
+	localparam [3:0] mode_sspi_rd     = 1;
+	localparam [3:0] mode_sspi_wr     = 2;
+	localparam [3:0] mode_dspi_rd     = 3;
+	localparam [3:0] mode_dspi_wr     = 4;
+	localparam [3:0] mode_qspi_rd     = 5;
+	localparam [3:0] mode_qspi_wr     = 6;
+
+	reg [3:0] spi_phase = mode_sspi_rd;
+	reg [3:0] spi_data_phase = 0;
+	reg [3:0] spi_mode = sspi;
+
+	reg io0_oe = 0;
+	reg io1_oe = 0;
+	reg io2_oe = 0;
+	reg io3_oe = 0;
+
+	reg io0_dout = 0;
+	reg io1_dout = 0;
+	reg io2_dout = 0;
+	reg io3_dout = 0;
+
+	assign #1 io0 = io0_oe ? io0_dout : 1'bz;
+	assign #1 io1 = io1_oe ? io1_dout : 1'bz;
+	assign #1 io2 = io2_oe ? io2_dout : 1'bz;
+	assign #1 io3 = io3_oe ? io3_dout : 1'bz;
+
+	wire io0_delayed;
+	wire io1_delayed;
+	wire io2_delayed;
+	wire io3_delayed;
+
+	assign #1 io0_delayed = io0;
+	assign #1 io1_delayed = io1;
+	assign #1 io2_delayed = io2;
+	assign #1 io3_delayed = io3;
+
+	// 128KB RAM
+	reg [7:0] memory [0:128*1024-1];
+
+	initial begin
+           if (!(mem_file_name == "none"))
+              $readmemh(mem_file_name,memory);
+	end
+
+	task spi_action;
+		begin
+		   spi_in = buffer;
+
+		   if (bytecount == 1) begin
+		   	spi_cmd = buffer;
+
+			if (spi_cmd == 8'h 3b) begin
+		   		spi_mode = dspi;
+			end
+
+			if (spi_cmd == 8'h 38) begin
+		   		spi_mode = qspi;
+			end
+
+			if (spi_cmd == 8'h ff) begin
+		   		spi_mode = sspi;
+			end
+
+			// spi read
+		   	if (spi_cmd == 8'h 03 && spi_mode == sspi)
+			   spi_phase = mode_sspi_rd;
+
+		        // spi write
+		   	if (spi_cmd == 8'h 02 && spi_mode == sspi)
+			   spi_phase = mode_sspi_wr;
+
+		        // dual spi read
+		   	if (spi_cmd == 8'h 03 && spi_mode == dspi)
+			   spi_phase = mode_dspi_rd;
+
+		        // dual spi write
+		   	if (spi_cmd == 8'h 02 && spi_mode == dspi)
+			   spi_phase = mode_dspi_wr;
+
+		        // quad spi read
+		   	if (spi_cmd == 8'h 03 && spi_mode == qspi)
+			   spi_phase = mode_qspi_rd;
+
+		        // quad spi write
+		   	if (spi_cmd == 8'h 02 && spi_mode == qspi)
+			   spi_phase = mode_qspi_wr;
+		   end
+
+		   if (spi_cmd == 'h 03 || (spi_cmd == 'h 02)) begin
+		   	if (bytecount == 2)
+		   		spi_addr[23:16] = buffer;
+
+		   	if (bytecount == 3)
+		   		spi_addr[15:8] = buffer;
+
+			if (bytecount == 4) begin
+		   	   spi_addr[7:0] = buffer;
+			   spi_data_phase = spi_phase;
+			end
+
+			// Dummy by selection at end of address phase for read
+			// mode only
+		   	if (bytecount == 4 && spi_mode == sspi && spi_cmd ==8'h03 )
+				dummycount = 8;
+		   	if (bytecount == 4 && spi_mode == dspi && spi_cmd ==8'h03)
+				dummycount = 4;
+		   	if (bytecount == 4 && spi_mode == qspi && spi_cmd ==8'h03)
+				dummycount = 2;
+
+		   	if (bytecount >= 4 && spi_cmd ==8'h03) begin // Data Read Phase
+		   		buffer = memory[spi_addr];
+				//$display("%m: Read Memory Address: %x Data: %x",spi_addr,buffer);
+		   		spi_addr = spi_addr + 1;
+		   	end
+		   	if (bytecount > 4 && spi_cmd ==8'h02) begin // Data Write Phase
+		   		memory[spi_addr] = buffer;
+				//$display("%m: Write Memory Address: %x Data: %x",spi_addr,buffer);
+		   		spi_addr = spi_addr + 1;
+		   	end
+		   end
+
+			spi_out = buffer;
+			spi_io_vld = 1;
+
+			if (verbose) begin
+				if (bytecount == 1)
+					$write("<SPI-START>");
+				$write("<SPI:%02x:%02x>", spi_in, spi_out);
+			end
+
+		end
+	endtask
+
+
+	always @(csb) begin
+		if (csb) begin
+			if (verbose) begin
+				$display("");
+				$fflush;
+			end
+			buffer = 0;
+			bitcount = 0;
+			bytecount = 0;
+			io0_oe = 0;
+			io1_oe = 0;
+			io2_oe = 0;
+			io3_oe = 0; 
+			spi_data_phase = 0;
+
+		end
+	end
+
+
+	always @(csb, clk) begin
+		spi_io_vld = 0;
+		if (!csb && !clk) begin
+			if (dummycount > 0) begin
+				io0_oe = 0;
+				io1_oe = 0;
+				io2_oe = 0;
+				io3_oe = 0;
+			end else
+			case (spi_data_phase)
+				mode_sspi_rd: begin
+					io0_oe = 0;
+					io1_oe = 1;
+					io2_oe = 0;
+					io3_oe = 0;
+					io1_dout = buffer[7];
+				end
+				mode_sspi_wr: begin
+					io0_oe = 0;
+					io1_oe = 0;
+					io2_oe = 0;
+					io3_oe = 0;
+				end
+				mode_dspi_wr: begin
+					io0_oe = 0;
+					io1_oe = 0;
+					io2_oe = 0;
+					io3_oe = 0;
+				end
+				mode_dspi_rd: begin
+					io0_oe = 1;
+					io1_oe = 1;
+					io2_oe = 0;
+					io3_oe = 0;
+					io0_dout = buffer[6];
+					io1_dout = buffer[7];
+				end
+				mode_qspi_wr: begin
+					io0_oe = 0;
+					io1_oe = 0;
+					io2_oe = 0;
+					io3_oe = 0;
+				end
+				mode_qspi_rd: begin
+					io0_oe = 1;
+					io1_oe = 1;
+					io2_oe = 1;
+					io3_oe = 1;
+					io0_dout = buffer[4];
+					io1_dout = buffer[5];
+					io2_dout = buffer[6];
+					io3_dout = buffer[7];
+				end
+				default: begin
+					io0_oe = 0;
+					io1_oe = 0;
+					io2_oe = 0;
+					io3_oe = 0;
+				end
+			endcase
+		end
+	end
+
+	always @(posedge clk) begin
+		if (!csb) begin
+			if (dummycount > 0) begin
+				dummycount = dummycount - 1;
+			end else
+			case (spi_mode)
+				sspi: begin
+					buffer = {buffer, io0};
+					bitcount = bitcount + 1;
+					if (bitcount == 8) begin
+						bitcount = 0;
+						bytecount = bytecount + 1;
+						spi_action;
+					end
+				end
+				dspi: begin
+					buffer = {buffer, io1, io0};
+					bitcount = bitcount + 2;
+					if (bitcount == 8) begin
+						bitcount = 0;
+						bytecount = bytecount + 1;
+						spi_action;
+					end
+				end
+				qspi: begin
+					buffer = {buffer, io3, io2, io1, io0};
+					bitcount = bitcount + 4;
+					if (bitcount == 8) begin
+						bitcount = 0;
+						bytecount = bytecount + 1;
+						spi_action;
+					end
+				end
+			endcase
+		end
+	end
+endmodule
diff --git a/verilog/dv/risc_boot/Makefile b/verilog/dv/risc_boot/Makefile
new file mode 100644
index 0000000..c8c838c
--- /dev/null
+++ b/verilog/dv/risc_boot/Makefile
@@ -0,0 +1,113 @@
+# 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
+
+## PDK 
+PDK_PATH = $(PDK_ROOT)/sky130A
+
+## 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_BEHAVIOURAL_AGENTS = ../agents
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/yifive/ycr1c/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include
+
+## YIFIVE FIRMWARE
+YIFIVE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/dv/firmware
+## RISCV GCC 
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+GCC64_PREFIX?=riscv64-unknown-elf
+
+## Simulation mode: RTL/GL
+SIM_DEFINES = -DFUNCTIONAL -DSIM
+SIM?=RTL
+DUMP?=OFF
+
+.SUFFIXES:
+
+PATTERN = risc_boot
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v %.hex
+	${GCC64_PREFIX}-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las  -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=0 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\"  -c -I./ -I$(YIFIVE_FIRMWARE_PATH)  user_uart.c -o user_uart.o
+	${GCC64_PREFIX}-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las  -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=0 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\"  -D__ASSEMBLY__=1 -c -I./ -I$(YIFIVE_FIRMWARE_PATH)  $(YIFIVE_FIRMWARE_PATH)/crt.S -o crt.o
+	${GCC64_PREFIX}-gcc -march=rv32imc -mabi=ilp32 -T $(YIFIVE_FIRMWARE_PATH)/link.ld user_uart.o crt.o -nostartfiles -nostdlib -lc -lgcc -o user_uart.elf -N
+	${GCC64_PREFIX}-objcopy -O verilog user_uart.elf user_uart.hex
+	${GCC64_PREFIX}-objdump -D user_uart.elf > user_uart.dump
+	rm crt.o user_uart.o
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2012 -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH)  \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+   else
+	iverilog -g2012 -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH)  \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+   endif
+else  
+	iverilog $(SIM_DEFINES) -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) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	$< -o $@ 
+endif
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c $(CARAVEL_FIRMWARE_PATH)/sections.lds $(CARAVEL_FIRMWARE_PATH)/start.s
+	${GCC64_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
+	${GCC64_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 *.dump
+
+.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..48e54f0
--- /dev/null
+++ b/verilog/dv/risc_boot/risc_boot.c
@@ -0,0 +1,190 @@
+/*
+ * 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_wbhost_reg0 (*(volatile uint32_t*)0x30800000)
+
+#define reg_mprj_globl_reg0  (*(volatile uint32_t*)0x30020000)
+#define reg_mprj_globl_reg1  (*(volatile uint32_t*)0x30020004)
+#define reg_mprj_globl_reg2  (*(volatile uint32_t*)0x30020008)
+#define reg_mprj_globl_reg3  (*(volatile uint32_t*)0x3002000C)
+#define reg_mprj_globl_reg4  (*(volatile uint32_t*)0x30020010)
+#define reg_mprj_globl_reg5  (*(volatile uint32_t*)0x30020014)
+#define reg_mprj_globl_reg6  (*(volatile uint32_t*)0x30020018)
+#define reg_mprj_globl_reg7  (*(volatile uint32_t*)0x3002001C)
+#define reg_mprj_globl_reg8  (*(volatile uint32_t*)0x30020020)
+#define reg_mprj_globl_reg9  (*(volatile uint32_t*)0x30020024)
+#define reg_mprj_globl_reg10 (*(volatile uint32_t*)0x30020028)
+#define reg_mprj_globl_reg11 (*(volatile uint32_t*)0x3002002C)
+#define reg_mprj_globl_reg12 (*(volatile uint32_t*)0x30020030)
+#define reg_mprj_globl_reg13 (*(volatile uint32_t*)0x30020034)
+#define reg_mprj_globl_reg14 (*(volatile uint32_t*)0x30020038)
+#define reg_mprj_globl_reg15 (*(volatile uint32_t*)0x3002003C)
+
+#define reg_mprj_uart_reg0 (*(volatile uint32_t*)0x30010000)
+#define reg_mprj_uart_reg1 (*(volatile uint32_t*)0x30010004)
+#define reg_mprj_uart_reg2 (*(volatile uint32_t*)0x30010008)
+#define reg_mprj_uart_reg3 (*(volatile uint32_t*)0x3001000C)
+#define reg_mprj_uart_reg4 (*(volatile uint32_t*)0x30010010)
+#define reg_mprj_uart_reg5 (*(volatile uint32_t*)0x30010014)
+#define reg_mprj_uart_reg6 (*(volatile uint32_t*)0x30010018)
+#define reg_mprj_uart_reg7 (*(volatile uint32_t*)0x3001001C)
+#define reg_mprj_uart_reg8 (*(volatile uint32_t*)0x30010020)
+
+#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);
+
+    reg_la0_data = 0x000;
+    reg_la0_data = 0x001; // Remove Soft Reset
+
+
+    // Remove Wishbone Reset
+    reg_mprj_wbhost_reg0 = 0x1;
+
+
+    // Remove All Reset
+    reg_mprj_wbhost_reg0 = 0x1F;
+
+    // Enable UART Multi Functional Ports
+
+    reg_mprj_globl_reg14 = 0x100;
+
+    // configure the user uart
+    reg_mprj_uart_reg0  = 0x7;
+
+}
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..bc4db63
--- /dev/null
+++ b/verilog/dv/risc_boot/risc_boot_tb.v
@@ -0,0 +1,389 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  User Risc Core Boot Validation                              ////
+////                                                              ////
+////  This file is part of the YIFive cores project               ////
+////  https://github.com/dineshannayya/yifive_r0.git              ////
+////  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 "s25fl256s.sv"
+`include "uprj_netlists.v"
+`include "caravel_netlists.v"
+`include "spiflash.v"
+`include "mt48lc8m8a2.v"
+`include "uart_agent.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;
+
+        //----------------------------------
+        // Uart Configuration
+        // ---------------------------------
+        reg [1:0]      uart_data_bit        ;
+        reg	       uart_stop_bits       ; // 0: 1 stop bit; 1: 2 stop bit;
+        reg	       uart_stick_parity    ; // 1: force even parity
+        reg	       uart_parity_en       ; // parity enable
+        reg	       uart_even_odd_parity ; // 0: odd parity; 1: even parity
+        
+        reg [7:0]      uart_data            ;
+        reg [15:0]     uart_divisor         ;	// divided by n * 16
+        reg [15:0]     uart_timeout         ;// wait time limit
+        
+        reg [15:0]     uart_rx_nu           ;
+        reg [15:0]     uart_tx_nu           ;
+        reg [7:0]      uart_write_data [0:39];
+        reg 	       uart_fifo_enable     ;	// fifo mode disable
+	reg            test_fail            ;
+        
+        integer i,j;
+	//---------------------------------
+	
+	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(1,risc_boot_tb.u_spi_flash_256mb);
+           //$dumpvars(2,risc_boot_tb.uut);
+           $dumpvars(4,risc_boot_tb.uut.mprj);
+           $dumpvars(0,risc_boot_tb.tb_uart);
+           //$dumpvars(0,risc_boot_tb.u_user_spiflash);
+	   $display("Waveform Dump started");
+        end
+        `endif
+
+
+        initial
+        begin
+           uart_data_bit           = 2'b11;
+           uart_stop_bits          = 0; // 0: 1 stop bit; 1: 2 stop bit;
+           uart_stick_parity       = 0; // 1: force even parity
+           uart_parity_en          = 0; // parity enable
+           uart_even_odd_parity    = 1; // 0: odd parity; 1: even parity
+           uart_divisor            = 15;// divided by n * 16
+           uart_timeout            = 500;// wait time limit
+           uart_fifo_enable        = 0;	// fifo mode disable
+        
+           #200; // Wait for reset removal
+
+           fork
+	   begin
+          
+	      // Wait for Managment core to boot up 
+	      wait(checkbits == 16'h AB60);
+	      $display("Monitor: Test User Risc Boot Started");
+       
+	      // Wait for user risc core to boot up 
+              repeat (30000) @(posedge clock);  
+              tb_uart.uart_init;
+              tb_uart.control_setup (uart_data_bit, uart_stop_bits, uart_parity_en, uart_even_odd_parity, 
+                                             uart_stick_parity, uart_timeout, uart_divisor);
+              
+              for (i=0; i<40; i=i+1)
+              	uart_write_data[i] = $random;
+              
+              
+              
+              fork
+                 begin
+                    for (i=0; i<40; i=i+1)
+                    begin
+                      $display ("\n... UART Agent Writing char %x ...", uart_write_data[i]);
+                       tb_uart.write_char (uart_write_data[i]);
+                    end
+                 end
+              
+                 begin
+                    for (j=0; j<40; j=j+1)
+                    begin
+                      tb_uart.read_char_chk(uart_write_data[j]);
+                    end
+                 end
+                 join
+              
+                 #100
+                 tb_uart.report_status(uart_rx_nu, uart_tx_nu);
+              
+                 test_fail = 0;
+        
+                 // Check 
+                 // if all the 40 byte transmitted
+                 // if all the 40 byte received
+                 // if no error 
+                 if(uart_tx_nu != 40) test_fail = 1;
+                 if(uart_rx_nu != 40) test_fail = 1;
+                 if(tb_uart.err_cnt != 0) test_fail = 1;
+        
+	      end
+	      begin
+                   // Loop for TimeOut
+                   repeat (60000) @(posedge clock);
+                		// $display("+1000 cycles");
+                   test_fail = 1;
+              end
+              join_any
+              disable fork; //disable pending fork activity
+
+              $display("###################################################");
+              if(test_fail == 0) begin
+                 `ifdef GL
+                     $display("Monitor: Standalone User UART Test (GL) Passed");
+                 `else
+                     $display("Monitor: Standalone User UART Test (RTL) Passed");
+                 `endif
+              end else begin
+                  `ifdef GL
+                      $display("Monitor: Standalone User UART Test (GL) Failed");
+                  `else
+                      $display("Monitor: Standalone User UART Test (RTL) Failed");
+                  `endif
+               end
+              $display("###################################################");
+              #100
+              $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[24];
+   wire user_flash_csb = mprj_io[28];
+   //tri  user_flash_io0 = mprj_io[26];
+   //tri  user_flash_io1 = mprj_io[27];
+   //tri  user_flash_io2 = mprj_io[28];
+   //tri  user_flash_io3 = mprj_io[29];
+
+
+   // Quard flash
+     s25fl256s #(.mem_file_name("user_uart.hex"),
+	         .otp_file_name("none"), 
+                 .TimingModel("S25FL512SAGMFI010_F_30pF")) 
+		 u_spi_flash_256mb (
+           // Data Inputs/Outputs
+       .SI      (mprj_io[29]),
+       .SO      (mprj_io[30]),
+       // Controls
+       .SCK     (user_flash_clk),
+       .CSNeg   (user_flash_csb),
+       .WPNeg   (mprj_io[31]),
+       .HOLDNeg (mprj_io[32]),
+       .RSTNeg  (RSTB)
+
+       );
+
+//---------------------------
+//  UART Agent integration
+// --------------------------
+wire uart_txd,uart_rxd;
+
+assign uart_txd   = mprj_io[2];
+assign mprj_io[1]  = uart_rxd ;
+ 
+uart_agent tb_uart(
+	.mclk                (clock              ),
+	.txd                 (uart_rxd           ),
+	.rxd                 (uart_txd           )
+	);
+
+
+`ifndef GL // Drive Power for Hold Fix Buf
+    // All standard cell need power hook-up for functionality work
+initial begin
+end
+`endif    
+
+
+/**
+//-----------------------------------------------------------------------------
+// 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..e2f2a4d
--- /dev/null
+++ b/verilog/dv/risc_boot/run_iverilog
@@ -0,0 +1,26 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# // 
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# //      http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+#add -DWFDUMP to enable waveform dump
+iverilog -DWFDUMP -g2005-sv -DFUNCTIONAL -DSIM -I $PDK_PATH \
+-I $CARAVEL_ROOT/verilog/dv/caravel -I $CARAVEL_ROOT/verilog/rtl \
+-I ../model  -I ../agents  -I ../../../verilog/rtl -I ../../../verilog \
+-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_uart.c b/verilog/dv/risc_boot/user_uart.c
new file mode 100644
index 0000000..29805f7
--- /dev/null
+++ b/verilog/dv/risc_boot/user_uart.c
@@ -0,0 +1,59 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+// //////////////////////////////////////////////////////////////////////////
+#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)
+
+#define reg_mprj_uart_reg0 (*(volatile uint32_t*)0x10010000)
+#define reg_mprj_uart_reg1 (*(volatile uint32_t*)0x10010004)
+#define reg_mprj_uart_reg2 (*(volatile uint32_t*)0x10010008)
+#define reg_mprj_uart_reg3 (*(volatile uint32_t*)0x1001000C)
+#define reg_mprj_uart_reg4 (*(volatile uint32_t*)0x10010010)
+#define reg_mprj_uart_reg5 (*(volatile uint32_t*)0x10010014)
+#define reg_mprj_uart_reg6 (*(volatile uint32_t*)0x10010018)
+#define reg_mprj_uart_reg7 (*(volatile uint32_t*)0x1001001C)
+#define reg_mprj_uart_reg8 (*(volatile uint32_t*)0x10010020)
+
+int main()
+{
+
+    while(1) {
+       // Check UART RX fifo has data, if available loop back the data
+       if(reg_mprj_uart_reg8 != 0) { 
+	   reg_mprj_uart_reg5 = reg_mprj_uart_reg6;
+       }
+    }
+
+    return 0;
+}
diff --git a/verilog/dv/riscv_regress/Makefile b/verilog/dv/riscv_regress/Makefile
new file mode 100644
index 0000000..0461ba3
--- /dev/null
+++ b/verilog/dv/riscv_regress/Makefile
@@ -0,0 +1,377 @@
+#------------------------------------------------------------------------------
+# Makefile for SCR1
+#------------------------------------------------------------------------------
+
+SIM ?= RTL
+DUMP ?= OFF
+
+# PARAMETERS
+
+# CFG = <MAX, BASE, MIN, CUSTOM>
+# BUS = <AHB, AXI, WB>
+
+export CFG      ?= MAX
+export BUS      ?= WB
+
+ifeq ($(CFG), MAX)
+# Predefined configuration YCR1_CFG_RV32IMC_MAX
+    override ARCH         := IMC
+    override VECT_IRQ     := 1
+    override IPIC         := 1
+    override TCM          := 0
+    override SIM_CFG_DEF  := YCR1_CFG_RV32IMC_MAX
+else
+    ifeq ($(CFG), BASE)
+    # Predefined configuration YCR1_CFG_RV32IC_BASE
+        override ARCH         := IC
+        override VECT_IRQ     := 1
+        override IPIC         := 1
+        override TCM          := 0
+        override SIM_CFG_DEF  := YCR1_CFG_RV32IC_BASE
+    else
+        ifeq ($(CFG), MIN)
+        # Predefined configuration SCR1_CFG_RV32EC_MIN
+            override ARCH         := EC
+            override VECT_IRQ     := 0
+            override IPIC         := 0
+            override TCM          := 0
+            override SIM_CFG_DEF  := YCR1_CFG_RV32EC_MIN
+        else
+        # CUSTOM configuration. Parameters can be overwritten
+            # These options are for compiling tests only. Set the corresponding RTL parameters manually in the file ycr1_arch_description.svh.
+            # ARCH = <IMC, IC, IM, I, EMC, EM, EC, E>
+            # VECT_IRQ = <0, 1>
+            # IPIC = <0, 1>
+            # TCM = <0, 1>
+            ARCH      ?= IMC
+            VECT_IRQ  ?= 0
+            IPIC      ?= 0
+            TCM       ?= 0
+            SIM_CFG_DEF  = YCR1_CFG_$(CFG)
+        endif
+    endif
+endif
+
+# export all overrided variables
+export ARCH
+export VECT_IRQ
+export IPIC
+export TCM
+export SIM_CFG_DEF
+
+ARCH_lowercase = $(shell echo $(ARCH) | tr A-Z a-z)
+BUS_lowercase  = $(shell echo $(BUS)  | tr A-Z a-z)
+
+ifeq ($(ARCH_lowercase),)
+    ARCH_tmp = imc
+else
+    ifneq (,$(findstring e,$(ARCH_lowercase)))
+        ARCH_tmp   += e
+        EXT_CFLAGS += -D__RVE_EXT
+    else
+        ARCH_tmp   += i
+    endif
+    ifneq (,$(findstring m,$(ARCH_lowercase)))
+        ARCH_tmp   := $(ARCH_tmp)m
+    endif
+    ifneq (,$(findstring c,$(ARCH_lowercase)))
+        ARCH_tmp   := $(ARCH_tmp)c
+        EXT_CFLAGS += -D__RVC_EXT
+    endif
+endif
+
+override ARCH=$(ARCH_tmp)
+
+# Use this parameter to enable tracelog
+TRACE ?= 0
+
+ifeq ($(TRACE), 1)
+    export SIM_TRACE_DEF = YCR1_TRACE_LOG_EN
+else
+    export SIM_TRACE_DEF = YCR1_TRACE_LOG_DIS
+endif
+
+
+# Use this parameter to pass additional options for simulation build command
+SIM_BUILD_OPTS ?=
+
+# Use this parameter to set the list of tests to run
+# TARGETS = <riscv_isa, riscv_compliance, coremark, dhrystone21, hello, isr_sample>
+export TARGETS :=
+
+
+export ABI   ?= ilp32
+# Testbench memory delay patterns\
+  (FFFFFFFF - no delay, 00000000 - random delay, 00000001 - max delay)
+imem_pattern ?= FFFFFFFF
+dmem_pattern ?= FFFFFFFF
+
+VCS_OPTS       ?=
+MODELSIM_OPTS  ?=
+NCSIM_OPTS     ?=
+VERILATOR_OPTS ?=
+
+current_goal := $(MAKECMDGOALS:run_%=%)
+ifeq ($(current_goal),)
+    current_goal := iverilog
+endif
+
+
+export root_dir := $(shell pwd)
+export bld_dir  := $(root_dir)/build/$(current_goal)_$(BUS)_$(CFG)_$(ARCH)_IPIC_$(IPIC)_TCM_$(TCM)_VIRQ_$(VECT_IRQ)_TRACE_$(TRACE)
+
+## Caravel Pointers related to build directory
+CARAVEL_ROOT ?= $(root_dir)/../../../caravel
+CARAVEL_PATH ?= $(CARAVEL_ROOT)
+CARAVEL_FIRMWARE_PATH = $(CARAVEL_PATH)/verilog/dv/caravel
+CARAVEL_VERILOG_PATH  = $(CARAVEL_PATH)/verilog
+CARAVEL_RTL_PATH = $(CARAVEL_VERILOG_PATH)/rtl
+CARAVEL_BEHAVIOURAL_MODELS = $(CARAVEL_VERILOG_PATH)/dv/caravel
+
+
+## User Project Pointers
+UPRJ_VERILOG_PATH ?= $(root_dir)/../../../verilog
+UPRJ_TESTS_PATH = $(root_dir)
+UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl
+UPRJ_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = $(root_dir)/../model
+UPRJ_BEHAVIOURAL_AGENTS = $(root_dir)/../agents
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/yifive/ycr1c/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include
+
+sv_list            = ../../user_risc_regress_tb.v
+top_module         = user_risc_regress_tb
+
+# TB Paths
+export sim_dir  := $(UPRJ_TESTS_PATH)
+export tst_dir  := $(sim_dir)/tests
+export inc_dir  := $(UPRJ_VERILOG_PATH)/dv/firmware
+
+test_results := $(bld_dir)/test_results.txt
+test_info    := $(bld_dir)/test_info
+sim_results  := $(bld_dir)/sim_results.txt
+
+todo_list    := $(bld_dir)/todo.txt
+
+# Environment
+export CROSS_PREFIX  ?= riscv64-unknown-elf-
+export RISCV_GCC     ?= $(CROSS_PREFIX)gcc
+export RISCV_OBJDUMP ?= $(CROSS_PREFIX)objdump -D
+export RISCV_OBJCOPY ?= $(CROSS_PREFIX)objcopy -O verilog
+export RISCV_ROM_OBJCOPY ?= $(CROSS_PREFIX)objcopy -j .text.init -j .text -j .rodata -j .rodata.str1.4 -O verilog
+#Seperate the RAM content and write out in 32bit Little endian format to load it to TCM Memory
+#export RISCV_RAM_OBJCOPY ?= $(CROSS_PREFIX)objcopy -R .text.init -R .text -R .rodata -R .rodata.str1.4 -R .riscv.attributes -R .comment -R .debug_abbrev -R .debug_loc -R .debug_str -O verilog --verilog-data-width=4 --reverse-bytes=4
+export RISCV_RAM_OBJCOPY ?= $(CROSS_PREFIX)objcopy -R .text.init -R .text -R .rodata -R .rodata.str1.4 -O verilog
+export RISCV_READELF ?= $(CROSS_PREFIX)readelf -s
+
+ifneq (,$(findstring e,$(ARCH_lowercase)))
+# Tests can be compiled for RVE only if gcc version 8.0.0 or higher
+    GCCVERSIONGT7 := $(shell expr `$(RISCV_GCC) -dumpfullversion | cut -f1 -d'.'` \> 7)
+    ifeq "$(GCCVERSIONGT7)" "1"
+        ABI := ilp32e
+    endif
+endif
+
+#--
+ifeq (,$(findstring e,$(ARCH_lowercase)))
+	# These tests cannot be compiled for RVE
+	# Comment this target if you don't want to run the riscv_isa
+	TARGETS += riscv_isa
+
+	# Comment this target if you don't want to run the riscv_compliance
+	TARGETS += riscv_compliance
+endif
+
+# Comment this target if you don't want to run the isr_sample
+TARGETS += isr_sample
+
+# Comment this target if you don't want to run the coremark
+TARGETS += coremark
+
+# Comment this target if you don't want to run the dhrystone
+TARGETS += dhrystone21
+
+# Comment this target if you don't want to run the hello test
+TARGETS += hello
+
+
+# Targets
+.PHONY: tests run_iverilog run_iverilog_wf run_modelsim run_modelsim_wlf run_vcs run_ncsim run_verilator run_verilator_wf
+
+default: clean_test_list run_iverilog
+
+clean_test_list:
+	rm -f $(test_info)
+
+echo_out: tests
+	@echo "                          Test               | build | simulation " ;
+	@echo "$$(cat $(test_results))"
+
+tests: $(TARGETS)
+
+$(test_info): clean_hex tests
+	cd $(bld_dir)
+
+isr_sample: | $(bld_dir)
+	$(MAKE) -C $(tst_dir)/isr_sample ARCH=$(ARCH) IPIC=$(IPIC) VECT_IRQ=$(VECT_IRQ)
+
+dhrystone21: | $(bld_dir)
+	$(MAKE) -C $(tst_dir)/benchmarks/dhrystone21 EXT_CFLAGS="$(EXT_CFLAGS)" ARCH=$(ARCH)
+
+coremark: | $(bld_dir)
+	@echo "core marks"
+	$(MAKE) -C $(tst_dir)/benchmarks/coremark EXT_CFLAGS="$(EXT_CFLAGS)" ARCH=$(ARCH)
+
+riscv_isa: | $(bld_dir)
+	$(MAKE) -C $(tst_dir)/riscv_isa ARCH=$(ARCH)
+
+riscv_compliance: | $(bld_dir)
+	$(MAKE) -C $(tst_dir)/riscv_compliance ARCH=$(ARCH)
+
+hello: | $(bld_dir)
+	-$(MAKE) -C $(tst_dir)/hello EXT_CFLAGS="$(EXT_CFLAGS)" ARCH=$(ARCH)
+
+test: | $(bld_dir)
+	-$(MAKE) -C $(tst_dir)/test EXT_CFLAGS="$(EXT_CFLAGS)" ARCH=$(ARCH)
+
+clean_hex: | $(bld_dir)
+	$(RM) $(bld_dir)/*.hex
+
+$(bld_dir):
+	mkdir -p $(bld_dir)
+
+run_vcs: $(test_info)
+	$(MAKE) -C $(root_dir)/sim build_vcs SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS);
+	printf "" > $(test_results);
+	cd $(bld_dir); \
+	$(bld_dir)/simv  -V \
+	+test_info=$(test_info) \
+	+test_results=$(test_results) \
+	+imem_pattern=$(imem_pattern) \
+	+dmem_pattern=$(dmem_pattern) \
+	$(VCS_OPTS) | tee $(sim_results)  ;\
+	printf "                          Test               | build | simulation \n" ; \
+	printf "$$(cat $(test_results)) \n"
+run_modelsim: $(test_info)
+	$(MAKE) -C $(root_dir)/sim build_modelsim SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS); \
+	printf "" > $(test_results); \
+	cd $(bld_dir); \
+	vsim -c -do "run -all" +nowarn3691 \
+	+test_info=$(test_info) \
+	+test_results=$(test_results) \
+	+imem_pattern=$(imem_pattern) \
+	+dmem_pattern=$(dmem_pattern) \
+	work.$(top_module) \
+	$(MODELSIM_OPTS) | tee $(sim_results)  ;\
+	printf "Simulation performed on $$(vsim -version) \n" ;\
+	printf "                          Test               | build | simulation \n" ; \
+	printf "$$(cat $(test_results)) \n"
+
+run_iverilog: $(test_info)
+	cd $(bld_dir); \
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) -I $(UPRJ_TESTS_PATH) \
+	$(sv_list) \
+	-o $(top_module).vvp; \
+	printf "" > $(test_results); \
+        iverilog-vpi ../../../vpi/system/system.c; \
+	vvp  -M. -msystem  $(top_module).vvp \
+	+test_info=$(test_info) \
+	+test_results=$(test_results) \
+	| tee $(sim_results)  ;\
+	printf "Simulation performed on $$(vvp -V) \n" ;\
+	printf "                          Test               | build | simulation \n" ; \
+	printf "$$(cat $(test_results)) \n"
+
+run_iverilog_wf: $(test_info)
+	cd $(bld_dir); \
+	iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) -I $(UPRJ_TESTS_PATH) \
+	$(sv_list) \
+	-o $(top_module).vvp; \
+	printf "" > $(test_results); \
+        iverilog-vpi ../../../vpi/system/system.c; \
+	vvp  -M. -msystem  $(top_module).vvp \
+	+test_info=$(test_info) \
+	+test_results=$(test_results) \
+	| tee $(sim_results)  ;\
+	printf "Simulation performed on $$(vvp -V) \n" ;\
+	printf "                          Test               | build | simulation \n" ; \
+	printf "$$(cat $(test_results)) \n"
+
+run_modelsim_wlf: $(test_info)
+	$(MAKE) -C $(root_dir)/sim build_modelsim_wlf SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS); \
+	printf "" > $(test_results); \
+	cd $(bld_dir); \
+	vsim -c -do "run -all" +nowarn3691 \
+	+test_info=$(test_info) \
+	+test_results=$(test_results) \
+	+imem_pattern=$(imem_pattern) \
+	+dmem_pattern=$(dmem_pattern) \
+	work.$(top_module) \
+	$(MODELSIM_OPTS) | tee $(sim_results)  ;\
+	printf "Simulation performed on $$(vsim -version) \n" ;\
+	printf "                          Test               | build | simulation \n" ; \
+	printf "$$(cat $(test_results)) \n"
+run_ncsim: $(test_info)
+	$(MAKE) -C $(root_dir)/sim build_ncsim SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS);
+	printf "" > $(test_results);
+	cd $(bld_dir); \
+	irun \
+	-R \
+	-64bit \
+	+test_info=$(test_info) \
+	+test_results=$(test_results) \
+	+imem_pattern=$(imem_pattern) \
+	+dmem_pattern=$(dmem_pattern) \
+	$(NCSIM_OPTS) | tee $(sim_results)  ;\
+	printf "Simulation performed on $$(irun -version) \n" ;\
+	printf "                          Test               | build | simulation \n" ; \
+	printf "$$(cat $(test_results)) \n"
+
+run_verilator: $(test_info)
+	$(MAKE) -C $(root_dir)/sim build_verilator SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS);
+	printf "" > $(test_results);
+	cd $(bld_dir); \
+	echo $(top_module) | tee $(sim_results); \
+	$(bld_dir)/verilator/V$(top_module) \
+	+test_info=$(test_info) \
+	+test_results=$(test_results) \
+	+imem_pattern=$(imem_pattern) \
+	+dmem_pattern=$(dmem_pattern) \
+	$(VERILATOR_OPTS) | tee -a $(sim_results) ;\
+	printf "Simulation performed on $$(verilator -version) \n" ;\
+	printf "                          Test               | build | simulation \n" ; \
+	printf "$$(cat $(test_results)) \n"
+
+run_verilator_wf: $(test_info)
+	$(MAKE) -C $(root_dir)/sim build_verilator_wf SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS);
+	printf "" > $(test_results);
+	cd $(bld_dir); \
+	echo $(top_module) | tee $(sim_results); \
+	$(bld_dir)/verilator/V$(top_module) \
+	+test_info=$(test_info) \
+	+test_results=$(test_results) \
+	+imem_pattern=$(imem_pattern) \
+	+dmem_pattern=$(dmem_pattern) \
+	$(VERILATOR_OPTS) | tee -a $(sim_results)  ;\
+	printf "Simulation performed on $$(verilator -version) \n" ;\
+	printf "                          Test               | build | simulation \n" ; \
+	printf "$$(cat $(test_results)) \n"
+clean: 
+	$(MAKE) -C $(tst_dir)/benchmarks/dhrystone21 clean
+	$(MAKE) -C $(tst_dir)/riscv_isa clean
+	$(MAKE) -C $(tst_dir)/riscv_compliance clean
+	$(RM) -R $(root_dir)/build/*
+	$(RM) $(test_info)
diff --git a/verilog/dv/riscv_regress/riscv_runtests.sv b/verilog/dv/riscv_regress/riscv_runtests.sv
new file mode 100644
index 0000000..25c14a5
--- /dev/null
+++ b/verilog/dv/riscv_regress/riscv_runtests.sv
@@ -0,0 +1,384 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_top_tb_runtests.sv>
+/// @brief      SCR1 testbench run tests
+///
+
+//-------------------------------------------------------------------------------
+// Run tests
+//-------------------------------------------------------------------------------
+
+initial begin
+    //$value$plusargs("imem_pattern=%h", imem_req_ack_stall);
+    //$value$plusargs("dmem_pattern=%h", dmem_req_ack_stall);
+
+    //$display("imem_pattern:%x",imem_req_ack_stall);
+    //$display("dmem_pattern:%x",dmem_req_ack_stall);
+`ifdef SIGNATURE_OUT
+    $value$plusargs("test_name=%s", s_testname);
+    b_single_run_flag = 1;
+`else // SIGNATURE_OUT
+
+    $value$plusargs("test_info=%s", s_info);
+    $value$plusargs("test_results=%s", s_results);
+
+    f_info      = $fopen(s_info, "r");
+    f_results   = $fopen(s_results, "a");
+`endif // SIGNATURE_OUT
+
+
+
+end
+/***
+// Debug message - dinesh A
+ logic [`SCR1_DMEM_AWIDTH-1:0]           core2imem_addr_o_r;           // DMEM address
+ logic [`SCR1_DMEM_AWIDTH-1:0]           core2dmem_addr_o_r;           // DMEM address
+ logic                                   core2dmem_cmd_o_r;
+ 
+ `define RISC_CORE  i_top.i_core_top
+ 
+ always@(posedge `RISC_CORE.clk) begin
+     if(`RISC_CORE.imem2core_req_ack_i && `RISC_CORE.core2imem_req_o)
+           core2imem_addr_o_r <= `RISC_CORE.core2imem_addr_o;
+ 
+     if(`RISC_CORE.dmem2core_req_ack_i && `RISC_CORE.core2dmem_req_o) begin
+           core2dmem_addr_o_r <= `RISC_CORE.core2dmem_addr_o;
+           core2dmem_cmd_o_r  <= `RISC_CORE.core2dmem_cmd_o;
+     end
+ 
+     if(`RISC_CORE.imem2core_resp_i !=0)
+           $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x Resonse: %x", core2imem_addr_o_r,`RISC_CORE.imem2core_rdata_i,`RISC_CORE.imem2core_resp_i);
+     if((`RISC_CORE.dmem2core_resp_i !=0) && core2dmem_cmd_o_r)
+           $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", core2dmem_addr_o_r,`RISC_CORE.core2dmem_wdata_o,`RISC_CORE.dmem2core_resp_i);
+     if((`RISC_CORE.dmem2core_resp_i !=0) && !core2dmem_cmd_o_r)
+           $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", core2dmem_addr_o_r,`RISC_CORE.dmem2core_rdata_i,`RISC_CORE.dmem2core_resp_i);
+ end
+**/
+/***
+  logic [31:0] test_count;
+ `define RISC_CORE  u_top.u_riscv_top.i_core_top
+ `define RISC_EXU  u_top.u_riscv_top.i_core_top.i_pipe_top.i_pipe_exu
+
+ initial begin
+	 test_count = 0;
+ end
+
+ 
+ always@(posedge `RISC_CORE.clk) begin
+	 if(`RISC_EXU.pc_curr_upd) begin
+            $display("RISCV-DEBUG => Cnt: %x PC: %x", test_count,`RISC_EXU.pc_curr_ff);
+               test_count <= test_count+1;
+	  end
+ end
+***/
+
+always @(posedge clk) begin
+    bit test_pass;
+    int unsigned                            f_test;
+    int unsigned                            f_test_ram;
+    if (test_running) begin
+        test_pass = 1;
+        rst_init <= 1'b0;
+	if(u_top.u_riscv_top.i_core_top.i_pipe_top.i_pipe_exu.pc_curr_ff === 32'hxxxx_xxxx) begin
+	   $display("ERROR: CURRENT PC Counter State is Known");
+	   $finish;
+	end
+        if ((u_top.u_riscv_top.i_core_top.i_pipe_top.i_pipe_exu.exu2pipe_pc_curr_o == YCR1_SIM_EXIT_ADDR) & ~rst_init & &rst_cnt) begin
+
+            `ifdef VERILATOR
+                logic [255:0] full_filename;
+                full_filename = test_file;
+            `else // VERILATOR
+                string full_filename;
+                full_filename = test_file;
+            `endif // VERILATOR
+
+            if (is_compliance(test_file)) begin
+                logic [31:0] tmpv, start, stop, ref_data, test_data;
+                integer fd;
+                `ifdef VERILATOR
+                logic [2047:0] tmpstr;
+                `else // VERILATOR
+                string tmpstr;
+                `endif // VERILATOR
+
+	        // Flush the content of dcache for signature validation at app
+	        // memory	
+	        force u_top.u_riscv_top.u_intf.u_dcache.cfg_force_flush = 1'b1;
+	        wait(u_top.u_riscv_top.u_intf.u_dcache.force_flush_done == 1'b1);
+	        release u_top.u_riscv_top.u_intf.u_dcache.cfg_force_flush;
+	        repeat (2000) @(posedge clock); // wait data to flush in pipe
+		$display("STATUS: Checking Complaince Test Status .... ");
+                test_running <= 1'b0;
+                test_pass = 1;
+
+                $sformat(tmpstr, "riscv64-unknown-elf-readelf -s %s | grep 'begin_signature\\|end_signature' | awk '{print $2}' > elfinfo", get_filename(test_file));
+                fd = $fopen("script.sh", "w");
+                if (fd == 0) begin
+                    $write("Can't open script.sh\n");
+                    $display("ERRIR:Can't open script.sh\n");
+                    test_pass = 0;
+                end
+                $fwrite(fd, "%s", tmpstr);
+                $fclose(fd);
+
+                $system("sh script.sh");
+
+                fd = $fopen("elfinfo", "r");
+                if (fd == 0) begin
+                    $write("Can't open elfinfo\n");
+                    $display("ERROR: Can't open elfinfo\n");
+                    test_pass = 0;
+                end
+                if ($fscanf(fd,"%h\n%h", start, stop) != 2) begin
+                    $write("Wrong elfinfo data\n");
+                    $display("ERROR:Wrong elfinfo data: start: %x stop: %x\n",start,stop);
+                    test_pass = 0;
+                end
+                if (start > stop) begin
+                    tmpv = start;
+                    start = stop;
+                    stop = tmpv;
+                end
+                $fclose(fd);
+		start = start & 32'h07FF_FFFF;
+	        stop  = stop & 32'h07FF_FFFF;
+		$display("Complaince Signature Start Address: %x End Address:%x",start,stop);
+
+		//if((start & 32'h1FFF) > 512)
+		//	$display("ERROR: Start address is more than 512, Start: %x",start & 32'h1FFF);
+		//if((stop & 32'h1FFF) > 512)
+		//	$display("ERROR: Stop address is more than 512, Start: %x",stop & 32'h1FFF);
+
+                `ifdef SIGNATURE_OUT
+
+                    $sformat(tmpstr, "%s.signature.output", s_testname);
+`ifdef VERILATOR
+                    tmpstr = remove_trailing_whitespaces(tmpstr);
+`endif
+                    fd = $fopen(tmpstr, "w");
+                    while ((start != stop)) begin
+                        //test_data = u_top.u_sram0_2kb.mem[(start & 32'h1FFF)];
+                        test_data = {u_sram.memory[start+3], u_sram.memory[start+2], u_sram.memory[start+1], u_sram.memory[start]};
+                        $fwrite(fd, "%x", test_data);
+                        $fwrite(fd, "%s", "\n");
+                        start += 4;
+                    end
+                    $fclose(fd);
+                `else //SIGNATURE_OUT
+                    $sformat(tmpstr, "riscv_compliance/ref_data/%s", get_ref_filename(test_file));
+`ifdef VERILATOR
+                tmpstr = remove_trailing_whitespaces(tmpstr);
+`endif
+                    fd = $fopen(tmpstr,"r");
+                    if (fd == 0) begin
+                        $write("Can't open reference_data file: %s\n", tmpstr);
+                        $display("ERROR: Can't open reference_data file: %s\n", tmpstr);
+                        test_pass = 0;
+                    end
+                    while (!$feof(fd) && (start != stop)) begin
+                        $fscanf(fd, "0x%h,\n", ref_data);
+			//----------------------------------------------------
+			// Assumed all signaure are with-in first 512 location of memory, 
+			// other-wise need to switch bank
+			// --------------------------------------------------
+		        //$writememh("sram0_out.hex",u_top.u_tsram0_2kb.mem,0,511);
+                        //test_data = u_top.u_sram0_2kb.mem[((start >> 2) & 32'h1FFF)];
+                        test_data = {u_sram.memory[start+3], u_sram.memory[start+2], u_sram.memory[start+1], u_sram.memory[start]};
+			//$display("Compare Addr: %x ref_data : %x, test_data: %x",start,ref_data,test_data);
+                        test_pass &= (ref_data == test_data);
+			if(ref_data != test_data)
+			   $display("ERROR: Compare Addr: %x Mem Addr: %x ref_data : %x, test_data: %x",start,start & 32'h1FFF,ref_data,test_data);
+			else
+			   $display("STATUS: Compare Addr: %x Mem Addr: %x ref_data : %x",start,start & 32'h1FFF,ref_data);
+                        start += 4;
+                    end
+                    $fclose(fd);
+                    tests_total += 1;
+                    tests_passed += test_pass;
+                    if (test_pass) begin
+                        $write("\033[0;32mTest passed\033[0m\n");
+                    end else begin
+                        $write("\033[0;31mTest failed-2\033[0m\n");
+                    end
+                `endif  // SIGNATURE_OUT
+            end else begin // Non compliance mode
+                test_running <= 1'b0;
+		if(u_top.u_riscv_top.i_core_top.i_pipe_top.i_pipe_mprf.mprf_int[10] != 0)
+		   $display("ERROR: mprf_int[10]: %x not zero",u_top.u_riscv_top.i_core_top.i_pipe_top.i_pipe_mprf.mprf_int[10]);
+
+                test_pass = (u_top.u_riscv_top.i_core_top.i_pipe_top.i_pipe_mprf.mprf_int[10] == 0);
+                tests_total     += 1;
+                tests_passed    += test_pass;
+                `ifndef SIGNATURE_OUT
+                    if (test_pass) begin
+                        $write("\033[0;32mTest passed\033[0m\n");
+                    end else begin
+                        $write("\033[0;31mTest failed\033[0m\n");
+                    end
+                `endif //SIGNATURE_OUT
+            end
+            $fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "OK" , (test_pass ? "PASS" : "__FAIL"));
+        end
+    end else begin
+`ifdef VERILATOR
+    `ifdef SIGNATURE_OUT
+        if ((s_testname.len() != 0) && (b_single_run_flag)) begin
+            $sformat(test_file, "%s.bin", s_testname);
+    `else //SIGNATURE_OUT
+        if ($fgets(test_file,f_info)) begin
+            test_file = test_file >> 8; // < Removing trailing LF symbol ('\n')
+    `endif //SIGNATURE_OUT
+`else // VERILATOR
+        if (!$feof(f_info)) begin
+            $fscanf(f_info, "%s\n", test_file);
+`endif // VERILATOR
+            f_test = $fopen(test_file,"r");
+            if (f_test != 0) begin
+            // Launch new test
+                `ifdef YCR1_TRACE_LOG_EN
+                    u_top.u_riscv_top.i_core_top.i_pipe_top.i_tracelog.test_name = test_file;
+                `endif // SCR1_TRACE_LOG_EN
+                //i_memory_tb.test_file = test_file;
+                //i_memory_tb.test_file_init = 1'b1;
+                `ifndef SIGNATURE_OUT
+                    $write("\033[0;34m---Test: %s\033[0m\n", test_file);
+                `endif //SIGNATURE_OUT
+                test_running <= 1'b1;
+                rst_init <= 1'b1;
+                `ifdef SIGNATURE_OUT
+                    b_single_run_flag = 0;
+                `endif
+            end else begin
+                $fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "__FAIL", "--------");
+            end
+        end else begin
+            // Exit
+            `ifndef SIGNATURE_OUT
+                $display("\n#--------------------------------------");
+                $display("# Summary: %0d/%0d tests passed", tests_passed, tests_total);
+                $display("#--------------------------------------\n");
+                $fclose(f_info);
+                $fclose(f_results);
+            `endif
+            $finish();
+        end
+    end
+end
+
+
+        `ifdef VERILATOR
+        function bit is_compliance (logic [255:0] testname);
+            bit res;
+            logic [79:0] pattern;
+        begin
+            pattern = 80'h636f6d706c69616e6365; // compliance
+            res = 0;
+            for (int i = 0; i<= 176; i++) begin
+                if(testname[i+:80] == pattern) begin
+                    return ~res;
+                end
+            end
+            `ifdef SIGNATURE_OUT
+                return ~res;
+            `else
+                return res;
+            `endif
+        end
+        endfunction : is_compliance
+        
+        function logic [255:0] get_filename (logic [255:0] testname);
+        logic [255:0] res;
+        int i, j;
+        begin
+            testname[7:0] = 8'h66;
+            testname[15:8] = 8'h6C;
+            testname[23:16] = 8'h65;
+        
+            for (i = 0; i <= 248; i += 8) begin
+                if (testname[i+:8] == 0) begin
+                    break;
+                end
+            end
+            i -= 8;
+            for (j = 255; i >= 0;i -= 8) begin
+                res[j-:8] = testname[i+:8];
+                j -= 8;
+            end
+            for (; j >= 0;j -= 8) begin
+                res[j-:8] = 0;
+            end
+        
+            return res;
+        end
+        endfunction : get_filename
+        
+        function logic [255:0] get_ref_filename (logic [255:0] testname);
+        logic [255:0] res;
+        int i, j;
+        logic [79:0] pattern;
+        begin
+            pattern = 80'h636f6d706c69616e6365; // compliance
+        
+            for(int i = 0; i <= 176; i++) begin
+                if(testname[i+:80] == pattern) begin
+                    testname[(i-8)+:88] = 0;
+                    break;
+                end
+            end
+        
+            for(i = 32; i <= 248; i += 8) begin
+                if(testname[i+:8] == 0) break;
+            end
+            i -= 8;
+            for(j = 255; i > 24; i -= 8) begin
+                res[j-:8] = testname[i+:8];
+                j -= 8;
+            end
+            for(; j >=0;j -= 8) begin
+                res[j-:8] = 0;
+            end
+        
+            return res;
+        end
+        endfunction : get_ref_filename
+        
+        function logic [2047:0] remove_trailing_whitespaces (logic [2047:0] str);
+        int i;
+        begin
+            for (i = 0; i <= 2040; i += 8) begin
+                if (str[i+:8] != 8'h20) begin
+                    break;
+                end
+            end
+            str = str >> i;
+            return str;
+        end
+        endfunction: remove_trailing_whitespaces
+        
+        `else // VERILATOR
+        function bit is_compliance (string testname);
+        begin
+            return (testname.substr(0, 9) == "compliance");
+        end
+        endfunction : is_compliance
+        
+        function string get_filename (string testname);
+        int length;
+        begin
+            length = testname.len();
+            testname[length-1] = "f";
+            testname[length-2] = "l";
+            testname[length-3] = "e";
+        
+            return testname;
+        end
+        endfunction : get_filename
+        
+        function string get_ref_filename (string testname);
+        begin
+            return testname.substr(11, testname.len() - 5);
+        end
+        endfunction : get_ref_filename
+        
+        `endif // VERILATOR
+
diff --git a/verilog/dv/riscv_regress/run_iverilog b/verilog/dv/riscv_regress/run_iverilog
new file mode 100755
index 0000000..fbd8e05
--- /dev/null
+++ b/verilog/dv/riscv_regress/run_iverilog
@@ -0,0 +1,33 @@
+cd /home/dinesha/workarea/opencore/git/riscduino/verilog/rtl/syntacore/scr1/sim/tests/hello
+
+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/home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/../../../verilog/rtl/syntacore/scr1/sim/tests/common  /home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/../../../verilog/rtl/syntacore/scr1/sim/tests/common/sc_print.c -o /home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/build/iverilog_WB_MAX_imc_IPIC_1_TCM_1_VIRQ_1_TRACE_0/sc_print.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 "\"  -c -I./ -I/home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/../../../verilog/rtl/syntacore/scr1/sim/tests/common  hello.c -o /home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/build/iverilog_WB_MAX_imc_IPIC_1_TCM_1_VIRQ_1_TRACE_0/hello.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/home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/../../../verilog/rtl/syntacore/scr1/sim/tests/common  /home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/../../../verilog/rtl/syntacore/scr1/sim/tests/common/crt_tcm.S -o /home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/build/iverilog_WB_MAX_imc_IPIC_1_TCM_1_VIRQ_1_TRACE_0/crt_tcm.o
+
+riscv64-unknown-elf-gcc -o /home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/build/iverilog_WB_MAX_imc_IPIC_1_TCM_1_VIRQ_1_TRACE_0/hello.elf -T /home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/../../../verilog/rtl/syntacore/scr1/sim/tests/common/link_tcm.ld /home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/build/iverilog_WB_MAX_imc_IPIC_1_TCM_1_VIRQ_1_TRACE_0/sc_print.o /home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/build/iverilog_WB_MAX_imc_IPIC_1_TCM_1_VIRQ_1_TRACE_0/hello.o /home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/build/iverilog_WB_MAX_imc_IPIC_1_TCM_1_VIRQ_1_TRACE_0/crt_tcm.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32
+rm /home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/build/iverilog_WB_MAX_imc_IPIC_1_TCM_1_VIRQ_1_TRACE_0/sc_print.o /home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/build/iverilog_WB_MAX_imc_IPIC_1_TCM_1_VIRQ_1_TRACE_0/crt_tcm.o /home/dinesha/workarea/opencore/git/riscduino/verilog/dv/riscv_regress/build/iverilog_WB_MAX_imc_IPIC_1_TCM_1_VIRQ_1_TRACE_0/hello.o
+
+cd build/iverilog_WB_MAX_imc_IPIC_1_TCM_1_VIRQ_1_TRACE_0
+
+iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $PDK_ROOT/sky130A \
+-I $CARAVEL_ROOT/verilog/dv/caravel \
+-I $CARAVEL_ROOT/verilog/rtl \
+-I ../../../model    \
+-I ../../../../../verilog/rtl \
+-I ../../../../../verilog \
+-I ../../../agents    \
+-I ../../../../../verilog/rtl/yifive/ycr1c/src/includes \
+-I ../../../../../verilog/rtl/sdram_ctrl/src/defs \
+-I ../../../../../verilog/rtl/i2cm/src/includes \
+-I ../../../../../verilog/rtl/usb1_host/src/includes \
+-I ../../../../../verilog/rtl/mbist/include \
+-I ../.. \
+../../user_risc_regress_tb.v \
+-o user_risc_regress_tb.vvp
+
+iverilog-vpi ../../../vpi/system/system.c
+
+vvp  -M. -msystem  user_risc_regress_tb.vvp +test_info=./test_info +test_results=./test_results.txt | tee sim_results.txt
+
diff --git a/verilog/dv/riscv_regress/tests/benchmarks/coremark/Makefile b/verilog/dv/riscv_regress/tests/benchmarks/coremark/Makefile
new file mode 100644
index 0000000..e60623b
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/benchmarks/coremark/Makefile
@@ -0,0 +1,26 @@
+src_dir := $(dir $(lastword $(MAKEFILE_LIST)))
+depend_dir := $(src_dir)/../../../dependencies/coremark
+
+ifeq ("$(ITERATIONS)","")
+ITERATIONS=1
+endif
+
+ADD_CFLAGS  += -DITERATIONS=$(ITERATIONS)
+ADD_VPATH   := $(depend_dir)
+ADD_incs    := -I$(src_dir)/src -I$(depend_dir)
+
+c_src := core_portme.c sc_print.c 
+coremark_src := ./src/core_list_join.c ./src/core_matrix.c ./src/core_main.c ./src/core_util.c ./src/core_state.c
+c_src += core_list_join.c core_matrix.c core_main.c core_util.c core_state.c
+
+include $(inc_dir)/common.mk
+
+
+default: log_requested_tgt  $(bld_dir)/coremark.elf $(bld_dir)/coremark.hex $(bld_dir)/coremark.dump 
+
+log_requested_tgt:
+	echo coremark.hex>> $(bld_dir)/test_info
+	echo $(inc_dir)/common.mk
+
+clean:
+	$(RM) $(c_objs) $(asm_objs) $(bld_dir)/coremark.hex $(bld_dir)/coremark.dump 
diff --git a/verilog/dv/riscv_regress/tests/benchmarks/coremark/core_portme.c b/verilog/dv/riscv_regress/tests/benchmarks/coremark/core_portme.c
new file mode 100644
index 0000000..3c801f7
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/benchmarks/coremark/core_portme.c
@@ -0,0 +1,141 @@
+/*
+	File : core_portme.c
+*/
+/*
+	Author : Shay Gal-On, EEMBC
+	Legal : TODO!
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "coremark.h"
+#include "core_portme.h"
+#include "riscv_csr_encoding.h"
+#include "sc_test.h"
+
+#if VALIDATION_RUN
+	volatile ee_s32 seed1_volatile=0x3415;
+	volatile ee_s32 seed2_volatile=0x3415;
+	volatile ee_s32 seed3_volatile=0x66;
+#endif
+#if PERFORMANCE_RUN
+	volatile ee_s32 seed1_volatile=0x0;
+	volatile ee_s32 seed2_volatile=0x0;
+	volatile ee_s32 seed3_volatile=0x66;
+#endif
+#if PROFILE_RUN
+	volatile ee_s32 seed1_volatile=0x8;
+	volatile ee_s32 seed2_volatile=0x8;
+	volatile ee_s32 seed3_volatile=0x8;
+#endif
+	volatile ee_s32 seed4_volatile=ITERATIONS;
+	volatile ee_s32 seed5_volatile=0;
+
+/* Porting : Timing functions
+	How to capture time and convert to seconds must be ported to whatever is supported by the platform.
+	e.g. Read value from on board RTC, read value from cpu clock cycles performance counter etc.
+	Sample implementation for standard time.h and windows.h definitions included.
+*/
+#if 1
+CORETIMETYPE barebones_clock() {
+	unsigned long n;
+	__asm__ __volatile__ (
+		"rdtime %0"
+		: "=r" (n));
+	return n;
+}
+#define CLOCKS_PER_SEC	10000000
+
+/* Define : TIMER_RES_DIVIDER
+	Divider to trade off timer resolution and total time that can be measured.
+
+	Use lower values to increase resolution, but make sure that overflow does not occur.
+	If there are issues with the return value overflowing, increase this value.
+	*/
+/* #define NSECS_PER_SEC CLOCKS_PER_SEC */
+/* #define CORETIMETYPE clock_t */
+#define GETMYTIME(_t) (*_t=barebones_clock())
+#define MYTIMEDIFF(fin,ini) ((fin)-(ini))
+#define TIMER_RES_DIVIDER 1
+#define SAMPLE_TIME_IMPLEMENTATION 1
+#define EE_TICKS_PER_SEC (CLOCKS_PER_SEC / TIMER_RES_DIVIDER)
+#else
+
+#endif
+
+/** Define Host specific (POSIX), or target specific global time variables. */
+static CORETIMETYPE start_time_val, stop_time_val;
+
+/* Function : start_time
+	This function will be called right before starting the timed portion of the benchmark.
+
+	Implementation may be capturing a system timer (as implemented in the example code)
+	or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0.
+*/
+void start_time(void) {
+	GETMYTIME(&start_time_val );
+}
+/* Function : stop_time
+	This function will be called right after ending the timed portion of the benchmark.
+
+	Implementation may be capturing a system timer (as implemented in the example code)
+	or other system parameters - e.g. reading the current value of cpu cycles counter.
+*/
+void stop_time(void) {
+	GETMYTIME(&stop_time_val );
+}
+/* Function : get_time
+	Return an abstract "ticks" number that signifies time on the system.
+
+	Actual value returned may be cpu cycles, milliseconds or any other value,
+	as long as it can be converted to seconds by <time_in_secs>.
+	This methodology is taken to accomodate any hardware or simulated platform.
+	The sample implementation returns millisecs by default,
+	and the resolution is controlled by <TIMER_RES_DIVIDER>
+*/
+CORE_TICKS get_time(void) {
+	CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
+	return elapsed;
+}
+/* Function : time_in_secs
+	Convert the value returned by get_time to seconds.
+
+	The <secs_ret> type is used to accomodate systems with no support for floating point.
+	Default implementation implemented by the EE_TICKS_PER_SEC macro above.
+*/
+secs_ret time_in_secs(CORE_TICKS ticks) {
+	secs_ret retval=((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
+	return retval;
+}
+
+ee_u32 default_num_contexts=1;
+
+/* Function : portable_init
+	Target specific initialization code
+	Test for some common mistakes.
+*/
+void portable_init(core_portable *p, int *argc, char *argv[])
+{
+    ee_printf("CoreMark 1.0\n");
+	if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) {
+		ee_printf("ERROR! Please define ee_ptr_int to a type that holds a pointer! (%u != %u)\n", sizeof(ee_ptr_int), sizeof(ee_u8 *));
+	}
+	if (sizeof(ee_u32) != 4) {
+		ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type! (%u)\n", sizeof(ee_u32));
+	}
+	p->portable_id=1;
+}
+/* Function : portable_fini
+	Target specific final code
+*/
+void portable_fini(core_portable *p)
+{
+	p->portable_id=0;
+
+    report_results(0, 0, 0, 0, 0);
+
+    /* results[0].iterations * 10000000/(total_time) */
+
+    /* extern void tohost_exit(long code); */
+
+    /* tohost_exit(0); */
+}
diff --git a/verilog/dv/riscv_regress/tests/benchmarks/coremark/core_portme.h b/verilog/dv/riscv_regress/tests/benchmarks/coremark/core_portme.h
new file mode 100644
index 0000000..857930f
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/benchmarks/coremark/core_portme.h
@@ -0,0 +1,210 @@
+/* File : core_portme.h */
+
+/*
+	Author : Shay Gal-On, EEMBC
+	Legal : TODO!
+*/
+/* Topic : Description
+	This file contains configuration constants required to execute on different platforms
+*/
+#ifndef CORE_PORTME_H
+#define CORE_PORTME_H
+/************************/
+/* Data types and settings */
+/************************/
+/* Configuration : HAS_FLOAT
+	Define to 1 if the platform supports floating point.
+*/
+#ifndef HAS_FLOAT
+#define HAS_FLOAT 0
+#endif
+/* Configuration : HAS_TIME_H
+	Define to 1 if platform has the time.h header file,
+	and implementation of functions thereof.
+*/
+#ifndef HAS_TIME_H
+#define HAS_TIME_H 0
+#endif
+/* Configuration : USE_CLOCK
+	Define to 1 if platform has the time.h header file,
+	and implementation of functions thereof.
+*/
+#ifndef USE_CLOCK
+#define USE_CLOCK 0
+#endif
+/* Configuration : HAS_STDIO
+	Define to 1 if the platform has stdio.h.
+*/
+#ifndef HAS_STDIO
+#define HAS_STDIO 1
+#endif
+/* Configuration : HAS_PRINTF
+	Define to 1 if the platform has stdio.h and implements the printf function.
+*/
+#ifndef HAS_PRINTF
+#define HAS_PRINTF 0
+#endif
+
+#include "sc_print.h"
+#define ee_printf sc_printf
+
+/* static inline int ee_printf(const char *fmt, ...) {} */
+
+/* Configuration : CORE_TICKS
+	Define type of return from the timing functions.
+ */
+/* #include <time.h> */
+/* typedef clock_t CORE_TICKS; */
+#include <stdint.h>
+#include <stddef.h>
+#define CORETIMETYPE uint32_t
+typedef uint32_t CORE_TICKS;
+
+/* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION
+	Initialize these strings per platform
+*/
+#ifndef COMPILER_VERSION
+ #ifdef __GNUC__
+ #define COMPILER_VERSION "GCC"__VERSION__
+ #else
+ #define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)"
+ #endif
+#endif
+#ifndef COMPILER_FLAGS
+ #define COMPILER_FLAGS FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */
+#endif
+#ifndef MEM_LOCATION
+ /* #define MEM_LOCATION "STACK" */
+ #define MEM_LOCATION "STATIC"
+#endif
+
+/* Data Types :
+	To avoid compiler issues, define the data types that need ot be used for 8b, 16b and 32b in <core_portme.h>.
+
+	*Imprtant* :
+	ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!!
+*/
+typedef int16_t ee_s16;
+typedef uint16_t ee_u16;
+typedef int32_t ee_s32;
+typedef float ee_f32;
+typedef uint8_t ee_u8;
+typedef uint32_t ee_u32;
+typedef uintptr_t ee_ptr_int;
+typedef size_t ee_size_t;
+/* align_mem :
+	This macro is used to align an offset to point to a 32b value. It is used in the Matrix algorithm to initialize the input memory blocks.
+*/
+#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x) - 1) & ~3))
+
+/* Configuration : SEED_METHOD
+	Defines method to get seed values that cannot be computed at compile time.
+
+	Valid values :
+	SEED_ARG - from command line.
+	SEED_FUNC - from a system function.
+	SEED_VOLATILE - from volatile variables.
+*/
+#ifndef SEED_METHOD
+#define SEED_METHOD SEED_VOLATILE
+#endif
+
+/* Configuration : MEM_METHOD
+	Defines method to get a block of memry.
+
+	Valid values :
+	MEM_MALLOC - for platforms that implement malloc and have malloc.h.
+	MEM_STATIC - to use a static memory array.
+	MEM_STACK - to allocate the data block on the stack (NYI).
+*/
+#ifndef MEM_METHOD
+/* #define MEM_METHOD MEM_STACK */
+#define MEM_METHOD MEM_STATIC
+#endif
+
+/* Configuration : MULTITHREAD
+	Define for parallel execution
+
+	Valid values :
+	1 - only one context (default).
+	N>1 - will execute N copies in parallel.
+
+	Note :
+	If this flag is defined to more then 1, an implementation for launching parallel contexts must be defined.
+
+	Two sample implementations are provided. Use <USE_PTHREAD> or <USE_FORK> to enable them.
+
+	It is valid to have a different implementation of <core_start_parallel> and <core_end_parallel> in <core_portme.c>,
+	to fit a particular architecture.
+*/
+#ifndef MULTITHREAD
+#define MULTITHREAD 1
+#define USE_PTHREAD 0
+#define USE_FORK 0
+#define USE_SOCKET 0
+#endif
+
+/* Configuration : MAIN_HAS_NOARGC
+	Needed if platform does not support getting arguments to main.
+
+	Valid values :
+	0 - argc/argv to main is supported
+	1 - argc/argv to main is not supported
+
+	Note :
+	This flag only matters if MULTITHREAD has been defined to a value greater then 1.
+*/
+#ifndef MAIN_HAS_NOARGC
+#define MAIN_HAS_NOARGC 1
+#endif
+
+/* Configuration : MAIN_HAS_NORETURN
+	Needed if platform does not support returning a value from main.
+
+	Valid values :
+	0 - main returns an int, and return value will be 0.
+	1 - platform does not support returning a value from main
+*/
+#ifndef MAIN_HAS_NORETURN
+#define MAIN_HAS_NORETURN 0
+#endif
+
+/* Variable : default_num_contexts
+	Not used for this simple port, must cintain the value 1.
+*/
+extern ee_u32 default_num_contexts;
+
+typedef struct CORE_PORTABLE_S {
+	ee_u8	portable_id;
+} core_portable;
+
+/* target specific init/fini */
+void portable_init(core_portable *p, int *argc, char *argv[]);
+void portable_fini(core_portable *p);
+
+#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN)
+#if (TOTAL_DATA_SIZE==1200)
+#define PROFILE_RUN 1
+#elif (TOTAL_DATA_SIZE==2000)
+#define PERFORMANCE_RUN 1
+#else
+#define VALIDATION_RUN 1
+#endif
+#endif
+
+typedef ee_s16 MATDAT;
+typedef ee_s32 MATRES;
+
+
+ee_u16 crcu8(ee_u8 data, ee_u16 crc ) __attribute__ ((hot));
+ee_u16 crcu16(ee_u16 newval, ee_u16 crc) __attribute__ ((hot));
+ee_u16 crcu32(ee_u32 newval, ee_u16 crc) __attribute__ ((hot));
+ee_u16 crc16(ee_s16 newval, ee_u16 crc) __attribute__ ((hot));
+ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval) __attribute__ ((hot));
+void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val) __attribute__ ((hot));
+void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) __attribute__ ((hot));
+void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) __attribute__ ((hot));
+void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) __attribute__ ((hot));
+void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val) __attribute__ ((hot));
+
+#endif /* CORE_PORTME_H */
diff --git a/verilog/dv/riscv_regress/tests/benchmarks/dhrystone21/Makefile b/verilog/dv/riscv_regress/tests/benchmarks/dhrystone21/Makefile
new file mode 100644
index 0000000..7056489
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/benchmarks/dhrystone21/Makefile
@@ -0,0 +1,16 @@
+src_dir := $(dir $(lastword $(MAKEFILE_LIST)))
+
+ADD_FLAGS   := -flto
+ADD_CFLAGS  := -DSELF_TIMED=1 -DTIME=1
+
+c_src := sc_print.c dhry_1.c dhry_2.c
+
+include $(inc_dir)/common.mk
+
+default: log_requested_tgt $(bld_dir)/dhrystone21.elf $(bld_dir)/dhrystone21.hex $(bld_dir)/dhrystone21.dump
+
+log_requested_tgt:
+	@echo dhrystone21.hex>> $(bld_dir)/test_info
+
+clean:
+	$(RM) $(c_objs) $(asm_objs) $(bld_dir)/dhrystone21.elf $(bld_dir)/dhrystone21.hex $(bld_dir)/dhrystone21.dump
\ No newline at end of file
diff --git a/verilog/dv/riscv_regress/tests/benchmarks/dhrystone21/dhry.h b/verilog/dv/riscv_regress/tests/benchmarks/dhrystone21/dhry.h
new file mode 100644
index 0000000..cba0059
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/benchmarks/dhrystone21/dhry.h
@@ -0,0 +1,446 @@
+/*****************************************************************************
+ *  The BYTE UNIX Benchmarks - Release 3
+ *          Module: dhry.h   SID: 3.4 5/15/91 19:30:21
+ *
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ *	Ben Smith, Rick Grehan or Tom Yager
+ *	ben@bytepb.byte.com   rick_g@bytepb.byte.com   tyager@bytepb.byte.com
+ *
+ *****************************************************************************
+ *  Modification Log:
+ *  addapted from:
+ *
+ *
+ *                   "DHRYSTONE" Benchmark Program
+ *                   -----------------------------
+ *
+ *  Version:    C, Version 2.1
+ *
+ *  File:       dhry.h (part 1 of 3)
+ *
+ *  Date:       May 25, 1988
+ *
+ *  Author:     Reinhold P. Weicker
+ *                      Siemens AG, AUT E 51
+ *                      Postfach 3220
+ *                      8520 Erlangen
+ *                      Germany (West)
+ *                              Phone:  [+49]-9131-7-20330
+ *                                      (8-17 Central European Time)
+ *                              Usenet: ..!mcvax!unido!estevax!weicker
+ *
+ *              Original Version (in Ada) published in
+ *              "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
+ *              pp. 1013 - 1030, together with the statistics
+ *              on which the distribution of statements etc. is based.
+ *
+ *              In this C version, the following C library functions are used:
+ *              - strcpy, strcmp (inside the measurement loop)
+ *              - printf, scanf (outside the measurement loop)
+ *              In addition, Berkeley UNIX system calls "times ()" or "time ()"
+ *              are used for execution time measurement. For measurements
+ *              on other systems, these calls have to be changed.
+ *
+ *  Collection of Results:
+ *              Reinhold Weicker (address see above) and
+ *
+ *              Rick Richardson
+ *              PC Research. Inc.
+ *              94 Apple Orchard Drive
+ *              Tinton Falls, NJ 07724
+ *                      Phone:  (201) 834-1378 (9-17 EST)
+ *                      Usenet: ...!seismo!uunet!pcrat!rick
+ *
+ *      Please send results to Rick Richardson and/or Reinhold Weicker.
+ *      Complete information should be given on hardware and software used.
+ *      Hardware information includes: Machine type, CPU, type and size
+ *      of caches; for microprocessors: clock frequency, memory speed
+ *      (number of wait states).
+ *      Software information includes: Compiler (and runtime library)
+ *      manufacturer and version, compilation switches, OS version.
+ *      The Operating System version may give an indication about the
+ *      compiler; Dhrystone itself performs no OS calls in the measurement loop.
+ *
+ *      The complete output generated by the program should be mailed
+ *      such that at least some checks for correctness can be made.
+ *
+ ***************************************************************************
+ *
+ *  History:    This version C/2.1 has been made for two reasons:
+ *
+ *              1) There is an obvious need for a common C version of
+ *              Dhrystone, since C is at present the most popular system
+ *              programming language for the class of processors
+ *              (microcomputers, minicomputers) where Dhrystone is used most.
+ *              There should be, as far as possible, only one C version of
+ *              Dhrystone such that results can be compared without
+ *              restrictions. In the past, the C versions distributed
+ *              by Rick Richardson (Version 1.1) and by Reinhold Weicker
+ *              had small (though not significant) differences.
+ *
+ *              2) As far as it is possible without changes to the Dhrystone
+ *              statistics, optimizing compilers should be prevented from
+ *              removing significant statements.
+ *
+ *              This C version has been developed in cooperation with
+ *              Rick Richardson (Tinton Falls, NJ), it incorporates many
+ *              ideas from the "Version 1.1" distributed previously by
+ *              him over the UNIX network Usenet.
+ *              I also thank Chaim Benedelac (National Semiconductor),
+ *              David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
+ *              Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
+ *              for their help with comments on earlier versions of the
+ *              benchmark.
+ *
+ *  Changes:    In the initialization part, this version follows mostly
+ *              Rick Richardson's version distributed via Usenet, not the
+ *              version distributed earlier via floppy disk by Reinhold Weicker.
+ *              As a concession to older compilers, names have been made
+ *              unique within the first 8 characters.
+ *              Inside the measurement loop, this version follows the
+ *              version previously distributed by Reinhold Weicker.
+ *
+ *              At several places in the benchmark, code has been added,
+ *              but within the measurement loop only in branches that
+ *              are not executed. The intention is that optimizing compilers
+ *              should be prevented from moving code out of the measurement
+ *              loop, or from removing code altogether. Since the statements
+ *              that are executed within the measurement loop have NOT been
+ *              changed, the numbers defining the "Dhrystone distribution"
+ *              (distribution of statements, operand types and locality)
+ *              still hold. Except for sophisticated optimizing compilers,
+ *              execution times for this version should be the same as
+ *              for previous versions.
+ *
+ *              Since it has proven difficult to subtract the time for the
+ *              measurement loop overhead in a correct way, the loop check
+ *              has been made a part of the benchmark. This does have
+ *              an impact - though a very minor one - on the distribution
+ *              statistics which have been updated for this version.
+ *
+ *              All changes within the measurement loop are described
+ *              and discussed in the companion paper "Rationale for
+ *              Dhrystone version 2".
+ *
+ *              Because of the self-imposed limitation that the order and
+ *              distribution of the executed statements should not be
+ *              changed, there are still cases where optimizing compilers
+ *              may not generate code for some statements. To a certain
+ *              degree, this is unavoidable for small synthetic benchmarks.
+ *              Users of the benchmark are advised to check code listings
+ *              whether code is generated for all statements of Dhrystone.
+ *
+ *              Version 2.1 is identical to version 2.0 distributed via
+ *              the UNIX network Usenet in March 1988 except that it corrects
+ *              some minor deficiencies that were found by users of version 2.0.
+ *              The only change within the measurement loop is that a
+ *              non-executed "else" part was added to the "if" statement in
+ *              Func_3, and a non-executed "else" part removed from Proc_3.
+ *
+ ***************************************************************************
+ *
+ * Defines:     The following "Defines" are possible:
+ *              -DREG=register          (default: Not defined)
+ *                      As an approximation to what an average C programmer
+ *                      might do, the "register" storage class is applied
+ *                      (if enabled by -DREG=register)
+ *                      - for local variables, if they are used (dynamically)
+ *                        five or more times
+ *                      - for parameters if they are used (dynamically)
+ *                        six or more times
+ *                      Note that an optimal "register" strategy is
+ *                      compiler-dependent, and that "register" declarations
+ *                      do not necessarily lead to faster execution.
+ *              -DNOSTRUCTASSIGN        (default: Not defined)
+ *                      Define if the C compiler does not support
+ *                      assignment of structures.
+ *              -DNOENUMS               (default: Not defined)
+ *                      Define if the C compiler does not support
+ *                      enumeration types.
+ *              -DTIMES                 (default)
+ *              -DTIME
+ *                      The "times" function of UNIX (returning process times)
+ *                      or the "time" function (returning wallclock time)
+ *                      is used for measurement.
+ *                      For single user machines, "time ()" is adequate. For
+ *                      multi-user machines where you cannot get single-user
+ *                      access, use the "times ()" function. If you have
+ *                      neither, use a stopwatch in the dead of night.
+ *                      "printf"s are provided marking the points "Start Timer"
+ *                      and "Stop Timer". DO NOT use the UNIX "time(1)"
+ *                      command, as this will measure the total time to
+ *                      run this program, which will (erroneously) include
+ *                      the time to allocate storage (malloc) and to perform
+ *                      the initialization.
+ *              -DHZ=nnn
+ *                      In Berkeley UNIX, the function "times" returns process
+ *                      time in 1/HZ seconds, with HZ = 60 for most systems.
+ *                      CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
+ *                      A VALUE.
+ *
+ ***************************************************************************
+ *
+ *  Compilation model and measurement (IMPORTANT):
+ *
+ *  This C version of Dhrystone consists of three files:
+ *  - dhry.h (this file, containing global definitions and comments)
+ *  - dhry_1.c (containing the code corresponding to Ada package Pack_1)
+ *  - dhry_2.c (containing the code corresponding to Ada package Pack_2)
+ *
+ *  The following "ground rules" apply for measurements:
+ *  - Separate compilation
+ *  - No procedure merging
+ *  - Otherwise, compiler optimizations are allowed but should be indicated
+ *  - Default results are those without register declarations
+ *  See the companion paper "Rationale for Dhrystone Version 2" for a more
+ *  detailed discussion of these ground rules.
+ *
+ *  For 16-Bit processors (e.g. 80186, 80286), times for all compilation
+ *  models ("small", "medium", "large" etc.) should be given if possible,
+ *  together with a definition of these models for the compiler system used.
+ *
+ **************************************************************************
+ *
+ *  Dhrystone (C version) statistics:
+ *
+ *  [Comment from the first distribution, updated for version 2.
+ *   Note that because of language differences, the numbers are slightly
+ *   different from the Ada version.]
+ *
+ *  The following program contains statements of a high level programming
+ *  language (here: C) in a distribution considered representative:
+ *
+ *    assignments                  52 (51.0 %)
+ *    control statements           33 (32.4 %)
+ *    procedure, function calls    17 (16.7 %)
+ *
+ *  103 statements are dynamically executed. The program is balanced with
+ *  respect to the three aspects:
+ *
+ *    - statement type
+ *    - operand type
+ *    - operand locality
+ *         operand global, local, parameter, or constant.
+ *
+ *  The combination of these three aspects is balanced only approximately.
+ *
+ *  1. Statement Type:
+ *  -----------------             number
+ *
+ *     V1 = V2                     9
+ *       (incl. V1 = F(..)
+ *     V = Constant               12
+ *     Assignment,                 7
+ *       with array element
+ *     Assignment,                 6
+ *       with record component
+ *                                --
+ *                                34       34
+ *
+ *     X = Y +|-|"&&"|"|" Z        5
+ *     X = Y +|-|"==" Constant     6
+ *     X = X +|- 1                 3
+ *     X = Y *|/ Z                 2
+ *     X = Expression,             1
+ *           two operators
+ *     X = Expression,             1
+ *           three operators
+ *                                --
+ *                                18       18
+ *
+ *     if ....                    14
+ *       with "else"      7
+ *       without "else"   7
+ *           executed        3
+ *           not executed    4
+ *     for ...                     7  |  counted every time
+ *     while ...                   4  |  the loop condition
+ *     do ... while                1  |  is evaluated
+ *     switch ...                  1
+ *     break                       1
+ *     declaration with            1
+ *       initialization
+ *                                --
+ *                                34       34
+ *
+ *     P (...)  procedure call    11
+ *       user procedure      10
+ *       library procedure    1
+ *     X = F (...)
+ *             function  call      6
+ *       user function        5
+ *       library function     1
+ *                                --
+ *                                17       17
+ *                                        ---
+ *                                        103
+ *
+ *    The average number of parameters in procedure or function calls
+ *    is 1.82 (not counting the function values as implicit parameters).
+ *
+ *
+ *  2. Operators
+ *  ------------
+ *                          number    approximate
+ *                                    percentage
+ *
+ *    Arithmetic             32          50.8
+ *
+ *       +                     21          33.3
+ *       -                      7          11.1
+ *       *                      3           4.8
+ *       / (int div)            1           1.6
+ *
+ *    Comparison             27           42.8
+ *
+ *       ==                     9           14.3
+ *       /=                     4            6.3
+ *       >                      1            1.6
+ *       <                      3            4.8
+ *       >=                     1            1.6
+ *       <=                     9           14.3
+ *
+ *    Logic                   4            6.3
+ *
+ *       && (AND-THEN)          1            1.6
+ *       |  (OR)                1            1.6
+ *       !  (NOT)               2            3.2
+ *
+ *                           --          -----
+ *                           63          100.1
+ *
+ *
+ *  3. Operand Type (counted once per operand reference):
+ *  ---------------
+ *                          number    approximate
+ *                                    percentage
+ *
+ *     Integer               175        72.3 %
+ *     Character              45        18.6 %
+ *     Pointer                12         5.0 %
+ *     String30                6         2.5 %
+ *     Array                   2         0.8 %
+ *     Record                  2         0.8 %
+ *                           ---       -------
+ *                           242       100.0 %
+ *
+ *  When there is an access path leading to the final operand (e.g. a record
+ *  component), only the final data type on the access path is counted.
+ *
+ *
+ *  4. Operand Locality:
+ *  -------------------
+ *                                number    approximate
+ *                                          percentage
+ *
+ *     local variable              114        47.1 %
+ *     global variable              22         9.1 %
+ *     parameter                    45        18.6 %
+ *        value                        23         9.5 %
+ *        reference                    22         9.1 %
+ *     function result               6         2.5 %
+ *     constant                     55        22.7 %
+ *                                 ---       -------
+ *                                 242       100.0 %
+ *
+ *
+ *  The program does not compute anything meaningful, but it is syntactically
+ *  and semantically correct. All variables have a value assigned to them
+ *  before they are used as a source operand.
+ *
+ *  There has been no explicit effort to account for the effects of a
+ *  cache, or to balance the use of long or short displacements for code or
+ *  data.
+ *
+ ***************************************************************************
+ */
+
+
+/* Compiler and system dependent definitions: */
+
+#ifndef TIME
+#define TIMES
+#endif
+                /* Use times(2) time function unless    */
+                /* explicitly defined otherwise         */
+
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+                /* for "times" */
+#endif
+
+#define Mic_secs_Per_Second     1000000
+                /* Berkeley UNIX C returns process times in seconds/HZ */
+
+#ifdef  NOSTRUCTASSIGN
+#define structassign(d, s)      memcpy(&(d), &(s), sizeof(d))
+#else
+#define structassign(d, s)      d = s
+#endif
+
+#ifdef  NOENUM
+#define Ident_1 0
+#define Ident_2 1
+#define Ident_3 2
+#define Ident_4 3
+#define Ident_5 4
+  typedef int   Enumeration;
+#else
+  typedef       enum    {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
+                Enumeration;
+#endif
+        /* for boolean and enumeration types in Ada, Pascal */
+
+/* General definitions: */
+
+#include <stdio.h>
+#include <string.h>
+                /* for strcpy, strcmp */
+
+#define Null 0
+                /* Value of a Null pointer */
+#define true  1
+#define false 0
+
+typedef int     One_Thirty;
+typedef int     One_Fifty;
+typedef char    Capital_Letter;
+typedef int     Boolean;
+typedef char    Str_30 [31];
+typedef int     Arr_1_Dim [50];
+typedef int     Arr_2_Dim [50] [50];
+
+typedef struct record
+    {
+    struct record *Ptr_Comp;
+    Enumeration    Discr;
+    union {
+          struct {
+                  Enumeration Enum_Comp;
+                  int         Int_Comp;
+                  char        Str_Comp [31];
+                  } var_1;
+          struct {
+                  Enumeration E_Comp_2;
+                  char        Str_2_Comp [31];
+                  } var_2;
+          struct {
+                  char        Ch_1_Comp;
+                  char        Ch_2_Comp;
+                  } var_3;
+          } variant;
+      } Rec_Type, *Rec_Pointer;
+
+#include "sc_print.h"
+#include "csr.h"
+
+# define printf sc_printf
+
+#define HZ 1000000
+static long time(long *x)
+{
+    return rdcycle();
+}
diff --git a/verilog/dv/riscv_regress/tests/benchmarks/dhrystone21/dhry_1.c b/verilog/dv/riscv_regress/tests/benchmarks/dhrystone21/dhry_1.c
new file mode 100644
index 0000000..d52acbb
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/benchmarks/dhrystone21/dhry_1.c
@@ -0,0 +1,461 @@
+/*****************************************************************************
+ *  The BYTE UNIX Benchmarks - Release 3
+ *          Module: dhry_1.c   SID: 3.4 5/15/91 19:30:21
+ *
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ *	Ben Smith, Rick Grehan or Tom Yager
+ *	ben@bytepb.byte.com   rick_g@bytepb.byte.com   tyager@bytepb.byte.com
+ *
+ *****************************************************************************
+ *
+ * *** WARNING ****  With BYTE's modifications applied, results obtained with
+ *     *******       this version of the Dhrystone program may not be applicable
+ *                   to other versions.
+ *
+ *  Modification Log:
+ *  10/22/97 - code cleanup to remove ANSI C compiler warnings
+ *             Andy Kahn <kahn@zk3.dec.com>
+ *
+ *  Adapted from:
+ *
+ *                   "DHRYSTONE" Benchmark Program
+ *                   -----------------------------
+ *
+ *  Version:    C, Version 2.1
+ *
+ *  File:       dhry_1.c (part 2 of 3)
+ *
+ *  Date:       May 25, 1988
+ *
+ *  Author:     Reinhold P. Weicker
+ *
+ ***************************************************************************/
+char SCCSid[] = "@(#) @(#)dhry_1.c:3.4 -- 5/15/91 19:30:21";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "dhry.h"
+//#include "timeit.c"
+
+unsigned long Run_Index;
+/*
+void report()
+{
+	fprintf(stderr,"COUNT|%ld|1|lps\n", Run_Index);
+	exit(0);
+}
+*/
+/* Global Variables: */
+
+Rec_Pointer     Ptr_Glob,
+                Next_Ptr_Glob;
+int             Int_Glob;
+Boolean         Bool_Glob;
+char            Ch_1_Glob,
+                Ch_2_Glob;
+int             Arr_1_Glob [50];
+int             Arr_2_Glob [50] [50];
+
+Enumeration     Func_1 ();
+  /* forward declaration necessary since Enumeration may not simply be int */
+
+#ifndef REG
+        Boolean Reg = false;
+#define REG
+        /* REG becomes defined as empty */
+        /* i.e. no register variables   */
+#else
+        Boolean Reg = true;
+#endif
+
+/* variables for time measurement: */
+
+#ifdef TIMES
+struct tms      time_info;
+/* extern  int     times (); */
+                /* see library function "times" */
+#define Too_Small_Time 120
+                /* Measurements should last at least about 2 seconds */
+#endif
+#ifdef TIME
+extern long     time();
+                /* see library function "time"  */
+#define Too_Small_Time 2
+                /* Measurements should last at least 2 seconds */
+#endif
+
+long            Begin_Time,
+                End_Time,
+                User_Time;
+#if 0
+float           Microseconds,
+                Dhrystones_Per_Second;
+#else
+long            Microseconds,
+                Dhrystones_Per_Second;
+#endif
+
+/* end of variables for time measurement */
+
+void Proc_1 (REG Rec_Pointer Ptr_Val_Par);
+void Proc_2 (One_Fifty   *Int_Par_Ref);
+void Proc_3 (Rec_Pointer *Ptr_Ref_Par);
+void Proc_4 (void);
+void Proc_5 (void);
+
+
+extern Boolean Func_2(Str_30, Str_30);
+extern void Proc_6(Enumeration, Enumeration *);
+extern void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
+extern void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
+
+int main (argc, argv)
+int	argc;
+char	*argv[];
+  /* main program, corresponds to procedures        */
+  /* Main and Proc_0 in the Ada version             */
+{
+#ifdef SELF_TIMED
+        int             Number_Of_Runs;
+#else /* SELF_TIMED */
+        int             duration;
+#endif /* SELF_TIMED */
+        One_Fifty       Int_1_Loc;
+  REG   One_Fifty       Int_2_Loc;
+        One_Fifty       Int_3_Loc;
+  REG   char            Ch_Index;
+        Enumeration     Enum_Loc;
+        Str_30          Str_1_Loc;
+        Str_30          Str_2_Loc;
+
+  /* Initializations */
+#if 0
+  Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+  Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+#else
+  static Rec_Type glob1, glob2;
+  Next_Ptr_Glob = &glob1;
+  Ptr_Glob = &glob2;
+#endif
+
+  Ptr_Glob->Ptr_Comp                    = Next_Ptr_Glob;
+  Ptr_Glob->Discr                       = Ident_1;
+  Ptr_Glob->variant.var_1.Enum_Comp     = Ident_3;
+  Ptr_Glob->variant.var_1.Int_Comp      = 40;
+  strcpy (Ptr_Glob->variant.var_1.Str_Comp,
+          "DHRYSTONE PROGRAM, SOME STRING");
+  strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
+
+  Arr_2_Glob [8][7] = 10;
+        /* Was missing in published program. Without this statement,    */
+        /* Arr_2_Glob [8][7] would have an undefined value.             */
+        /* Warning: With 16-Bit processors and Number_Of_Runs > 32000,  */
+        /* overflow may occur for this array element.                   */
+
+#ifdef SELF_TIMED
+  Number_Of_Runs = 500;//500000;
+  if (argc >= 2) {
+    Number_Of_Runs = atoi(argv[1]);
+    }
+  printf ("\n");
+  printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
+  printf ("\n");
+  if (Reg)
+  {
+    printf ("Program compiled with 'register' attribute\n");
+    printf ("\n");
+  }
+  else
+  {
+    printf ("Program compiled without 'register' attribute\n");
+    printf ("\n");
+  }
+#ifdef PRATTLE
+  printf ("Please give the number of runs through the benchmark: ");
+  {
+    int n;
+    scanf ("%d", &n);
+    Number_Of_Runs = n;
+  }
+  printf ("\n");
+#endif /* PRATTLE */
+
+  printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
+
+  Run_Index = 0;
+#else /* SELF_TIMED */
+  if (argc != 2) {
+    fprintf(stderr, "Usage: %s duration\n", argv[0]);
+    exit(1);
+    }
+
+  duration = atoi(argv[1]);
+  Run_Index = 0;
+  wake_me(duration, report);
+#endif /* SELF_TIMED */
+
+  /***************/
+  /* Start timer */
+  /***************/
+
+#ifdef SELF_TIMED
+#ifdef TIMES
+  times (&time_info);
+  Begin_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+  Begin_Time = time ( (long *) 0);
+#endif
+#endif /* SELF_TIMED */
+
+#ifdef SELF_TIMED
+  for (Run_Index = 1; Run_Index <= Number_Of_Runs ; ++Run_Index)
+#else /* SELF_TIMED */
+  for (Run_Index = 1; ; ++Run_Index)
+#endif /* SELF_TIMED */
+  {
+
+    Proc_5();
+    Proc_4();
+      /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
+    Int_1_Loc = 2;
+    Int_2_Loc = 3;
+    strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
+    Enum_Loc = Ident_2;
+    Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
+      /* Bool_Glob == 1 */
+    while (Int_1_Loc < Int_2_Loc)  /* loop body executed once */
+    {
+      Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
+        /* Int_3_Loc == 7 */
+      Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
+        /* Int_3_Loc == 7 */
+      Int_1_Loc += 1;
+    } /* while */
+      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+    Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
+      /* Int_Glob == 5 */
+    Proc_1 (Ptr_Glob);
+    for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
+                             /* loop body executed twice */
+    {
+      if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+          /* then, not executed */
+        {
+        Proc_6 (Ident_1, &Enum_Loc);
+        strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+        Int_2_Loc = Run_Index;
+        Int_Glob = Run_Index;
+        }
+    }
+      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+    Int_2_Loc = Int_2_Loc * Int_1_Loc;
+    Int_1_Loc = Int_2_Loc / Int_3_Loc;
+    Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
+      /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
+    Proc_2 (&Int_1_Loc);
+      /* Int_1_Loc == 5 */
+
+  } /* loop "for Run_Index" */
+
+  /**************/
+  /* Stop timer */
+  /**************/
+#ifdef SELF_TIMED
+#ifdef TIMES
+  times (&time_info);
+  End_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+  End_Time = time ( (long *) 0);
+#endif
+#endif /* SELF_TIMED */
+
+  /* BYTE version never executes this stuff */
+#ifdef SELF_TIMED
+  printf ("Execution ends\n");
+  printf ("\n");
+  printf ("Final values of the variables used in the benchmark:\n");
+  printf ("\n");
+  printf ("Int_Glob:            %d\n", Int_Glob);
+  printf ("        should be:   %d\n", 5);
+  printf ("Bool_Glob:           %d\n", Bool_Glob);
+  printf ("        should be:   %d\n", 1);
+  printf ("Ch_1_Glob:           %c\n", Ch_1_Glob);
+  printf ("        should be:   %c\n", 'A');
+  printf ("Ch_2_Glob:           %c\n", Ch_2_Glob);
+  printf ("        should be:   %c\n", 'B');
+  printf ("Arr_1_Glob[8]:       %d\n", Arr_1_Glob[8]);
+  printf ("        should be:   %d\n", 7);
+  printf ("Arr_2_Glob[8][7]:    %d\n", Arr_2_Glob[8][7]);
+  printf ("        should be:   Number_Of_Runs + 10\n");
+  printf ("Ptr_Glob->\n");
+  printf ("  Ptr_Comp:          %d\n", (int) Ptr_Glob->Ptr_Comp);
+  printf ("        should be:   (implementation-dependent)\n");
+  printf ("  Discr:             %d\n", Ptr_Glob->Discr);
+  printf ("        should be:   %d\n", 0);
+  printf ("  Enum_Comp:         %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
+  printf ("        should be:   %d\n", 2);
+  printf ("  Int_Comp:          %d\n", Ptr_Glob->variant.var_1.Int_Comp);
+  printf ("        should be:   %d\n", 17);
+  printf ("  Str_Comp:          %s\n", Ptr_Glob->variant.var_1.Str_Comp);
+  printf ("        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
+  printf ("Next_Ptr_Glob->\n");
+  printf ("  Ptr_Comp:          %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
+  printf ("        should be:   (implementation-dependent), same as above\n");
+  printf ("  Discr:             %d\n", Next_Ptr_Glob->Discr);
+  printf ("        should be:   %d\n", 0);
+  printf ("  Enum_Comp:         %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
+  printf ("        should be:   %d\n", 1);
+  printf ("  Int_Comp:          %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
+  printf ("        should be:   %d\n", 18);
+  printf ("  Str_Comp:          %s\n",
+                                Next_Ptr_Glob->variant.var_1.Str_Comp);
+  printf ("        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
+  printf ("Int_1_Loc:           %d\n", Int_1_Loc);
+  printf ("        should be:   %d\n", 5);
+  printf ("Int_2_Loc:           %d\n", Int_2_Loc);
+  printf ("        should be:   %d\n", 13);
+  printf ("Int_3_Loc:           %d\n", Int_3_Loc);
+  printf ("        should be:   %d\n", 7);
+  printf ("Enum_Loc:            %d\n", Enum_Loc);
+  printf ("        should be:   %d\n", 1);
+  printf ("Str_1_Loc:           %s\n", Str_1_Loc);
+  printf ("        should be:   DHRYSTONE PROGRAM, 1'ST STRING\n");
+  printf ("Str_2_Loc:           %s\n", Str_2_Loc);
+  printf ("        should be:   DHRYSTONE PROGRAM, 2'ND STRING\n");
+  printf ("\n");
+
+  User_Time = End_Time - Begin_Time;
+
+  if (User_Time < Too_Small_Time)
+  {
+    printf ("Measured time too small to obtain meaningful results\n");
+    printf ("Please increase number of runs\n");
+    printf ("\n");
+  }
+  else
+  {
+#if 0
+#ifdef TIME
+    Microseconds = (float) User_Time * Mic_secs_Per_Second
+                        / (float) Number_Of_Runs;
+    Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
+#else
+    Microseconds = (float) User_Time * Mic_secs_Per_Second
+                        / ((float) HZ * ((float) Number_Of_Runs));
+    Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
+                        / (float) User_Time;
+#endif
+#else
+  Microseconds = ((User_Time / Number_Of_Runs) * Mic_secs_Per_Second) / HZ;
+  Dhrystones_Per_Second = (HZ * Number_Of_Runs) / User_Time;
+
+  sc_printf("Number_Of_Runs= %ld, HZ= %ld\n", Number_Of_Runs, HZ);
+  sc_printf("Time: begin= %ld, end= %ld, diff= %ld\n", Begin_Time, End_Time, User_Time);
+  sc_printf("Microseconds for one run through Dhrystone: %ld\n", Microseconds);
+  sc_printf("Dhrystones per Second:                      %ld\n", Dhrystones_Per_Second);
+
+#endif
+  }
+#endif /* SELF_TIMED */
+}
+
+
+void Proc_1 (REG Rec_Pointer Ptr_Val_Par)
+    /* executed once */
+{
+  REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
+                                        /* == Ptr_Glob_Next */
+  /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp,    */
+  /* corresponds to "rename" in Ada, "with" in Pascal           */
+
+  structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
+  Ptr_Val_Par->variant.var_1.Int_Comp = 5;
+  Next_Record->variant.var_1.Int_Comp
+        = Ptr_Val_Par->variant.var_1.Int_Comp;
+  Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
+  Proc_3 (&Next_Record->Ptr_Comp);
+    /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
+                        == Ptr_Glob->Ptr_Comp */
+  if (Next_Record->Discr == Ident_1)
+    /* then, executed */
+  {
+    Next_Record->variant.var_1.Int_Comp = 6;
+    Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
+           &Next_Record->variant.var_1.Enum_Comp);
+    Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
+    Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
+           &Next_Record->variant.var_1.Int_Comp);
+  }
+  else /* not executed */
+    structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
+} /* Proc_1 */
+
+
+void Proc_2 (One_Fifty   *Int_Par_Ref)
+    /* executed once */
+    /* *Int_Par_Ref == 1, becomes 4 */
+{
+  One_Fifty  Int_Loc;
+  Enumeration   Enum_Loc;
+
+  Enum_Loc = 0;
+
+  Int_Loc = *Int_Par_Ref + 10;
+  do /* executed once */
+    if (Ch_1_Glob == 'A')
+      /* then, executed */
+    {
+      Int_Loc -= 1;
+      *Int_Par_Ref = Int_Loc - Int_Glob;
+      Enum_Loc = Ident_1;
+    } /* if */
+  while (Enum_Loc != Ident_1); /* true */
+} /* Proc_2 */
+
+
+void Proc_3 (Rec_Pointer *Ptr_Ref_Par)
+    /* executed once */
+    /* Ptr_Ref_Par becomes Ptr_Glob */
+{
+  if (Ptr_Glob != Null)
+    /* then, executed */
+    *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
+  Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
+} /* Proc_3 */
+
+
+void Proc_4 (void) /* without parameters */
+    /* executed once */
+{
+  Boolean Bool_Loc;
+
+  Bool_Loc = Ch_1_Glob == 'A';
+  Bool_Glob = Bool_Loc | Bool_Glob;
+  Ch_2_Glob = 'B';
+} /* Proc_4 */
+
+void Proc_5 (void) /* without parameters */
+/*******/
+    /* executed once */
+{
+  Ch_1_Glob = 'A';
+  Bool_Glob = false;
+} /* Proc_5 */
+
+
+        /* Procedure for the assignment of structures,          */
+        /* if the C compiler doesn't support this feature       */
+#ifdef  NOSTRUCTASSIGN
+memcpy (d, s, l)
+register char   *d;
+register char   *s;
+register int    l;
+{
+        while (l--) *d++ = *s++;
+}
+#endif
diff --git a/verilog/dv/riscv_regress/tests/benchmarks/dhrystone21/dhry_2.c b/verilog/dv/riscv_regress/tests/benchmarks/dhrystone21/dhry_2.c
new file mode 100644
index 0000000..140161f
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/benchmarks/dhrystone21/dhry_2.c
@@ -0,0 +1,209 @@
+/*****************************************************************************
+ *  The BYTE UNIX Benchmarks - Release 3
+ *          Module: dhry_2.c   SID: 3.4 5/15/91 19:30:22
+ *          
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ *	Ben Smith, Rick Grehan or Tom Yager
+ *	ben@bytepb.byte.com   rick_g@bytepb.byte.com   tyager@bytepb.byte.com
+ *
+ *****************************************************************************
+ *  Modification Log:
+ *  10/22/97 - code cleanup to remove ANSI C compiler warnings
+ *             Andy Kahn <kahn@zk3.dec.com>
+ *
+ *  Adapted from:
+ *
+ *                   "DHRYSTONE" Benchmark Program
+ *                   -----------------------------
+ *
+ * **** WARNING **** See warning in n.dhry_1.c
+ *                                                                            
+ *  Version:    C, Version 2.1
+ *                                                                            
+ *  File:       dhry_2.c (part 3 of 3)
+ *
+ *  Date:       May 25, 1988
+ *
+ *  Author:     Reinhold P. Weicker
+ *
+ ****************************************************************************/
+/* SCCSid is defined in dhry_1.c */
+
+#include <string.h>
+#include "dhry.h"
+
+#ifndef REG
+#define REG
+        /* REG becomes defined as empty */
+        /* i.e. no register variables   */
+#endif
+
+extern  int     Int_Glob;
+extern  char    Ch_1_Glob;
+
+void Proc_6(Enumeration, Enumeration *);
+void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
+void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
+Enumeration Func_1(Capital_Letter, Capital_Letter);
+Boolean Func_2(Str_30, Str_30);
+Boolean Func_3(Enumeration);
+
+void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
+    /* executed once */
+    /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
+{
+  *Enum_Ref_Par = Enum_Val_Par;
+  if (! Func_3 (Enum_Val_Par))
+    /* then, not executed */
+    *Enum_Ref_Par = Ident_4;
+  switch (Enum_Val_Par)
+  {
+    case Ident_1: 
+      *Enum_Ref_Par = Ident_1;
+      break;
+    case Ident_2: 
+      if (Int_Glob > 100)
+        /* then */
+      *Enum_Ref_Par = Ident_1;
+      else *Enum_Ref_Par = Ident_4;
+      break;
+    case Ident_3: /* executed */
+      *Enum_Ref_Par = Ident_2;
+      break;
+    case Ident_4: break;
+    case Ident_5: 
+      *Enum_Ref_Par = Ident_3;
+      break;
+  } /* switch */
+} /* Proc_6 */
+
+void Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
+One_Fifty       Int_1_Par_Val;
+One_Fifty       Int_2_Par_Val;
+One_Fifty      *Int_Par_Ref;
+/**********************************************/
+    /* executed three times                                      */ 
+    /* first call:      Int_1_Par_Val == 2, Int_2_Par_Val == 3,  */
+    /*                  Int_Par_Ref becomes 7                    */
+    /* second call:     Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
+    /*                  Int_Par_Ref becomes 17                   */
+    /* third call:      Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
+    /*                  Int_Par_Ref becomes 18                   */
+{
+  One_Fifty Int_Loc;
+
+  Int_Loc = Int_1_Par_Val + 2;
+  *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
+} /* Proc_7 */
+
+
+void Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
+/*********************************************************************/
+    /* executed once      */
+    /* Int_Par_Val_1 == 3 */
+    /* Int_Par_Val_2 == 7 */
+Arr_1_Dim       Arr_1_Par_Ref;
+Arr_2_Dim       Arr_2_Par_Ref;
+int             Int_1_Par_Val;
+int             Int_2_Par_Val;
+{
+  REG One_Fifty Int_Index;
+  REG One_Fifty Int_Loc;
+
+  Int_Loc = Int_1_Par_Val + 5;
+  Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
+  Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
+  Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
+  for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
+    Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
+  Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
+  Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
+  Int_Glob = 5;
+} /* Proc_8 */
+
+
+Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val)
+/*************************************************/
+    /* executed three times                                         */
+    /* first call:      Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R'    */
+    /* second call:     Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C'    */
+    /* third call:      Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C'    */
+{
+  Capital_Letter        Ch_1_Loc;
+  Capital_Letter        Ch_2_Loc;
+
+  Ch_1_Loc = Ch_1_Par_Val;
+  Ch_2_Loc = Ch_1_Loc;
+  if (Ch_2_Loc != Ch_2_Par_Val)
+    /* then, executed */
+    return (Ident_1);
+  else  /* not executed */
+  {
+    Ch_1_Glob = Ch_1_Loc;
+    return (Ident_2);
+   }
+} /* Func_1 */
+
+
+
+Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
+/*************************************************/
+    /* executed once */
+    /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
+    /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
+
+Str_30  Str_1_Par_Ref;
+Str_30  Str_2_Par_Ref;
+{
+  REG One_Thirty        Int_Loc;
+      Capital_Letter    Ch_Loc;
+
+  Ch_Loc = 'A';
+  Int_Loc = 2;
+  while (Int_Loc <= 2) /* loop body executed once */
+    if (Func_1 (Str_1_Par_Ref[Int_Loc],
+                Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
+      /* then, executed */
+    {
+      Ch_Loc = 'A';
+      Int_Loc += 1;
+    } /* if, while */
+  if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
+    /* then, not executed */
+    Int_Loc = 7;
+  if (Ch_Loc == 'R')
+    /* then, not executed */
+    return (true);
+  else /* executed */
+  {
+    if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
+      /* then, not executed */
+    {
+      Int_Loc += 7;
+      Int_Glob = Int_Loc;
+      return (true);
+    }
+    else /* executed */
+      return (false);
+  } /* if Ch_Loc */
+} /* Func_2 */
+
+
+Boolean Func_3 (Enum_Par_Val)
+/***************************/
+    /* executed once        */
+    /* Enum_Par_Val == Ident_3 */
+Enumeration Enum_Par_Val;
+{
+  Enumeration Enum_Loc;
+
+  Enum_Loc = Enum_Par_Val;
+  if (Enum_Loc == Ident_3)
+    /* then, executed */
+    return (true);
+  else /* not executed */
+    return (false);
+} /* Func_3 */
+
diff --git a/verilog/dv/riscv_regress/tests/hello/Makefile b/verilog/dv/riscv_regress/tests/hello/Makefile
new file mode 100644
index 0000000..0f55d60
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/hello/Makefile
@@ -0,0 +1,13 @@
+src_dir := $(dir $(lastword $(MAKEFILE_LIST)))
+
+c_src := sc_print.c hello.c
+
+include $(inc_dir)/common.mk
+
+default: log_requested_tgt $(bld_dir)/hello.elf $(bld_dir)/hello.hex $(bld_dir)/hello.dump
+
+log_requested_tgt:
+	echo hello.hex>> $(bld_dir)/test_info
+
+clean:
+	$(RM) $(c_objs) $(asm_objs) $(bld_dir)/hello.elf $(bld_dir)/hello.hex $(bld_dir)/hello.dump
\ No newline at end of file
diff --git a/verilog/dv/riscv_regress/tests/hello/hello.c b/verilog/dv/riscv_regress/tests/hello/hello.c
new file mode 100644
index 0000000..af5c6e3
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/hello/hello.c
@@ -0,0 +1,7 @@
+#include "sc_print.h"
+
+int main()
+{
+    sc_printf("Hello from YCR1!\n");
+    return 0;
+}
diff --git a/verilog/dv/riscv_regress/tests/isr_sample/Makefile b/verilog/dv/riscv_regress/tests/isr_sample/Makefile
new file mode 100644
index 0000000..1c95e74
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/isr_sample/Makefile
@@ -0,0 +1,26 @@
+src_dir := $(dir $(lastword $(MAKEFILE_LIST)))
+
+LDFLAGS := -nostartfiles -nostdlib -march=rv32$(ARCH) -mabi=$(ABI)
+ADD_ASM_MACRO := -DASM
+
+ifeq ($(IPIC) ,1)
+    ADD_ASM_MACRO += -DIPIC_ENABLED
+endif
+
+ifeq ($(VECT_IRQ) ,1)
+    ADD_ASM_MACRO += -DVECT_IRQ_ENABLED
+endif
+asm_src := isr_sample.S
+
+# override ld script
+ld_script := $(inc_dir)/link.ld
+
+include $(inc_dir)/common.mk
+
+default: log_requested_tgt $(bld_dir)/isr_sample.elf $(bld_dir)/isr_sample.hex $(bld_dir)/isr_sample.dump
+
+log_requested_tgt:
+	echo isr_sample.hex >> $(bld_dir)/test_info
+
+clean:
+	$(RM)$(asm_objs) $(bld_dir)/isr_sample.elf $(bld_dir)/isr_sample.hex $(bld_dir)/isr_sample.dump
\ No newline at end of file
diff --git a/verilog/dv/riscv_regress/tests/isr_sample/isr_sample.S b/verilog/dv/riscv_regress/tests/isr_sample/isr_sample.S
new file mode 100644
index 0000000..d7b3d63
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/isr_sample/isr_sample.S
@@ -0,0 +1,291 @@
+#include "riscv_macros.h"
+#include "sc_test.h"
+
+.altmacro
+// global interrupt bit
+#define MSIE                        (1 << IRQ_M_SOFT)       //machine software interrupt enable
+#define MTIE                        (1 << IRQ_M_TIMER)      //machine timer interrupt enable
+#define MEIE                        (1 << IRQ_M_EXT)        //machine external interrupt enable
+#define MCAUSE_EXT_IRQ              (1 << 31 | IRQ_M_EXT)
+#define MCAUSE_SOFT_IRQ             (1 << 31 | IRQ_M_SOFT)
+#define MCAUSE_TMR_IRQ              (1 << 31 | IRQ_M_TIMER)
+
+// IPIC
+#define IRQ_LINES_ADDR              0x10020018      // simulation
+#define TRIG_EXT_IRQ_ADDR           0x10020018      // external irq is triggered when tb memory is set to non-zero // Bit [15:0]
+#define TRIG_SW_IRQ_ADDR            0x10020018      // software irq is triggered when tb memory is set to non-zero // Bit [16]
+
+#define IPIC_EOI                    0xBF4           // end of interrupt
+#define IPIC_SOI                    0xBF5           // start of interrupt
+#define IPIC_IDX                    0xBF6           // index register
+#define IPIC_ICSR                   0xBF7           // interrupt control status register
+
+// IPIC Interrupt Constrol Status Register
+#define IPIC_ICSR_IP                (1 << 0)        // interrupt pending
+#define IPIC_ICSR_IE                (1 << 1)        // interrupt enable
+#define IPIC_ICSR_IM                (1 << 2)        // interrupt mode (0/1: level/edge)
+#define IPIC_ICSR_INV               (1 << 3)        // line inversion
+#define IPIC_ICSR_IS                (1 << 4)        // in service
+
+//  Interrupt lines in use 
+#define IPIC_IRQ_LINE9              9
+#define EXT_IRQ_LINE_COMMON         0
+
+#include "timer.h"
+#include "reloc.h"
+
+.macro jmp_sc_exit
+    la  t0, sc_exit
+    jr  t0
+.endm
+
+    .section .text.init
+    .option norvc
+    .globl _start
+//  -----------------------------------------------------------------
+// Trap handlers
+// 0xXXXXXX00
+    .option norvc
+.org (64*3)
+
+//0xXXXXXXC0
+    .balign 64
+machine_trap_entry:
+vec_usr_soft:
+#ifdef VECT_IRQ_ENABLED
+    trap_entry:
+        j    _trap_fail
+    vec_supervisor_soft:
+        j    _trap_fail
+    vec_reserved1:
+        j    _trap_fail
+    vec_machine_soft:
+        j    vec_machine_soft_handler
+    vec_usr_tmr:
+        j    _trap_fail
+    vec_supervisor_tmr:
+        j    _trap_fail
+    vec_reserved2:
+        j    _trap_fail
+    vec_machine_tmr:
+        j    vec_machine_tmr_handler
+    vec_usr_ext:
+        j    _trap_fail
+    vec_supervisor_ext:
+        j    _trap_fail
+    vec_reserved3:
+        j    _trap_fail
+    vec_machine_ext:
+        j    vec_machine_ext_handler
+    vec_reserved4:
+        j    _trap_fail
+        j    _trap_fail
+        j    _trap_fail
+        j    _trap_fail
+#else
+    trap_entry:
+        j    direct_irq_handler
+    vec_supervisor_soft:
+        j    _trap_fail
+    vec_reserved1:
+        j    _trap_fail
+    vec_machine_soft:
+        j    _trap_fail
+    vec_usr_tmr:
+        j    _trap_fail
+    vec_supervisor_tmr:
+        j    _trap_fail
+    vec_reserved2:
+        j    _trap_fail
+    vec_machine_tmr:
+        j    _trap_fail
+    vec_usr_ext:
+        j    _trap_fail
+    vec_supervisor_ext:
+        j    _trap_fail
+    vec_reserved3:
+        j    _trap_fail
+    vec_machine_ext:
+        j    _trap_fail
+    vec_reserved4:
+        j    _trap_fail
+        j    _trap_fail
+        j    _trap_fail
+        j    _trap_fail
+
+#endif // ifdef VECT_IRQ_ENABLED
+
+
+    .balign 64
+_start:
+    la                  t0, machine_trap_entry
+    csrw                mtvec, t0
+
+    la                  t0,  test_start
+    jr                  (t0)
+
+//  -----------------------------------------------------------------
+    .option norvc
+    .balign 64
+test_start:
+    
+    la                  t0, trap_entry
+    csrw                mtvec, t0                          // set mtvec to trap_entry
+    #ifdef VECT_IRQ_ENABLED
+        csrsi               mtvec, 1                       // set vectored mode
+    #else
+        csrsi               mtvec, 0                       // set direct mode
+    #endif
+
+    /// configuring timer interrupt /// 
+    _reset_mtimecmp;                                   // reset timer
+    _run_timer;                                        // run timer
+    csrs                mstatus, MSTATUS_MIE           // enable global interrupt
+    li                  a0, MTIE                       
+    csrs                mie, a0                        // enable timer interrupt
+    li                  t2, 0                          // reset timer counter = 0 (updated in isr)
+    _read_mtime         s1                             // read timer value
+    addi                s1, s1, 256
+    _write_mtimecmp_32  s1 
+    wfi  
+
+
+   /// configuring external interrupt /// 
+    csrw                mie, zero                      // disable all interrupts
+    li                  t0, IRQ_LINES_ADDR
+    sh                  zero, (t0)                     // set all exterinal interrupt lines low
+    #ifdef IPIC_ENABLED
+        li                  t0, IPIC_IRQ_LINE9
+        csrw                IPIC_IDX, t0               // set IPIC to expect interupt on line 9...
+        li                  t0, (IPIC_ICSR_IE | IPIC_ICSR_IM)
+        csrw                IPIC_ICSR, t0              //  ....enable interrupt,set edge interrupt mode
+    #endif
+    li                  t0, MEIE
+    csrs                mie, t0                        // enable external interrupt 
+    li                  t0, TRIG_EXT_IRQ_ADDR
+    #ifdef IPIC_ENABLED          
+        li                  t1, (1 << IPIC_IRQ_LINE9)
+    #else
+        li                  t1, (1 << EXT_IRQ_LINE_COMMON)
+    #endif
+    sh                  t1, (t0)                       //send command to generate external interrupt on line 9 to testbench
+    nop
+    nop
+    nop
+    nop                                                //wait for external interrupt
+
+
+    /// configuring software interrupt /// 
+    csrw                mie, zero                      // disable all interrupts
+    li                  t0, TRIG_SW_IRQ_ADDR
+    li                  t1, 0x00010000                 // Soft ireq bit [16] 
+    sw                  t1, (t0)                       //send command to generate software interrupt 
+    li                  t0, MSIE
+    csrs                mie, t0                        // enable software interrupt 
+    nop
+    nop
+    nop
+    nop                                                //wait for software interrupt
+
+    li                  s1, 3
+    li                  a0, 0
+    beq                 t2, s1, 1f
+    li                  a0, -1
+1:
+    jmp_sc_exit
+
+
+#ifndef VECT_IRQ_ENABLED
+
+direct_irq_handler:
+    csrr            a1, mcause
+    li              a5, MCAUSE_TMR_IRQ      //0x80000007 -- mcause = tmr.irq
+    beq             a1, a5, vec_machine_tmr_handler
+    li              a5, MCAUSE_SOFT_IRQ     //0x80000003 -- mcause = soft.irq
+    beq             a1, a5, vec_machine_soft_handler
+    li              a5, MCAUSE_EXT_IRQ      //0x8000000B -- mcause = ext.irq
+    beq             a1, a5, vec_machine_ext_handler
+    mret
+#endif
+
+vec_machine_tmr_handler:
+    csrr            a1, mcause
+    li              a5, MCAUSE_TMR_IRQ      //0x80000007 -- mcause = tmr.irq
+    li              a0, -1
+    bne             a1, a5, check_fail
+    csrr            t1, mip
+    li              t0, MIP_MTIP
+    and             t0, t1, t0
+    beqz            t0, check_fail
+#ifdef IPIC_ENABLED
+    csrw            IPIC_SOI, zero
+    csrw            IPIC_EOI, zero
+#endif
+    _reset_mtimecmp
+    csrr            t1, mip
+    andi            t1, t1, MIP_MTIP
+    bne             t1, zero, check_fail
+    addi            t2, t2, 1               // tmr irq counter update
+    mret
+
+vec_machine_ext_handler:
+
+    csrr            a1, mcause
+    li              a5, MCAUSE_EXT_IRQ      //0x8000000B -- mcause = ext.irq
+    li              a0, -1
+    bne             a1, a5, check_fail
+    csrr            t1, mip
+    li              t0, MIP_MEIP
+    and             t0, t1, t0
+    beqz            t0, check_fail
+#ifdef IPIC_ENABLED
+    csrw            IPIC_SOI, zero
+    csrw            IPIC_EOI, zero
+#endif
+    li                  t0, MEIE
+    csrc                mie, t0             // disable software interrupt 
+
+    li              t0, TRIG_EXT_IRQ_ADDR
+    li              t1, EXT_IRQ_LINE_COMMON         
+    sh              t1, (t0)                // send command to disable external interrupt 
+     
+    csrr            t1, mip
+    li              t0, MIP_MEIP
+    bne             t1, zero, check_fail
+    addi            t2, t2, 1               // ext irq counter update
+    mret
+
+vec_machine_soft_handler:
+    csrr            a1, mcause
+    li              a5, MCAUSE_SOFT_IRQ     //0x80000003 -- mcause = soft.irq
+    li              a0, -1
+    bne             a1, a5, check_fail
+    csrr            t1, mip
+    li              t0, MIP_MSIP
+    and             t0, t1, t0
+    beqz            t0, check_fail
+    #ifdef IPIC_ENABLED
+       csrw         IPIC_SOI, zero
+       csrw         IPIC_EOI, zero
+    #endif
+    li              t0, MSIE
+    csrc            mie, t0                 // disable software interrupt 
+    li              t0, TRIG_SW_IRQ_ADDR
+    li              t1, 0x00000000
+    sw              t1, (t0)                // send command to stop generating  software interrupt 
+    li              t0, MIP_MSIP
+    csrc            mip, t0
+    csrr            t1, mip
+    li              t0, MIP_MSIP
+    and             t1, t1, t0
+    bne             t1, zero, check_fail
+    addi            t2, t2, 1               // ext irq counter update
+    mret
+
+check_fail:
+    la              t0, sc_exit
+    jr              t0
+
+_trap_fail:
+    li              a0, -1
+    j               check_fail
diff --git a/verilog/dv/riscv_regress/tests/isr_sample/timer.h b/verilog/dv/riscv_regress/tests/isr_sample/timer.h
new file mode 100644
index 0000000..827b849
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/isr_sample/timer.h
@@ -0,0 +1,97 @@
+#ifndef __TIMER__H
+#define __TIMER__H
+
+
+
+#define MEM_MTIME_MASK  0xF0000000
+#define MEM_MTIME_CTRL  0x0C490000
+#define MEM_MTIME_DIV   0x0C490004
+#define MEM_MTIME       0x0C490008
+#define MEM_MTIMEH      0x0C49000C
+#define MEM_MTIMECMP    0x0C490010
+#define MEM_MTIMECMPH   0x0C490014
+
+#define TMP   t0
+#define TMP2  t1
+#define TMP3  t2
+
+// Reset
+.macro _reset_mtime
+    li          TMP, MEM_MTIME
+    sw          zero, 0(TMP)
+    sw          zero, 4(TMP)
+.endm
+
+.macro _reset_mtimecmp
+    li          TMP, MEM_MTIMECMP
+    not         TMP2, zero
+    sw          TMP2, 0(TMP)
+    sw          TMP2, 4(TMP)
+.endm
+
+// Write
+.macro _write_mtime_ctrl reg
+    li          TMP, MEM_MTIME_CTRL
+    sw          \reg, 0(TMP)
+.endm
+
+.macro _write_mtime_div reg
+    li          TMP, MEM_MTIME_DIV
+    sw          \reg, 0(TMP)
+.endm
+
+.macro _write_mtimecmp_32 reg
+    li          TMP, MEM_MTIMECMP
+    li          TMP2, -1
+    sw          TMP2, 0(TMP)
+    sw          zero, 4(TMP)
+    sw          \reg, 0(TMP)
+.endm
+
+.macro _write_mtime reg
+    li          TMP, MEM_MTIME
+    sw          \reg, 0(TMP)
+.endm
+
+.macro _read_mtime reg
+    li          TMP, MEM_MTIME
+    lw          \reg, 0(TMP)
+.endm
+
+// Read
+.macro _read_mtimecmp reg
+    li          TMP, MEM_MTIMECMP
+    lw          \reg, 0(TMP)
+.endm
+
+.macro _read_mtime_ctrl reg
+    li          TMP, MEM_MTIME_CTRL
+    lw          \reg, 0(TMP)
+.endm
+
+.macro _read_mtime_div reg
+    li          TMP, MEM_MTIME_DIV
+    lw          \reg, 0(TMP)
+.endm
+
+// Misc
+.macro _run_timer
+    li          TMP, MEM_MTIME_CTRL
+    lw          TMP2, 0(TMP)
+    li          TMP3, (1 << YCR1_MTIME_CTRL_EN)
+    or          TMP2, TMP2, TMP3
+    sw          TMP2, 0(TMP)
+.endm
+
+.macro _stop_timer
+    li          TMP, MEM_MTIME_CTRL
+    lw          TMP2, 0(TMP)
+    li          TMP3, (1 << YCR1_MTIME_CTRL_EN)
+    not         TMP3, TMP3
+    and         TMP2, TMP2, TMP3
+    sw          TMP2, 0(TMP)
+.endm
+
+
+
+#endif // #ifndef __TIMER__H
diff --git a/verilog/dv/riscv_regress/tests/riscv_compliance/Makefile b/verilog/dv/riscv_regress/tests/riscv_compliance/Makefile
new file mode 100644
index 0000000..98f3d5f
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/riscv_compliance/Makefile
@@ -0,0 +1,200 @@
+## @file
+##  YCR* tests
+##
+##
+
+ARCH ?=im
+override ARCH:=rv32$(ARCH)
+
+src_dir       := $(CURDIR)
+RISCV_COMPLIANCE_TESTS := $(src_dir)/../../dependencies/riscv-compliance/
+
+#I IM IMC IC
+#EM EMC EC
+
+ifeq (rv32e,$(findstring rv32e,$(ARCH)))
+    $(info >>> RV32E - no compliance tests)
+else ## ifdef YCR_BASE_RVE_EXT
+  #ifeq (rv32i,$(findstring rv32i,$(ARCH)))
+  ifeq ($(ARCH),$(filter $(ARCH),rv32i rv32im rv32imc rv32ic))
+    $(info >>> I32 TESTS)
+    included_i += $(filter %.S,\
+                        $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32i/src/*))
+	included_i += $(filter %.S,\
+                        $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32Zicsr/src/*))
+	included_i += $(filter %.S,\
+                        $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32Zifencei/src/*))
+    compliance_set += $(included_i)
+  endif
+
+  #$(if or ifeq(rv32im,$(findstring rv32im,$(ARCH))), (rv32imc,$(findstring rv32imc,$(ARCH))))
+  ifeq ($(ARCH),$(filter $(ARCH), rv32im rv32imc))
+    $(info >>> IM32 TESTS)
+    included_im += $(filter %.S,\
+                        $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32im/src/*))
+    compliance_set += $(included_im)
+  endif ##
+
+  ifeq (rv32imc,$(findstring rv32imc,$(ARCH)))
+    $(info >>> IMC32 TESTS)
+    included_imc += $(filter %.S,\
+                        $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32imc/src/*))
+    compliance_set += $(included_imc)
+  endif ## ifeq (rv32imc,$(findstring rv32imc,$(ARCH)))
+  ifeq (rv32ic,$(findstring rv32ic,$(ARCH)))
+  endif
+endif ##
+
+
+$(info >>>$(ARCH) set included)
+
+ifeq ($(compliance_set),)
+$(info >>> No compliance tests included)
+endif
+
+$(info >>>>> compliance set: $(compliance_set))
+
+dst_dir       := $(bld_dir)
+test_name     := riscv_compliance
+bld_dir       := $(addprefix $(dst_dir)/, $(test_name))
+obj_dir       := $(bld_dir)/riscv_compliance_objs
+
+#cut_list      += scall csr shamt simple
+cut_list += I-MISALIGN_JMP-01 I-MISALIGN_LDST-01 I-EBREAK-01 I-ECALL-01
+reference_src += $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32i*/*/*.reference_output)
+reference_src += $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32Zi*/*/*.reference_output)
+testnames     := $(basename $(notdir $(compliance_set)))
+filtered      := $(filter-out $(cut_list),$(testnames))
+objs          := $(addprefix $(bld_dir)/,$(filtered:%=%.o))
+test_elf      := $(addprefix $(dst_dir)/compliance_,$(filtered:%=%.elf))
+test_hex      := $(addprefix $(dst_dir)/compliance_,$(filtered:%=%.hex))
+test_dump     := $(addprefix $(bld_dir)/compliance_,$(filtered:%=%.dump))
+
+compliance_macros_file := $(root_dir)/tests/riscv_compliance/compliance_io.h
+compliance_output ?= true
+
+testnames_i     := $(basename $(notdir $(included_i)))
+testnames_im     := $(basename $(notdir $(included_im)))
+testnames_imc     := $(basename $(notdir $(included_imc)))
+filtered_i      := $(filter-out $(cut_list),$(testnames_i))
+filtered_im      := $(filter-out $(cut_list),$(testnames_im))
+filtered_imc      := $(filter-out $(cut_list),$(testnames_imc))
+
+# ARCH_FLAGS := -Wa,-march=rv32im -march=rv32im
+# ARCH_FLAGS_C := -Wa,-march=rv32imc -march=rv32imc
+CFLAGS := -I$(inc_dir) -I$(src_dir) -DASM -mabi=ilp32 -D__riscv_xlen=32 -w
+LDFLAGS := -static -fvisibility=hidden -nostdlib -nostartfiles -T$(inc_dir)/link.ld -march=$(ARCH) -mabi=ilp32
+GCCVERSIONGT7 := $(shell expr `$(RISCV_GCC) -dumpfullversion | cut -f1 -d'.'` \> 7)
+ifeq "$(GCCVERSIONGT7)" "1"
+	LDFLAGS += -mno-relax
+endif
+VPATH += $(src_dir) $(bld_dir) $(obj_dir) $(asm_path) $(ref_path) $(RISCV_COMPLIANCE_TESTS)
+
+ifeq ($(compliance_output), true)
+CFLAGS += -D_COMPLIANCE_OUTPUT
+endif
+
+default: clean log_requested_tgt check_version cp_asm ref_data $(test_elf) $(test_hex) $(test_dump)
+
+define compile_template
+$(obj_dir)/$(1).o: $(obj_dir) cp_asm
+	$(RISCV_GCC) -c $$(bld_dir)/compliance_asm/$(1).S $$(CFLAGS) -Wa,$(2) $(2) -o $$@
+endef
+
+define preprocessing
+for test_asm in $(1); do                                                  \
+march_tmp=$$test_asm ;                                                    \
+march_tmp=$${march_tmp%/src*} ;                                           \
+march_tmp=$$(basename $$march_tmp) ;                                      \
+file_name="$$(basename $${test_asm})" ;                                   \
+$(RISCV_GCC) $(CFLAGS) -Wa,$(2) $(2) -E $$test_asm                        \
+-o $(bld_dir)/compliance_asm/$$file_name ;                                \
+done
+endef
+
+$(foreach SRC,$(filtered_i),$(eval $(call compile_template,$(SRC),-march=rv32i)))
+$(foreach SRC,$(filtered_im),$(eval $(call compile_template,$(SRC),-march=rv32im)))
+$(foreach SRC,$(filtered_imc),$(eval $(call compile_template,$(SRC),-march=rv32imc)))
+
+
+log_requested_tgt: $(bld_dir)
+	$(foreach test_name, $(filtered), $(eval $(shell echo compliance_$(test_name).hex >> $(bld_dir)/../test_info)))
+
+$(bld_dir) :
+	mkdir -p $(bld_dir)
+
+$(obj_dir) : | ref_data
+	mkdir -p $(obj_dir)
+
+$(dst_dir)/compliance_%.elf: $(obj_dir)/%.o | $(dep_files)
+	$(RISCV_GCC) $^ $(LDFLAGS) -o $@ -g
+
+$(dst_dir)/compliance_%.hex: $(dst_dir)/compliance_%.elf
+	$(RISCV_ROM_OBJCOPY) $^ $@
+	$(RISCV_RAM_OBJCOPY) $^ $@.ram
+	#assign 0x0800_0xxx  to 0x0000_0xxx to map to TCM Memory
+	sed -i 's/@08000/@00000/g' $@.ram
+
+$(bld_dir)/compliance_%.dump: $(dst_dir)/compliance_%.elf
+	$(RISCV_OBJDUMP) -D -w -x -S $^ > $@
+
+ref_data:
+	mkdir -p $(bld_dir)/ref_data
+	for files in $(reference_src) ; do \
+	sed_input=$$files ; \
+	sed_output=$$(basename $${files%.*}) ; \
+	sed "s/\r$$//; \
+	s/\(........\)/\1,/g; \
+	s/.$$//; s/\(.*\),\(.*\),\(.*\),\(.*\)/\4,\3,\2,\1/; \
+	s/\(.........\)/\10x/g; s/^/0x/; s/$$/,/; $$ s/.$$//" $$sed_input > $(bld_dir)/ref_data/$$sed_output; \
+	done
+
+cp_asm:
+	mkdir -p $(bld_dir)/compliance_asm
+	$(call preprocessing,$(included_i),-march=rv32i)
+	$(call preprocessing,$(included_im),-march=rv32im)
+	$(call preprocessing,$(included_imc),-march=rv32imc)
+
+
+riscv_compliance_tests_dir    := $(if $(RISCV_COMPLIANCE_TESTS), $(RISCV_COMPLIANCE_TESTS), ./undefined)
+riscv_tests_commit := d51259b2a949be3af02e776c39e135402675ac9b
+## commit hash readed from local copy of https://github.com/riscv/riscv-compliance
+tmp_commit = $(shell cd $(riscv_compliance_tests_dir) 2>/dev/null && git log -1 | grep "commit" | cut -f2 -d ' ')
+is_commit_good = $(if $(subst $(riscv_tests_commit),,$(tmp_commit)),false,true)
+
+# Color
+RED=\033[0;31m
+NC=\033[0m
+
+check_version : $(riscv_compliance_tests_dir)
+	@if [ ! -d $(riscv_compliance_tests_dir) ]; then \
+		echo -e "$(RED)==========================================================================" &&\
+		echo "   Error! Environment variable RISCV_COMPLIANCE_TESTS='$(riscv_compliance_tests_dir)' " &&\
+		echo "      directory not exist!" && \
+		echo "==========================================================================$(NC)" ; \
+	fi
+ifneq ($(is_commit_good),true)
+	@echo -e "$(RED)=========================================================================="
+	@echo "   Warning! Execution of test code is not guaranteed "
+	@echo "   while using the current commit of repository located at : $(riscv_compliance_tests_dir) ."
+	@echo "   "
+	@echo "   riscv_compliance repository must point to commit $(riscv_tests_commit)!"
+	@echo -e "==========================================================================$(NC)"
+endif
+
+$(riscv_compliance_tests_dir) :.
+ifndef RISCV_COMPLIANCE_TESTS
+	@echo -e "$(RED)=========================================================================="
+	@echo "    Error! Environment variable RISCV_COMPLIANCE_TESTS not set!"
+	@echo "    You must set the environment variable RISCV_COMPLIANCE_TESTS"
+	@echo "    The variable should point to the local copy of the"
+	@echo "      repository https://github.com/riscv/riscv-compliance"
+	@echo "      with the commit $(riscv_tests_commit)"
+	@echo -e "==========================================================================$(NC)"
+	exit 1
+endif
+
+clean:
+	$(RM) -R $(test_elf) $(test_hex) $(bld_dir)
+
+.PHONY: check_version clean ref_data cp_asm default
diff --git a/verilog/dv/riscv_regress/tests/riscv_compliance/aw_test_macros.h b/verilog/dv/riscv_regress/tests/riscv_compliance/aw_test_macros.h
new file mode 100644
index 0000000..3e052a1
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/riscv_compliance/aw_test_macros.h
@@ -0,0 +1,683 @@
+/*
+  COPY OF /riscv-compliance/riscv-test-env/aw_test_macros.h
+  */
+
+// See LICENSE for license details.
+
+#ifndef __TEST_MACROS_SCALAR_H
+#define __TEST_MACROS_SCALAR_H
+
+
+#-----------------------------------------------------------------------
+# Helper macros
+#-----------------------------------------------------------------------
+
+#define MASK_XLEN(x) ((x) & ((1 << (__riscv_xlen - 1) << 1) - 1))
+
+#define CHECK_XLEN li a0, 1; slli a0, a0, 31; bltz a0, 1f; RVTEST_PASS; 1: srli a0, a0, 31; la t0, begin_signature; sw a0, 0(t0)
+
+#define TESTNUM gp
+
+#define SWSIG( testnum, testreg ) \
+    la  x28, test_res; \
+    sw testreg, (testnum<<2)(x28); \
+
+#
+# Address = base+(testnum<<2)
+# sw testreg, (testnum<<2)(basereg)
+#
+#define TEST_CASE( testnum, testreg, correctval, code... ) \
+test_ ## testnum: \
+    code; \
+    li  x29, MASK_XLEN(correctval); \
+    li  TESTNUM, testnum; \
+        SWSIG(testnum,testreg); \
+    bne testreg, x29, fail;
+
+# We use a macro hack to simpify code generation for various numbers
+# of bubble cycles.
+
+#define TEST_INSERT_NOPS_0
+#define TEST_INSERT_NOPS_1  nop; TEST_INSERT_NOPS_0
+#define TEST_INSERT_NOPS_2  nop; TEST_INSERT_NOPS_1
+#define TEST_INSERT_NOPS_3  nop; TEST_INSERT_NOPS_2
+#define TEST_INSERT_NOPS_4  nop; TEST_INSERT_NOPS_3
+#define TEST_INSERT_NOPS_5  nop; TEST_INSERT_NOPS_4
+#define TEST_INSERT_NOPS_6  nop; TEST_INSERT_NOPS_5
+#define TEST_INSERT_NOPS_7  nop; TEST_INSERT_NOPS_6
+#define TEST_INSERT_NOPS_8  nop; TEST_INSERT_NOPS_7
+#define TEST_INSERT_NOPS_9  nop; TEST_INSERT_NOPS_8
+#define TEST_INSERT_NOPS_10 nop; TEST_INSERT_NOPS_9
+
+
+#-----------------------------------------------------------------------
+# RV64UI MACROS
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# Tests for instructions with immediate operand
+#-----------------------------------------------------------------------
+
+#define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11))
+
+#define TEST_IMM_OP( testnum, inst, result, val1, imm ) \
+    TEST_CASE( testnum, x30, result, \
+      li  x1, MASK_XLEN(val1); \
+      inst x30, x1, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_SRC1_EQ_DEST( testnum, inst, result, val1, imm ) \
+    TEST_CASE( testnum, x1, result, \
+      li  x1, MASK_XLEN(val1); \
+      inst x1, x1, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \
+    TEST_CASE( testnum, x6, result, \
+      li  x4, 0; \
+1:    li  x1, MASK_XLEN(val1); \
+      inst x30, x1, SEXT_IMM(imm); \
+      TEST_INSERT_NOPS_ ## nop_cycles \
+      addi  x6, x30, 0; \
+      addi  x4, x4, 1; \
+      li  x5, 2; \
+      bne x4, x5, 1b \
+    )
+
+#define TEST_IMM_SRC1_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \
+    TEST_CASE( testnum, x30, result, \
+      li  x4, 0; \
+1:    li  x1, MASK_XLEN(val1); \
+      TEST_INSERT_NOPS_ ## nop_cycles \
+      inst x30, x1, SEXT_IMM(imm); \
+      addi  x4, x4, 1; \
+      li  x5, 2; \
+      bne x4, x5, 1b \
+    )
+
+#define TEST_IMM_ZEROSRC1( testnum, inst, result, imm ) \
+    TEST_CASE( testnum, x1, result, \
+      inst x1, x0, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_ZERODEST( testnum, inst, val1, imm ) \
+    TEST_CASE( testnum, x0, 0, \
+      li  x1, MASK_XLEN(val1); \
+      inst x0, x1, SEXT_IMM(imm); \
+    )
+
+#-----------------------------------------------------------------------
+# Tests for an instruction with register operands
+#-----------------------------------------------------------------------
+
+#define TEST_R_OP( testnum, inst, result, val1 ) \
+    TEST_CASE( testnum, x30, result, \
+      li  x1, val1; \
+      inst x30, x1; \
+    )
+
+#define TEST_R_SRC1_EQ_DEST( testnum, inst, result, val1 ) \
+    TEST_CASE( testnum, x1, result, \
+      li  x1, val1; \
+      inst x1, x1; \
+    )
+
+#define TEST_R_DEST_BYPASS( testnum, nop_cycles, inst, result, val1 ) \
+    TEST_CASE( testnum, x6, result, \
+      li  x4, 0; \
+1:    li  x1, val1; \
+      inst x30, x1; \
+      TEST_INSERT_NOPS_ ## nop_cycles \
+      addi  x6, x30, 0; \
+      addi  x4, x4, 1; \
+      li  x5, 2; \
+      bne x4, x5, 1b \
+    )
+
+#-----------------------------------------------------------------------
+# Tests for an instruction with register-register operands
+#-----------------------------------------------------------------------
+
+#define TEST_RR_OP( testnum, inst, result, val1, val2 ) \
+    TEST_CASE( testnum, x30, result, \
+      li  x1, MASK_XLEN(val1); \
+      li  x2, MASK_XLEN(val2); \
+      inst x30, x1, x2; \
+    )
+
+#define TEST_RR_SRC1_EQ_DEST( testnum, inst, result, val1, val2 ) \
+    TEST_CASE( testnum, x1, result, \
+      li  x1, MASK_XLEN(val1); \
+      li  x2, MASK_XLEN(val2); \
+      inst x1, x1, x2; \
+    )
+
+#define TEST_RR_SRC2_EQ_DEST( testnum, inst, result, val1, val2 ) \
+    TEST_CASE( testnum, x2, result, \
+      li  x1, MASK_XLEN(val1); \
+      li  x2, MASK_XLEN(val2); \
+      inst x2, x1, x2; \
+    )
+
+#define TEST_RR_SRC12_EQ_DEST( testnum, inst, result, val1 ) \
+    TEST_CASE( testnum, x1, result, \
+      li  x1, MASK_XLEN(val1); \
+      inst x1, x1, x1; \
+    )
+
+#define TEST_RR_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, val2 ) \
+    TEST_CASE( testnum, x6, result, \
+      li  x4, 0; \
+1:    li  x1, MASK_XLEN(val1); \
+      li  x2, MASK_XLEN(val2); \
+      inst x30, x1, x2; \
+      TEST_INSERT_NOPS_ ## nop_cycles \
+      addi  x6, x30, 0; \
+      addi  x4, x4, 1; \
+      li  x5, 2; \
+      bne x4, x5, 1b \
+    )
+
+#define TEST_RR_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \
+    TEST_CASE( testnum, x30, result, \
+      li  x4, 0; \
+1:    li  x1, MASK_XLEN(val1); \
+      TEST_INSERT_NOPS_ ## src1_nops \
+      li  x2, MASK_XLEN(val2); \
+      TEST_INSERT_NOPS_ ## src2_nops \
+      inst x30, x1, x2; \
+      addi  x4, x4, 1; \
+      li  x5, 2; \
+      bne x4, x5, 1b \
+    )
+
+#define TEST_RR_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \
+    TEST_CASE( testnum, x30, result, \
+      li  x4, 0; \
+1:    li  x2, MASK_XLEN(val2); \
+      TEST_INSERT_NOPS_ ## src1_nops \
+      li  x1, MASK_XLEN(val1); \
+      TEST_INSERT_NOPS_ ## src2_nops \
+      inst x30, x1, x2; \
+      addi  x4, x4, 1; \
+      li  x5, 2; \
+      bne x4, x5, 1b \
+    )
+
+#define TEST_RR_ZEROSRC1( testnum, inst, result, val ) \
+    TEST_CASE( testnum, x2, result, \
+      li x1, MASK_XLEN(val); \
+      inst x2, x0, x1; \
+    )
+
+#define TEST_RR_ZEROSRC2( testnum, inst, result, val ) \
+    TEST_CASE( testnum, x2, result, \
+      li x1, MASK_XLEN(val); \
+      inst x2, x1, x0; \
+    )
+
+#define TEST_RR_ZEROSRC12( testnum, inst, result ) \
+    TEST_CASE( testnum, x1, result, \
+      inst x1, x0, x0; \
+    )
+
+#define TEST_RR_ZERODEST( testnum, inst, val1, val2 ) \
+    TEST_CASE( testnum, x0, 0, \
+      li x1, MASK_XLEN(val1); \
+      li x2, MASK_XLEN(val2); \
+      inst x0, x1, x2; \
+    )
+
+#-----------------------------------------------------------------------
+# Test memory instructions
+#-----------------------------------------------------------------------
+
+#define TEST_LD_OP( testnum, inst, result, offset, base ) \
+    TEST_CASE( testnum, x30, result, \
+      la  x1, base; \
+      inst x30, offset(x1); \
+    )
+
+#define TEST_ST_OP( testnum, load_inst, store_inst, result, offset, base ) \
+    TEST_CASE( testnum, x30, result, \
+      la  x1, base; \
+      li  x2, result; \
+      store_inst x2, offset(x1); \
+      load_inst x30, offset(x1); \
+    )
+
+#define TEST_LD_DEST_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+    li  x4, 0; \
+1:  la  x1, base; \
+    inst x30, offset(x1); \
+    TEST_INSERT_NOPS_ ## nop_cycles \
+    addi  x6, x30, 0; \
+    li  x29, result; \
+    bne x6, x29, fail; \
+    addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b; \
+
+#define TEST_LD_SRC1_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+    li  x4, 0; \
+1:  la  x1, base; \
+    TEST_INSERT_NOPS_ ## nop_cycles \
+    inst x30, offset(x1); \
+    li  x29, result; \
+    bne x30, x29, fail; \
+    addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+#define TEST_ST_SRC12_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+    li  x4, 0; \
+1:  li  x1, result; \
+    TEST_INSERT_NOPS_ ## src1_nops \
+    la  x2, base; \
+    TEST_INSERT_NOPS_ ## src2_nops \
+    store_inst x1, offset(x2); \
+    load_inst x30, offset(x2); \
+    li  x29, result; \
+    bne x30, x29, fail; \
+    addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+#define TEST_ST_SRC21_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+    li  x4, 0; \
+1:  la  x2, base; \
+    TEST_INSERT_NOPS_ ## src1_nops \
+    li  x1, result; \
+    TEST_INSERT_NOPS_ ## src2_nops \
+    store_inst x1, offset(x2); \
+    load_inst x30, offset(x2); \
+    li  x29, result; \
+    bne x30, x29, fail; \
+    addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+#define TEST_BR2_OP_TAKEN( testnum, inst, val1, val2 ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+    li  x1, val1; \
+    li  x2, val2; \
+    inst x1, x2, 2f; \
+    bne x0, TESTNUM, fail; \
+1:  bne x0, TESTNUM, 3f; \
+2:  inst x1, x2, 1b; \
+    bne x0, TESTNUM, fail; \
+3:
+
+#define TEST_BR2_OP_NOTTAKEN( testnum, inst, val1, val2 ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+    li  x1, val1; \
+    li  x2, val2; \
+    inst x1, x2, 1f; \
+    bne x0, TESTNUM, 2f; \
+1:  bne x0, TESTNUM, fail; \
+2:  inst x1, x2, 1b; \
+3:
+
+#define TEST_BR2_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+    li  x4, 0; \
+1:  li  x1, val1; \
+    TEST_INSERT_NOPS_ ## src1_nops \
+    li  x2, val2; \
+    TEST_INSERT_NOPS_ ## src2_nops \
+    inst x1, x2, fail; \
+    addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+#define TEST_BR2_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+    li  x4, 0; \
+1:  li  x2, val2; \
+    TEST_INSERT_NOPS_ ## src1_nops \
+    li  x1, val1; \
+    TEST_INSERT_NOPS_ ## src2_nops \
+    inst x1, x2, fail; \
+    addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+#-----------------------------------------------------------------------
+# Test jump instructions
+#-----------------------------------------------------------------------
+
+#define TEST_JR_SRC1_BYPASS( testnum, nop_cycles, inst ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+    li  x4, 0; \
+1:  la  x6, 2f; \
+    TEST_INSERT_NOPS_ ## nop_cycles \
+    inst x6; \
+    bne x0, TESTNUM, fail; \
+2:  addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+#define TEST_JALR_SRC1_BYPASS( testnum, nop_cycles, inst ) \
+test_ ## testnum: \
+    li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+    li  x4, 0; \
+1:  la  x6, 2f; \
+    TEST_INSERT_NOPS_ ## nop_cycles \
+    inst x19, x6, 0; \
+    bne x0, TESTNUM, fail; \
+2:  addi  x4, x4, 1; \
+    li  x5, 2; \
+    bne x4, x5, 1b \
+
+
+#-----------------------------------------------------------------------
+# RV64UF MACROS
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+# Tests floating-point instructions
+#-----------------------------------------------------------------------
+
+#define qNaNf 0f:7fc00000
+#define sNaNf 0f:7f800001
+#define qNaN 0d:7ff8000000000000
+#define sNaN 0d:7ff0000000000001
+
+#define TEST_FP_OP_S_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+  la  a0, test_ ## testnum ## _data ;\
+  flw f0, 0(a0); \
+  flw f1, 4(a0); \
+  flw f2, 8(a0); \
+  lw  a3, 12(a0); \
+  code; \
+  fsflags a1, x0; \
+  li a2, flags; \
+  bne a0, a3, fail; \
+  bne a1, a2, fail; \
+  .pushsection .data; \
+  .align 2; \
+  test_ ## testnum ## _data: \
+  .float val1; \
+  .float val2; \
+  .float val3; \
+  .result; \
+  .popsection
+
+#define TEST_FP_OP_D_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+  la  a0, test_ ## testnum ## _data ;\
+  fld f0, 0(a0); \
+  fld f1, 8(a0); \
+  fld f2, 16(a0); \
+  ld  a3, 24(a0); \
+  code; \
+  fsflags a1, x0; \
+  li a2, flags; \
+  bne a0, a3, fail; \
+  bne a1, a2, fail; \
+  .pushsection .data; \
+  .align 3; \
+  test_ ## testnum ## _data: \
+  .double val1; \
+  .double val2; \
+  .double val3; \
+  .result; \
+  .popsection
+
+// TODO: assign a separate mem location for the comparison address?
+#define TEST_FP_OP_D32_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+  la  a0, test_ ## testnum ## _data ;\
+  fld f0, 0(a0); \
+  fld f1, 8(a0); \
+  fld f2, 16(a0); \
+  lw  a3, 24(a0); \
+  lw  t1, 28(a0); \
+  code; \
+  fsflags a1, x0; \
+  li a2, flags; \
+  bne a0, a3, fail; \
+  bne t1, t2, fail; \
+  bne a1, a2, fail; \
+  .pushsection .data; \
+  .align 3; \
+  test_ ## testnum ## _data: \
+  .double val1; \
+  .double val2; \
+  .double val3; \
+  .result; \
+  .popsection
+
+#define TEST_FCVT_S_D32( testnum, result, val1 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \
+                    fcvt.s.d f3, f0; fcvt.d.s f3, f3; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
+#define TEST_FCVT_S_D( testnum, result, val1 ) \
+  TEST_FP_OP_D_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \
+                    fcvt.s.d f3, f0; fcvt.d.s f3, f3; fmv.x.d a0, f3)
+
+#define TEST_FCVT_D_S( testnum, result, val1 ) \
+  TEST_FP_OP_S_INTERNAL( testnum, 0, float result, val1, 0.0, 0.0, \
+                    fcvt.d.s f3, f0; fcvt.s.d f3, f3; fmv.x.s a0, f3)
+
+#define TEST_FP_OP1_S( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, 0.0, 0.0, \
+                    inst f3, f0; fmv.x.s a0, f3)
+
+#define TEST_FP_OP1_D32( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \
+                    inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+// ^: store computation result in address from a0, load high-word into t2
+
+#define TEST_FP_OP1_D( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \
+                    inst f3, f0; fmv.x.d a0, f3)
+
+#define TEST_FP_OP1_S_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_S_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+                    inst f3, f0; fmv.x.s a0, f3)
+
+#define TEST_FP_OP1_D32_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+                    inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+// ^: store computation result in address from a0, load high-word into t2
+
+#define TEST_FP_OP1_D_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+                    inst f3, f0; fmv.x.d a0, f3)
+
+#define TEST_FP_OP2_S( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, 0.0, \
+                    inst f3, f0, f1; fmv.x.s a0, f3)
+
+#define TEST_FP_OP2_D32( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
+                    inst f3, f0, f1; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+// ^: store computation result in address from a0, load high-word into t2
+
+#define TEST_FP_OP2_D( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
+                    inst f3, f0, f1; fmv.x.d a0, f3)
+
+#define TEST_FP_OP3_S( testnum, inst, flags, result, val1, val2, val3 ) \
+  TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, val3, \
+                    inst f3, f0, f1, f2; fmv.x.s a0, f3)
+
+#define TEST_FP_OP3_D32( testnum, inst, flags, result, val1, val2, val3 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, val3, \
+                    inst f3, f0, f1, f2; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+// ^: store computation result in address from a0, load high-word into t2
+
+#define TEST_FP_OP3_D( testnum, inst, flags, result, val1, val2, val3 ) \
+  TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, val2, val3, \
+                    inst f3, f0, f1, f2; fmv.x.d a0, f3)
+
+#define TEST_FP_INT_OP_S( testnum, inst, flags, result, val1, rm ) \
+  TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, 0.0, 0.0, \
+                    inst a0, f0, rm)
+
+#define TEST_FP_INT_OP_D32( testnum, inst, flags, result, val1, rm ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+                    inst a0, f0, f1; li t2, 0)
+
+#define TEST_FP_INT_OP_D( testnum, inst, flags, result, val1, rm ) \
+  TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+                    inst a0, f0, rm)
+
+#define TEST_FP_CMP_OP_S( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, val2, 0.0, \
+                    inst a0, f0, f1)
+
+#define TEST_FP_CMP_OP_D32( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \
+                    inst a0, f0, f1; li t2, 0)
+
+#define TEST_FP_CMP_OP_D( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \
+                    inst a0, f0, f1)
+
+#define TEST_FCLASS_S(testnum, correct, input) \
+  TEST_CASE(testnum, a0, correct, li a0, input; fmv.s.x fa0, a0; \
+                    fclass.s a0, fa0)
+
+#define TEST_FCLASS_D32(testnum, correct, input) \
+  TEST_CASE(testnum, a0, correct, \
+            la a0, test_ ## testnum ## _data ;\
+            fld fa0, 0(a0); \
+            fclass.d a0, fa0) \
+    .pushsection .data; \
+    .align 3; \
+    test_ ## testnum ## _data: \
+    .dword input; \
+    .popsection
+
+#define TEST_FCLASS_D(testnum, correct, input) \
+  TEST_CASE(testnum, a0, correct, li a0, input; fmv.d.x fa0, a0; \
+                    fclass.d a0, fa0)
+
+#define TEST_INT_FP_OP_S( testnum, inst, result, val1 ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+  la  a0, test_ ## testnum ## _data ;\
+  lw  a3, 0(a0); \
+  li  a0, val1; \
+  inst f0, a0; \
+  fsflags x0; \
+  fmv.x.s a0, f0; \
+  bne a0, a3, fail; \
+  .pushsection .data; \
+  .align 2; \
+  test_ ## testnum ## _data: \
+  .float result; \
+  .popsection
+
+#define TEST_INT_FP_OP_D32( testnum, inst, result, val1 ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+  la  a0, test_ ## testnum ## _data ;\
+  lw  a3, 0(a0); \
+  lw  a4, 4(a0); \
+  li  a1, val1; \
+  inst f0, a1; \
+  \
+  fsd f0, 0(a0); \
+  lw a1, 4(a0); \
+  lw a0, 0(a0); \
+  \
+  fsflags x0; \
+  bne a0, a3, fail; \
+  bne a1, a4, fail; \
+  .pushsection .data; \
+  .align 3; \
+  test_ ## testnum ## _data: \
+  .double result; \
+  .popsection
+
+#define TEST_INT_FP_OP_D( testnum, inst, result, val1 ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  SWSIG (testnum, TESTNUM);\
+  la  a0, test_ ## testnum ## _data ;\
+  ld  a3, 0(a0); \
+  li  a0, val1; \
+  inst f0, a0; \
+  fsflags x0; \
+  fmv.x.d a0, f0; \
+  bne a0, a3, fail; \
+  .pushsection .data; \
+  .align 3; \
+  test_ ## testnum ## _data: \
+  .double result; \
+  .popsection
+
+// We need some special handling here to allow 64-bit comparison in 32-bit arch
+// TODO: find a better name and clean up when intended for general usage?
+#define TEST_CASE_D32( testnum, testreg1, testreg2, correctval, code... ) \
+test_ ## testnum: \
+    code; \
+    la  x31, test_ ## testnum ## _data ; \
+    lw  x29, 0(x31); \
+    lw  x31, 4(x31); \
+    li  TESTNUM, testnum; \
+    SWSIG (testnum, TESTNUM);\
+    bne testreg1, x29, fail;\
+    bne testreg2, x31, fail;\
+    .pushsection .data; \
+    .align 3; \
+    test_ ## testnum ## _data: \
+    .dword correctval; \
+    .popsection
+
+// ^ x30 is used in some other macros, to avoid issues we use x31 for upper word
+
+#-----------------------------------------------------------------------
+# Pass and fail code (assumes test num is in TESTNUM)
+#-----------------------------------------------------------------------
+
+#define TEST_PASSFAIL \
+        bne x0, TESTNUM, pass; \
+fail: \
+        RVTEST_FAIL; \
+pass: \
+        RVTEST_PASS \
+
+
+#-----------------------------------------------------------------------
+# Test data section
+#-----------------------------------------------------------------------
+
+#define TEST_DATA
+
+#endif
diff --git a/verilog/dv/riscv_regress/tests/riscv_compliance/compliance_io.h b/verilog/dv/riscv_regress/tests/riscv_compliance/compliance_io.h
new file mode 100644
index 0000000..5b7ca54
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/riscv_compliance/compliance_io.h
@@ -0,0 +1,70 @@
+// RISC-V Compliance IO Test Header File
+
+/*
+ * Copyright (c) 2005-2018 Imperas Software Ltd., www.imperas.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _COMPLIANCE_IO_H
+#define _COMPLIANCE_IO_H
+
+//-----------------------------------------------------------------------
+// RV IO Macros (Non functional)
+//-----------------------------------------------------------------------
+#ifdef _COMPLIANCE_OUTPUT
+
+#define RVTEST_IO_PUSH(_SP)                                             \
+la _SP, begin_regstate;                                                 \
+sw x3, 0(_SP);                                                          \
+sw x4, 4(_SP);                                                          \
+sw x5, 8(_SP);
+
+#define RVTEST_IO_POP(_SP)                                              \
+la _SP, begin_regstate;                                                 \
+lw x3, 0(_SP);                                                          \
+lw x4, 4(_SP);                                                          \
+lw x5, 8(_SP);	
+
+#define RVTEST_IO_WRITE_STR(_SP, _STR)	                                \
+    .section .data.string;                                              \
+20001:                                                                  \
+    .string _STR;                                                       \
+    .section .text;                                                     \
+    RVTEST_IO_PUSH(_SP)                                                 \
+    li x3, 0xF0000000;                                                  \
+    la x4, 20001b;                                                      \
+2:  lb x5, 0(x4);                                                       \
+    sb x5, 0(x3);                                                       \
+    beq x5, zero, 1f;                                                   \
+    add x4, x4, 1;                                                      \
+    j 2b;                                                               \
+1:  RVTEST_IO_POP(_SP)
+
+#else // #ifdef _COMPLIANCE_OUTPUT
+
+#define RVTEST_IO_WRITE_STR(_SP, _STR)
+
+#endif // #end #ifdef _COMPLIANCE_OUTPUT
+
+#define RVTEST_IO_INIT
+#define RVTEST_IO_CHECK()
+#define RVTEST_IO_ASSERT_GPR_EQ(_SP, _R, _I)
+#define RVTEST_IO_ASSERT_SFPR_EQ(_F, _R, _I)
+#define RVTEST_IO_ASSERT_DFPR_EQ(_D, _R, _I)
+#define RVTEST_IO_ASSERT_EQ(_R, _I) 
+
+#endif // _COMPLIANCE_IO_H
diff --git a/verilog/dv/riscv_regress/tests/riscv_compliance/compliance_test.h b/verilog/dv/riscv_regress/tests/riscv_compliance/compliance_test.h
new file mode 100644
index 0000000..0c7e7f9
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/riscv_compliance/compliance_test.h
@@ -0,0 +1,31 @@
+// RISC-V Compliance Test Header File
+// Copyright (c) 2017, Codasip Ltd. All Rights Reserved.
+// See LICENSE for license details.
+//
+// Description: Common header file for RV32I tests
+
+#ifndef _COMPLIANCE_TEST_H
+#define _COMPLIANCE_TEST_H
+
+//-----------------------------------------------------------------------
+// RV Compliance Macros
+//-----------------------------------------------------------------------
+
+#define RV_COMPLIANCE_HALT                                                   \
+
+#define RV_COMPLIANCE_RV32M                                                  \
+        RVTEST_RV32M                                                         \
+
+#define RV_COMPLIANCE_CODE_BEGIN                                             \
+        RVTEST_CODE_BEGIN                                                    \
+
+#define RV_COMPLIANCE_CODE_END                                               \
+        RVTEST_CODE_END                                                      \
+
+#define RV_COMPLIANCE_DATA_BEGIN                                             \
+        RVTEST_DATA_BEGIN                                                    \
+
+#define RV_COMPLIANCE_DATA_END                                               \
+        RVTEST_DATA_END                                                      \
+
+#endif
\ No newline at end of file
diff --git a/verilog/dv/riscv_regress/tests/riscv_compliance/riscv_test.h b/verilog/dv/riscv_regress/tests/riscv_compliance/riscv_test.h
new file mode 100644
index 0000000..fdc6156
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/riscv_compliance/riscv_test.h
@@ -0,0 +1,7 @@
+
+#ifndef _RISCV_TEST_H
+#define _RISCV_TEST_H
+
+#include "test_macros.h"
+
+#endif
\ No newline at end of file
diff --git a/verilog/dv/riscv_regress/tests/riscv_compliance/riscv_test_macros.h b/verilog/dv/riscv_regress/tests/riscv_compliance/riscv_test_macros.h
new file mode 100644
index 0000000..6717bd4
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/riscv_compliance/riscv_test_macros.h
@@ -0,0 +1,463 @@
+// RISC-V Compliance IO Test Header File
+
+/*
+ * Copyright (c) 2005-2018 Imperas Software Ltd., www.imperas.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "riscv_macros.h"
+
+//
+// In general the following registers are reserved
+// ra, a0, t0, t1
+// Additionally on an assertion violation, t1, t2 are overwritten
+// x1, x10, x5, x6, x7 respectively
+// Floating registers reserved
+// f5
+//
+
+#define MASK_XLEN(x) ((x) & ((1 << (__riscv_xlen - 1) << 1) - 1))
+
+#define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11))
+
+// Base function for integer operations
+#define TEST_CASE(testreg, destreg, correctval, swreg, offset, code... ) \
+    code; \
+    sw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) \
+
+// Base functions for single precision floating point operations
+#define TEST_CASE_FP(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    flw reg1, 0(a0); \
+    flw reg2, 4(a0); \
+    lw t1, 8(a0); \
+    code; \
+    fsw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_SFPR_EQ(destreg, t1, correctval) \
+    .pushsection .data; \
+    .align 3; \
+    test_ ## test_num ## _data: \
+      .float val1; \
+      .float val2; \
+      .word correctval; \
+    .popsection
+
+#define TEST_CASE_FP_I(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    lw t1, 0(a0); \
+    code; \
+    fsw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_SFPR_EQ(destreg, t1, correctval) \
+    .pushsection .data; \
+    .align 1; \
+    test_ ## test_num ## _data: \
+      .word correctval; \
+    .popsection
+
+#define TEST_CASE_FP_I2(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    flw reg, 0(a0); \
+    lw t1, 4(a0); \
+    code; \
+    sw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+    .pushsection .data; \
+    .align 2; \
+    test_ ## test_num ## _data: \
+      .float val; \
+      .word correctval; \
+    .popsection
+
+#define TEST_CASE_FP_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    flw reg1, 0(a0); \
+    flw reg2, 4(a0); \
+    flw reg3, 8(a0); \
+    lw t1, 12(a0); \
+    code; \
+    fsw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_SFPR_EQ(destreg, t1, correctval) \
+    .pushsection .data; \
+    .align 4; \
+    test_ ## test_num ## _data: \
+      .float val1; \
+      .float val2; \
+      .float val3; \
+      .word correctval; \
+    .popsection
+
+#define TEST_CASE_FP_FMVXS(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    flw reg, 0(a0); \
+    code; \
+    sw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+    .pushsection .data; \
+    .align 1; \
+    test_ ## test_num ## _data: \
+      .float val; \
+    .popsection
+
+#define TEST_CASE_FP_FMVSX(test_num, destreg, reg, correctval, val, swreg, offset, code...) \
+    la  a0, test_ ## test_num ## _data; \
+    li reg, val; \
+    code; \
+    fsw destreg, offset(swreg); \
+    lw a1, 0(a0); \
+    RVTEST_IO_ASSERT_SFPR_EQ(destreg, a1, correctval) \
+    .pushsection .data; \
+    .align 1; \
+    test_ ## test_num ## _data: \
+      .word correctval; \
+    .popsection
+
+// Base functions for double precision floating point operations - rv32d
+#define TEST_CASE_FPD(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    fld reg1, 0(a0); \
+    fld reg2, 8(a0); \
+    code; \
+    fsd destreg, offset(swreg); \
+    lw t1, 16(a0); \
+    lw t2, 20(a0); \
+    la a0, store_ ## test_num ## _data; \
+    fsd destreg, 0(a0); \
+    lw a1, 0(a0); \
+    lw a2, 4(a0); \
+    RVTEST_IO_ASSERT_DFPR_EQ(destreg, t2, t1, a2, a1, correctval) \
+    .pushsection .data; \
+    .align 3; \
+    test_ ## test_num ## _data: \
+      .double val1; \
+      .double val2; \
+      .dword correctval; \
+    .popsection; \
+    .pushsection .data; \
+    store_ ## test_num ## _data: \
+      .fill 1, 8, -1; \
+    .popsection
+
+#define TEST_CASE_FPD_I(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    code; \
+    fsd destreg, offset(swreg); \
+    lw t1, 0(a0); \
+    lw t2, 4(a0); \
+    la a0, store_ ## test_num ## _data; \
+    fsd destreg, 0(a0); \
+    lw a1, 0(a0); \
+    lw a2, 4(a0); \
+    RVTEST_IO_ASSERT_DFPR_EQ(destreg, t2, t1, a2, a1, correctval) \
+    .pushsection .data; \
+    .align 1; \
+    test_ ## test_num ## _data: \
+      .dword correctval; \
+    .popsection; \
+    store_ ## test_num ## _data: \
+      .fill 1, 8, -1; \
+    .popsection
+
+#define TEST_CASE_FPD_I2(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    fld reg, 0(a0); \
+    lw t1, 8(a0); \
+    code; \
+    sw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+    .pushsection .data; \
+    .align 2; \
+    test_ ## test_num ## _data: \
+      .double val; \
+      .word correctval; \
+    .popsection
+
+#define TEST_CASE_FPD_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    fld reg1, 0(a0); \
+    fld reg2, 8(a0); \
+    fld reg3, 16(a0); \
+    code; \
+    fsd destreg, offset(swreg); \
+    lw t1, 24(a0); \
+    lw t2, 28(a0); \
+    la a0, store_ ## test_num ## _data; \
+    fsd destreg, 0(a0); \
+    lw a1, 0(a0); \
+    lw a2, 4(a0); \
+    RVTEST_IO_ASSERT_DFPR_EQ(destreg, t2, t1, a2, a1, correctval) \
+    .pushsection .data; \
+    .align 4; \
+    test_ ## test_num ## _data: \
+      .double val1; \
+      .double val2; \
+      .double val3; \
+      .dword correctval; \
+    .popsection; \
+    .pushsection .data; \
+    store_ ## test_num ## _data: \
+      .fill 1, 8, -1; \
+    .popsection
+
+//Tests for a instructions with register-register operand
+#define TEST_RR_OP(inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      li  reg1, MASK_XLEN(val1); \
+      li  reg2, MASK_XLEN(val2); \
+      inst destreg, reg1, reg2; \
+    )
+
+#define TEST_RR_SRC1( inst, destreg, reg, correctval, val1, val2, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      li destreg, MASK_XLEN(val1); \
+      li reg, MASK_XLEN(val2); \
+      inst destreg, destreg, reg; \
+    )
+
+#define TEST_RR_SRC2( inst, destreg, reg, correctval, val1, val2, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      li reg, MASK_XLEN(val1); \
+      li destreg, MASK_XLEN(val2); \
+      inst destreg, reg, destreg; \
+    )
+
+#define TEST_RR_SRC12( inst, destreg, correctval, val, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      li destreg, MASK_XLEN(val1); \
+      inst destreg, destreg, destreg; \
+    )
+
+#define TEST_RR_ZERO1( inst, destreg, reg, correctval, val, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      li reg, MASK_XLEN(val); \
+      inst destreg, x0, reg; \
+    )
+
+#define TEST_RR_ZERO2( inst, destreg, reg, correctval, val, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      li reg, MASK_XLEN(val); \
+      inst destreg, reg, x0; \
+    )
+
+#define TEST_RR_ZERO12( inst, destreg, correctval, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      inst destreg, x0, x0; \
+    )
+
+#define TEST_RR_ZERODEST( inst, reg1, reg2, val1, val2, swreg, offset, testreg) \
+    TEST_CASE(testreg, x0, 0, swreg, offset, \
+      li reg1, MASK_XLEN(val1); \
+      li reg2, MASK_XLEN(val2); \
+      inst x0, reg1, reg2; \
+    )
+
+//Tests for a instructions with register-immediate operand
+#define TEST_IMM_OP( inst, destreg, reg, correctval, val, imm, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      li reg, MASK_XLEN(val); \
+      inst destreg, reg, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_SRC( inst, destreg, correctval, val, imm, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      li destreg, MASK_XLEN(val); \
+      inst destreg, destreg, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_ZEROSRC( inst, destreg, correctval, imm, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      inst destreg, x0, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_ZERODEST( inst, reg, val, imm, swreg, offset, testreg) \
+    TEST_CASE(testreg, x0, 0, swreg, offset, \
+      li reg, MASK_XLEN(val); \
+      inst x0, reg, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_ONEREG( inst, destreg, correctval, imm, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      inst destreg, SEXT_IMM(imm); \
+      )
+
+#define TEST_AUIPC(inst, destreg, correctval, imm, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      1: \
+      inst destreg, imm; \
+      la swreg, 1b; \
+      sub destreg, destreg, swreg; \
+      )
+
+//Tests for a compressed instruction
+#define TEST_CR_OP( inst, destreg, reg, correctval, val1, val2, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      li reg, MASK_XLEN(val1); \
+      li destreg, MASK_XLEN(val2); \
+      inst destreg, reg; \
+      )
+
+#define TEST_CI_OP( inst, destreg, correctval, val, imm, swreg, offset, testreg) \
+    TEST_CASE(testreg, destreg, correctval, swreg, offset, \
+      li destreg, MASK_XLEN(val); \
+      inst destreg, imm; \
+      )
+
+#define TEST_CI_OP_NOREG(inst, correctval, imm, swreg, offset, testreg) \
+    TEST_CASE(testreg,x0, correctval, swreg, offset, \
+      inst imm; \
+      )
+
+//Tests for floating point instructions - single precision
+#define TEST_FP_OP(test_num, inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset) \
+      TEST_CASE_FP(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, \
+        inst destreg, reg1, reg2; \
+        )
+
+#define TEST_FP_ONEREG(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FP(test_num, destreg, reg, reg, correctval, val, val, swreg, offset, \
+        inst destreg, reg; \
+        )
+
+#define TEST_FP_4REG(test_num, inst, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset) \
+      TEST_CASE_FP_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, \
+        inst destreg, reg1, reg2, reg3; \
+        )
+
+#define TEST_FP_I(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FP_I(test_num, destreg, reg, correctval, val, swreg, offset, \
+        li reg, MASK_XLEN(val); \
+        inst destreg, reg; \
+        )
+
+#define TEST_FP_I2(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FP_I2(test_num, destreg, reg, correctval, val, swreg, offset, \
+        inst destreg, reg; \
+        )
+
+//Tests for floating point instructions - double precision
+#define TEST_FPD_OP(test_num, inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset) \
+      TEST_CASE_FPD(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, \
+        inst destreg, reg1, reg2; \
+        )
+
+#define TEST_FPD_ONEREG(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FPD(test_num, destreg, reg, reg, correctval, val, val, swreg, offset, \
+        inst destreg, reg; \
+        )
+
+#define TEST_FPD_4REG(test_num, inst, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset) \
+      TEST_CASE_FPD_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, \
+        inst destreg, reg1, reg2, reg3; \
+        )
+
+#define TEST_FPD_I(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FPD_I(test_num, destreg, reg, correctval, val, swreg, offset, \
+        li reg, MASK_XLEN(val); \
+        inst destreg, reg; \
+        )
+
+#define TEST_FPD_I2(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FPD_I2(test_num, destreg, reg, correctval, val, swreg, offset, \
+        inst destreg, reg; \
+        )
+
+#define TEST_CADDI16SP(correctval, imm, swreg, offset, testreg) \
+      TEST_CASE(testreg,x2, correctval, swreg, offset, \
+      c.addi16sp x2, imm; \
+      )
+
+#define TEST_CADDI4SPN(destreg, correctval, imm, swreg, offset, testreg) \
+      TEST_CASE(testreg,destreg, correctval, swreg, offset, \
+        c.addi4spn destreg, x2, SEXT_IMM(imm); \
+        )
+
+#define TEST_CJL(inst, reg, val, swreg, offset) \
+      li x10, val; \
+      la reg, 1f; \
+      inst reg; \
+      li x10, 0x123ab; \
+1: \
+      sw x10, offset(swreg); \
+      RVTEST_IO_ASSERT_GPR_EQ(x31, x10, val); \
+
+#define ABS(x) ((x >> 11) ^ x) - (x >> 11)
+
+#define TEST_CJ(inst, reg, val, swreg, offset) \
+      li reg, val; \
+      inst 1f; \
+      li reg, 0x123ab; \
+1: \
+      sw reg, offset(swreg); \
+      RVTEST_IO_ASSERT_GPR_EQ(x31, reg, val); \
+
+#define TEST_CL(inst, reg, imm, swreg, offset) \
+      la reg, test_data; \
+      inst reg, imm(reg); \
+      sw reg, offset(swreg); \
+
+// lw reg, imm(x2)
+// c.lwsp reg, imm(x2)
+#define TEST_CLWSP(reg, imm, swreg, offset) \
+      la x2, test_data; \
+      c.lwsp reg, imm(x2); \
+      sw reg, offset(swreg); \
+
+#define TEST_CSW(test_data, inst, reg1, reg2, val, imm, swreg, offset) \
+      li reg1, val; \
+      la reg2, test_data; \
+      inst reg1, imm(reg2); \
+      lw reg1, imm(reg2); \
+      sw reg1, offset(swreg); \
+      RVTEST_IO_ASSERT_GPR_EQ(x31, reg1, val); \
+
+#define TEST_CSWSP(test_data, reg, val, imm, swreg, offset) \
+      la x2, test_data; \
+      li reg, val; \
+      c.swsp reg, imm(x2); \
+      lw reg, imm(x2); \
+      sw reg, offset(swreg); \
+      RVTEST_IO_ASSERT_GPR_EQ(x31, reg, val); \
+
+#define TEST_CBEQZ(reg, val, swreg, offset) \
+      li reg, val; \
+      c.sub reg, reg; \
+      c.beqz reg, 3f; \
+      li reg, 0x123ab; \
+3: \
+      sw reg, offset(swreg); \
+      RVTEST_IO_ASSERT_GPR_EQ(x31, reg, 0x0); \
+
+#define TEST_CBNEZ(reg, val, swreg, offset) \
+      li reg, val; \
+      c.bnez reg, 4f; \
+      li reg, 0x0; \
+4: \
+      sw reg, offset(swreg); \
+      RVTEST_IO_ASSERT_GPR_EQ(x31, reg, val); \
+
+#define TEST_FMVXS(test_num, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FP_FMVXS(test_num, destreg, reg, correctval, val, swreg, offset, \
+        fmv.x.s destreg, reg; \
+        )
+
+#define TEST_FMVSX(test_num, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FP_FMVSX(test_num, destreg, reg, correctval, val, swreg, offset, \
+        fmv.s.x destreg, reg; \
+        )
+
+#define SWSIG(a,b)
+
diff --git a/verilog/dv/riscv_regress/tests/riscv_compliance/test_macros.h b/verilog/dv/riscv_regress/tests/riscv_compliance/test_macros.h
new file mode 100644
index 0000000..b2c610e
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/riscv_compliance/test_macros.h
@@ -0,0 +1,593 @@
+
+// RISC-V Compliance Test Header File
+// Copyright (c) 2017, Codasip Ltd. All Rights Reserved.
+// See LICENSE for license details.
+//
+// Description: Common header file for RV32I tests
+
+#ifndef _TEST_MACROS_H
+#define _TEST_MACROS_H
+
+#include "riscv_macros.h"
+
+// RISC-V Compliance IO Test Header File
+
+/*
+ * Copyright (c) 2005-2018 Imperas Software Ltd., www.imperas.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+//
+// In general the following registers are reserved
+// ra, a0, t0, t1
+// Additionally on an assertion violation, t1, t2 are overwritten
+// x1, x10, x5, x6, x7 respectively
+// Floating registers reserved
+// f5
+//
+
+#define MASK_XLEN(x) ((x) & ((1 << (__riscv_xlen - 1) << 1) - 1))
+
+#define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11))
+
+// Base function for integer operations
+#define TEST_CASE(destreg, correctval, swreg, offset, code... ) \
+    code; \
+    sw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+
+// Base functions for single precision floating point operations
+#define TEST_CASE_FP(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    flw reg1, 0(a0); \
+    flw reg2, 4(a0); \
+    lw t1, 8(a0); \
+    code; \
+    fsw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_SFPR_EQ(destreg, t1, correctval) \
+    .pushsection .data; \
+    .balign 8; \
+    test_ ## test_num ## _data: \
+      .float val1; \
+      .float val2; \
+      .word correctval; \
+    .popsection
+
+#define TEST_CASE_FP_I(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    lw t1, 0(a0); \
+    code; \
+    fsw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_SFPR_EQ(destreg, t1, correctval) \
+    .pushsection .data; \
+    .balign 2; \
+    test_ ## test_num ## _data: \
+      .word correctval; \
+    .popsection
+
+#define TEST_CASE_FP_I2(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    flw reg, 0(a0); \
+    lw t1, 4(a0); \
+    code; \
+    sw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+    .pushsection .data; \
+    .balign 4; \
+    test_ ## test_num ## _data: \
+      .float val; \
+      .word correctval; \
+    .popsection
+
+#define TEST_CASE_FP_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    flw reg1, 0(a0); \
+    flw reg2, 4(a0); \
+    flw reg3, 8(a0); \
+    lw t1, 12(a0); \
+    code; \
+    fsw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_SFPR_EQ(destreg, t1, correctval) \
+    .pushsection .data; \
+    .balign 16; \
+    test_ ## test_num ## _data: \
+      .float val1; \
+      .float val2; \
+      .float val3; \
+      .word correctval; \
+    .popsection
+
+#define TEST_CASE_FP_FMVXS(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    flw reg, 0(a0); \
+    code; \
+    sw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+    .pushsection .data; \
+    .balign 2; \
+    test_ ## test_num ## _data: \
+      .float val; \
+    .popsection
+
+#define TEST_CASE_FP_FMVSX(test_num, destreg, reg, correctval, val, swreg, offset, code...) \
+    la  a0, test_ ## test_num ## _data; \
+    li reg, val; \
+    code; \
+    fsw destreg, offset(swreg); \
+    lw a1, 0(a0); \
+    RVTEST_IO_ASSERT_SFPR_EQ(destreg, a1, correctval) \
+    .pushsection .data; \
+    .balign 2; \
+    test_ ## test_num ## _data: \
+      .word correctval; \
+    .popsection
+
+// Base functions for double precision floating point operations - rv32d
+#define TEST_CASE_FPD(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    fld reg1, 0(a0); \
+    fld reg2, 8(a0); \
+    code; \
+    fsd destreg, offset(swreg); \
+    lw t1, 16(a0); \
+    lw t2, 20(a0); \
+    la a0, store_ ## test_num ## _data; \
+    fsd destreg, 0(a0); \
+    lw a1, 0(a0); \
+    lw a2, 4(a0); \
+    RVTEST_IO_ASSERT_DFPR_EQ(destreg, t2, t1, a2, a1, correctval) \
+    .pushsection .data; \
+    .balign 8; \
+    test_ ## test_num ## _data: \
+      .double val1; \
+      .double val2; \
+      .dword correctval; \
+    .popsection; \
+    .pushsection .data; \
+    store_ ## test_num ## _data: \
+      .fill 1, 8, -1; \
+    .popsection
+
+#define TEST_CASE_FPD_I(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    code; \
+    fsd destreg, offset(swreg); \
+    lw t1, 0(a0); \
+    lw t2, 4(a0); \
+    la a0, store_ ## test_num ## _data; \
+    fsd destreg, 0(a0); \
+    lw a1, 0(a0); \
+    lw a2, 4(a0); \
+    RVTEST_IO_ASSERT_DFPR_EQ(destreg, t2, t1, a2, a1, correctval) \
+    .pushsection .data; \
+    .balign 2; \
+    test_ ## test_num ## _data: \
+      .dword correctval; \
+    .popsection; \
+    store_ ## test_num ## _data: \
+      .fill 1, 8, -1; \
+    .popsection
+
+#define TEST_CASE_FPD_I2(test_num, destreg, reg, correctval, val, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    fld reg, 0(a0); \
+    lw t1, 8(a0); \
+    code; \
+    sw destreg, offset(swreg); \
+    RVTEST_IO_ASSERT_GPR_EQ(x31, destreg, correctval) \
+    .pushsection .data; \
+    .balign 4; \
+    test_ ## test_num ## _data: \
+      .double val; \
+      .word correctval; \
+    .popsection
+
+#define TEST_CASE_FPD_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, code... ) \
+    la  a0, test_ ## test_num ## _data; \
+    fld reg1, 0(a0); \
+    fld reg2, 8(a0); \
+    fld reg3, 16(a0); \
+    code; \
+    fsd destreg, offset(swreg); \
+    lw t1, 24(a0); \
+    lw t2, 28(a0); \
+    la a0, store_ ## test_num ## _data; \
+    fsd destreg, 0(a0); \
+    lw a1, 0(a0); \
+    lw a2, 4(a0); \
+    RVTEST_IO_ASSERT_DFPR_EQ(destreg, t2, t1, a2, a1, correctval) \
+    .pushsection .data; \
+    .balign 16; \
+    test_ ## test_num ## _data: \
+      .double val1; \
+      .double val2; \
+      .double val3; \
+      .dword correctval; \
+    .popsection; \
+    .pushsection .data; \
+    store_ ## test_num ## _data: \
+      .fill 1, 8, -1; \
+    .popsection
+
+//Tests for a instructions with register-register operand
+#define TEST_RR_OP(inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset) \
+    TEST_CASE( destreg, correctval, swreg, offset, \
+      li  reg1, MASK_XLEN(val1); \
+      li  reg2, MASK_XLEN(val2); \
+      inst destreg, reg1, reg2; \
+    )
+
+#define TEST_RR_SRC1( inst, destreg, reg, correctval, val1, val2, swreg, offset) \
+    TEST_CASE( destreg, correctval, swreg, offset, \
+      li destreg, MASK_XLEN(val1); \
+      li reg, MASK_XLEN(val2); \
+      inst destreg, destreg, reg; \
+    )
+
+#define TEST_RR_SRC2( inst, destreg, reg, correctval, val1, val2, swreg, offset) \
+    TEST_CASE( destreg, correctval, swreg, offset, \
+      li reg, MASK_XLEN(val1); \
+      li destreg, MASK_XLEN(val2); \
+      inst destreg, reg, destreg; \
+    )
+
+#define TEST_RR_SRC12( inst, destreg, correctval, val, swreg, offset) \
+    TEST_CASE( destreg, correctval, swreg, offset, \
+      li destreg, MASK_XLEN(val1); \
+      inst destreg, destreg, destreg; \
+    )
+
+#define TEST_RR_ZERO1( inst, destreg, reg, correctval, val, swreg, offset) \
+    TEST_CASE( destreg, correctval, swreg, offset, \
+      li reg, MASK_XLEN(val); \
+      inst destreg, x0, reg; \
+    )
+
+#define TEST_RR_ZERO2( inst, destreg, reg, correctval, val, swreg, offset) \
+    TEST_CASE( destreg, correctval, swreg, offset, \
+      li reg, MASK_XLEN(val); \
+      inst destreg, reg, x0; \
+    )
+
+#define TEST_RR_ZERO12( inst, destreg, correctval, swreg, offset) \
+    TEST_CASE( destreg, correctval, swreg, offset, \
+      inst destreg, x0, x0; \
+    )
+
+#define TEST_RR_ZERODEST( inst, reg1, reg2, val1, val2, swreg, offset) \
+    TEST_CASE( x0, 0, swreg, offset, \
+      li reg1, MASK_XLEN(val1); \
+      li reg2, MASK_XLEN(val2); \
+      inst x0, reg1, reg2; \
+    )
+
+//Tests for a instructions with register-immediate operand
+#define TEST_IMM_OP( inst, destreg, reg, correctval, val, imm, swreg, offset) \
+    TEST_CASE ( destreg, correctval, swreg, offset, \
+      li reg, MASK_XLEN(val); \
+      inst destreg, reg, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_SRC( inst, destreg, correctval, val, imm, swreg, offset) \
+    TEST_CASE ( destreg, correctval, swreg, offset, \
+      li destreg, MASK_XLEN(val); \
+      inst destreg, destreg, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_ZEROSRC( inst, destreg, correctval, imm, swreg, offset) \
+    TEST_CASE ( destreg, correctval, swreg, offset, \
+      inst destreg, x0, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_ZERODEST( inst, reg, val, imm, swreg, offset) \
+    TEST_CASE ( x0, 0, swreg, offset, \
+      li reg, MASK_XLEN(val); \
+      inst x0, reg, SEXT_IMM(imm); \
+    )
+
+#define TEST_IMM_ONEREG( inst, destreg, correctval, imm, swreg, offset) \
+    TEST_CASE ( destreg, correctval, swreg, offset, \
+      inst destreg, SEXT_IMM(imm); \
+      )
+
+#define TEST_AUIPC(inst, destreg, correctval, imm, swreg, offset) \
+    TEST_CASE ( destreg, correctval, swreg, offset, \
+      1: \
+      inst destreg, SEXT_IMM(imm); \
+      la swreg, 1b; \
+      sub destreg, destreg, swreg; \
+      )
+
+//Tests for a compressed instruction
+#define TEST_CR_OP( inst, destreg, reg, correctval, val1, val2, swreg, offset) \
+    TEST_CASE ( destreg, correctval, swreg, offset, \
+      li reg, MASK_XLEN(val1); \
+      li destreg, MASK_XLEN(val2); \
+      inst destreg, reg; \
+      )
+
+#define TEST_CI_OP( inst, destreg, correctval, val, imm, swreg, offset) \
+    TEST_CASE( destreg, correctval, swreg, offset, \
+      li destreg, MASK_XLEN(val); \
+      inst destreg, imm; \
+      )
+
+#define TEST_CI_OP_NOREG(inst, correctval, imm, swreg, offset) \
+    TEST_CASE (x0, correctval, swreg, offset, \
+      inst imm; \
+      )
+
+//Tests for floating point instructions - single precision
+#define TEST_FP_OP(test_num, inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset) \
+      TEST_CASE_FP(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, \
+        inst destreg, reg1, reg2; \
+        )
+
+#define TEST_FP_ONEREG(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FP(test_num, destreg, reg, reg, correctval, val, val, swreg, offset, \
+        inst destreg, reg; \
+        )
+
+#define TEST_FP_4REG(test_num, inst, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset) \
+      TEST_CASE_FP_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, \
+        inst destreg, reg1, reg2, reg3; \
+        )
+
+#define TEST_FP_I(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FP_I(test_num, destreg, reg, correctval, val, swreg, offset, \
+        li reg, MASK_XLEN(val); \
+        inst destreg, reg; \
+        )
+
+#define TEST_FP_I2(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FP_I2(test_num, destreg, reg, correctval, val, swreg, offset, \
+        inst destreg, reg; \
+        )
+
+//Tests for floating point instructions - double precision
+#define TEST_FPD_OP(test_num, inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset) \
+      TEST_CASE_FPD(test_num, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, \
+        inst destreg, reg1, reg2; \
+        )
+
+#define TEST_FPD_ONEREG(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FPD(test_num, destreg, reg, reg, correctval, val, val, swreg, offset, \
+        inst destreg, reg; \
+        )
+
+#define TEST_FPD_4REG(test_num, inst, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset) \
+      TEST_CASE_FPD_4REG(test_num, destreg, reg1, reg2, reg3, correctval, val1, val2, val3, swreg, offset, \
+        inst destreg, reg1, reg2, reg3; \
+        )
+
+#define TEST_FPD_I(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FPD_I(test_num, destreg, reg, correctval, val, swreg, offset, \
+        li reg, MASK_XLEN(val); \
+        inst destreg, reg; \
+        )
+
+#define TEST_FPD_I2(test_num, inst, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FPD_I2(test_num, destreg, reg, correctval, val, swreg, offset, \
+        inst destreg, reg; \
+        )
+
+#define TEST_CADDI16SP(correctval, imm, swreg, offset) \
+      TEST_CASE(x2, correctval, swreg, offset, \
+      c.addi16sp x2, imm; \
+      )
+
+#define TEST_CADDI4SPN(destreg, correctval, imm, swreg, offset) \
+      TEST_CASE(destreg, correctval, swreg, offset, \
+        c.addi4spn destreg, x2, SEXT_IMM(imm); \
+        )
+
+#define TEST_CJL(inst, reg, val, swreg, offset) \
+      li x10, val; \
+      la reg, 1f; \
+      inst reg; \
+      li x10, 0x123ab; \
+1: \
+      sw x10, offset(swreg); \
+      RVTEST_IO_ASSERT_GPR_EQ(x31, x10, val); \
+
+#define ABS(x) ((x >> 11) ^ x) - (x >> 11)
+
+#define TEST_CJ(inst, reg, val, swreg, offset) \
+      li reg, val; \
+      inst 1f; \
+      li reg, 0x123ab; \
+1: \
+      sw reg, offset(swreg); \
+      RVTEST_IO_ASSERT_GPR_EQ(x31, reg, val); \
+
+#define TEST_CL(inst, reg, imm, swreg, offset) \
+      la reg, test_data; \
+      inst reg, imm(reg); \
+      sw reg, offset(swreg); \
+
+// lw reg, imm(x2)
+// c.lwsp reg, imm(x2)
+#define TEST_CLWSP(reg, imm, swreg, offset) \
+      la x2, test_data; \
+      c.lwsp reg, imm(x2); \
+      sw reg, offset(swreg); \
+
+#define TEST_CSW(test_data, inst, reg1, reg2, val, imm, swreg, offset) \
+      li reg1, val; \
+      la reg2, test_data; \
+      inst reg1, imm(reg2); \
+      lw reg1, imm(reg2); \
+      sw reg1, offset(swreg); \
+      RVTEST_IO_ASSERT_GPR_EQ(x31, reg1, val); \
+
+#define TEST_CSWSP(test_data, reg, val, imm, swreg, offset) \
+      la x2, test_data; \
+      li reg, val; \
+      c.swsp reg, imm(x2); \
+      lw reg, imm(x2); \
+      sw reg, offset(swreg); \
+      RVTEST_IO_ASSERT_GPR_EQ(x31, reg, val); \
+
+#define TEST_CBEQZ(reg, val, swreg, offset) \
+      li reg, val; \
+      c.sub reg, reg; \
+      c.beqz reg, 3f; \
+      li reg, 0x123ab; \
+3: \
+      sw reg, offset(swreg); \
+      RVTEST_IO_ASSERT_GPR_EQ(x31, reg, 0x0); \
+
+#define TEST_CBNEZ(reg, val, swreg, offset) \
+      li reg, val; \
+      c.bnez reg, 4f; \
+      li reg, 0x0; \
+4: \
+      sw reg, offset(swreg); \
+      RVTEST_IO_ASSERT_GPR_EQ(x31, reg, val); \
+
+#define TEST_FMVXS(test_num, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FP_FMVXS(test_num, destreg, reg, correctval, val, swreg, offset, \
+        fmv.x.s destreg, reg; \
+        )
+
+#define TEST_FMVSX(test_num, destreg, reg, correctval, val, swreg, offset) \
+      TEST_CASE_FP_FMVSX(test_num, destreg, reg, correctval, val, swreg, offset, \
+        fmv.s.x destreg, reg; \
+        )
+
+#define SWSIG(a,b)
+
+
+#if __riscv_xlen == 64
+#define SATP_MODE SATP64_MODE
+#else
+#define SATP_MODE SATP32_MODE
+#endif
+
+#define SATP32_MODE         0x80000000
+#define SATP32_ASID         0x7FC00000
+#define SATP32_PPN          0x003FFFFF
+#define SATP64_MODE 0xF000000000000000
+#define SATP64_ASID 0x0FFFF00000000000
+#define SATP64_PPN  0x00000FFFFFFFFFFF
+
+#define SATP_MODE_OFF                0
+#define SATP_MODE_SV32               1
+#define SATP_MODE_SV39               8
+#define SATP_MODE_SV48               9
+#define SATP_MODE_SV57              10
+#define SATP_MODE_SV64              11
+
+#define TEST_FP_OP2_D32( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \
+                    inst f3, f0, f1; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
+#define TEST_CASE_D32( testnum, testreg1, testreg2, correctval, code... ) \
+test_ ## testnum: \
+    code; \
+    la  x31, test_ ## testnum ## _data ; \
+    lw  x29, 0(x31); \
+    lw  x31, 4(x31); \
+    li  TESTNUM, testnum; \
+    bne testreg1, x29, fail;\
+    bne testreg2, x31, fail;\
+    .pushsection .data; \
+    .balign 8; \
+    test_ ## testnum ## _data: \
+    .dword correctval; \
+    .popsection
+
+#define TEST_FP_OP_D32_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  la  a0, test_ ## testnum ## _data ;\
+  fld f0, 0(a0); \
+  fld f1, 8(a0); \
+  fld f2, 16(a0); \
+  lw  a3, 24(a0); \
+  lw  t1, 28(a0); \
+  code; \
+  fsflags a1, x0; \
+  li a2, flags; \
+  bne a0, a3, fail; \
+  bne t1, t2, fail; \
+  bne a1, a2, fail; \
+  .pushsection .data; \
+  .balign 8; \
+  test_ ## testnum ## _data: \
+  .double val1; \
+  .double val2; \
+  .double val3; \
+  .result; \
+  .popsection
+
+#define TEST_FP_OP1_D32( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \
+                    inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
+#define TEST_FCLASS_D32(testnum, correct, input) \
+  TEST_CASE(testnum, a0, correct, \
+            la a0, test_ ## testnum ## _data ;\
+            fld fa0, 0(a0); \
+            fclass.d a0, fa0) \
+    .pushsection .data; \
+    .balign 8; \
+    test_ ## testnum ## _data: \
+    .dword input; \
+    .popsection
+
+#define TEST_FP_CMP_OP_D32( testnum, inst, flags, result, val1, val2 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \
+                    inst a0, f0, f1; li t2, 0)
+
+#define TEST_INT_FP_OP_D32( testnum, inst, result, val1 ) \
+test_ ## testnum: \
+  li  TESTNUM, testnum; \
+  la  a0, test_ ## testnum ## _data ;\
+  lw  a3, 0(a0); \
+  lw  a4, 4(a0); \
+  li  a1, val1; \
+  inst f0, a1; \
+  \
+  fsd f0, 0(a0); \
+  lw a1, 4(a0); \
+  lw a0, 0(a0); \
+  \
+  fsflags x0; \
+  bne a0, a3, fail; \
+  bne a1, a4, fail; \
+  .pushsection .data; \
+  .balign 8; \
+  test_ ## testnum ## _data: \
+  .double result; \
+  .popsection
+
+#define TEST_FCVT_S_D32( testnum, result, val1 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \
+                    fcvt.s.d f3, f0; fcvt.d.s f3, f3; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
+#define TEST_FP_OP3_D32( testnum, inst, flags, result, val1, val2, val3 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, val3, \
+                    inst f3, f0, f1, f2; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
+#define TEST_FP_OP1_D32_DWORD_RESULT( testnum, inst, flags, result, val1 ) \
+  TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \
+                    inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0))
+
+
+#endif
diff --git a/verilog/dv/riscv_regress/tests/riscv_isa/Makefile b/verilog/dv/riscv_regress/tests/riscv_isa/Makefile
new file mode 100644
index 0000000..2f0fa3f
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/riscv_isa/Makefile
@@ -0,0 +1,96 @@
+
+include rv32_tests.inc
+
+ARCH_tmp := imf
+
+ifneq (,$(findstring c,$(ARCH_lowercase)))
+	ARCH_tmp := $(ARCH_tmp)c
+endif
+
+override ARCH := $(ARCH_tmp)
+
+src_dir := $(CURDIR)
+obj_dir   := $(bld_dir)/riscv_objs
+test_list := $(patsubst %.S, %, $(notdir $(rv32_isa_tests)))
+objs      := $(addprefix $(obj_dir)/,$(test_list:%=%.o))
+test_elf  := $(addprefix $(bld_dir)/,$(test_list:%=%.elf))
+test_hex  := $(addprefix $(bld_dir)/,$(test_list:%=%.hex))
+test_dump := $(addprefix $(bld_dir)/,$(test_list:%=%.dump))
+
+CFLAGS := -I$(inc_dir) -I$(src_dir) -DASM -Wa,-march=rv32$(ARCH) -march=rv32$(ARCH) -mabi=ilp32f -D__riscv_xlen=32
+LDFLAGS := -static -fvisibility=hidden -nostdlib -nostartfiles -T$(inc_dir)/link.ld -march=rv32$(ARCH) -mabi=ilp32f
+RISCV_TESTS := $(src_dir)/../../dependencies/riscv-tests/
+
+VPATH += $(src_dir) $(bld_dir) $(obj_dir) $(RISCV_TESTS)
+
+default: log_requested_tgt check_riscv_tests $(test_elf) $(test_hex) $(test_dump)
+
+define compile_template
+$(obj_dir)/$$(basename $(notdir $(SRC))).o: $$(SRC) | $(obj_dir)
+	$(RISCV_GCC) -c $$< $(CFLAGS) -o $$@
+ endef
+
+$(foreach SRC,$(rv32_isa_tests), $(eval $(compile_template)))
+
+log_requested_tgt:
+	$(foreach test_name, $(test_list), $(eval $(shell echo $(test_name).hex >> $(bld_dir)/test_info)))
+
+$(obj_dir) :
+	mkdir -p $(obj_dir)
+
+$(bld_dir)/%.elf: $(obj_dir)/%.o | $(obj_dir)
+	$(RISCV_GCC) $^ $(LDFLAGS) -o $@
+
+$(bld_dir)/%.hex: $(bld_dir)/%.elf
+	$(RISCV_ROM_OBJCOPY) $^ $@
+	$(RISCV_RAM_OBJCOPY) $^ $@.ram
+	#assign 0x0800_0xxx  to 0x0000_0xxx to map to TCM Memory
+	sed -i 's/@08000/@00000/g' $@.ram
+
+$(bld_dir)/%.dump: $(bld_dir)/%.elf
+	$(RISCV_OBJDUMP) $^ > $@
+
+clean:
+	$(RM) $(test_elf) $(test_hex) $(test_dump) $(objs)
+	$(RM) -R $(obj_dir)
+
+
+.PHONY: check_riscv_tests
+
+riscv_tests_dir    := $(if $(RISCV_TESTS), $(RISCV_TESTS), ./undefined)
+riscv_tests_commit := 5f8a4918c6482e65c67a2b7decd5c2af3e3fe0e5
+## commit hash readed from local copy of https://github.com/riscv/riscv-tests
+tmp_commit = $(shell cd $(riscv_tests_dir) 2>/dev/null && git log -1 | grep "commit" | cut -f2 -d ' ')
+is_commit_good = $(if $(subst $(riscv_tests_commit),,$(tmp_commit)),false,true)
+
+# Color
+RED=\033[0;31m
+NC=\033[0m
+
+check_riscv_tests : $(riscv_tests_dir)
+	@if [ ! -d $(riscv_tests_dir) ]; then \
+		echo -e "$(RED)==========================================================================" &&\
+		echo "   Error! Environment variable RISCV_TESTS='$(riscv_tests_dir)' " &&\
+		echo "      directory not exist!" && \
+		echo "==========================================================================$(NC)" ; \
+	fi
+ifneq ($(is_commit_good),true)
+	@echo -e "$(RED)=========================================================================="
+	@echo "   Warning! Execution of test code is not guaranteed "
+	@echo "   while using the current commit of repositorylocated at : $(riscv_tests_dir) ."
+	@echo "   "
+	@echo "   Riscv-tests repository must point to commit $(riscv_tests_commit)!"
+	@echo -e "==========================================================================$(NC)"
+endif
+
+$(riscv_tests_dir) :.
+ifndef RISCV_TESTS
+	@echo -e "$(RED)=========================================================================="
+	@echo "    Error! Environment variable RISCV_TESTS not set!"
+	@echo "    You must set the environment variable RISCV_TESTS"
+	@echo "    The variable should point to the local copy of the"
+	@echo "      repository https://github.com/riscv/riscv-tests"
+	@echo "      with the commit $(riscv_tests_commit)"
+	@echo -e "==========================================================================$(NC)"
+	exit 1
+endif
diff --git a/verilog/dv/riscv_regress/tests/riscv_isa/riscv_test.h b/verilog/dv/riscv_regress/tests/riscv_isa/riscv_test.h
new file mode 100644
index 0000000..2b9ce0d
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/riscv_isa/riscv_test.h
@@ -0,0 +1,6 @@
+#ifndef __RISCV__TEST__H
+#define __RISCV__TEST__H
+
+#include "riscv_macros.h" 
+
+#endif // #ifndef __RISCV__TEST__H
diff --git a/verilog/dv/riscv_regress/tests/riscv_isa/rv32_tests.inc b/verilog/dv/riscv_regress/tests/riscv_isa/rv32_tests.inc
new file mode 100644
index 0000000..62e5012
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/riscv_isa/rv32_tests.inc
@@ -0,0 +1,66 @@
+
+ARCH_lowercase = $(shell echo $(ARCH) | tr A-Z a-z)
+
+
+rv32_isa_tests += isa/rv32ui/add.S      \
+              isa/rv32ui/addi.S         \
+              isa/rv32ui/and.S          \
+              isa/rv32ui/andi.S         \
+              isa/rv32ui/auipc.S        \
+              isa/rv32ui/beq.S          \
+              isa/rv32ui/bge.S          \
+              isa/rv32ui/bgeu.S         \
+              isa/rv32ui/blt.S          \
+              isa/rv32ui/bltu.S         \
+              isa/rv32ui/bne.S          \
+              isa/rv32mi/csr.S          \
+              isa/rv32ui/fence_i.S      \
+              isa/rv32mi/illegal.S      \
+              isa/rv32ui/jal.S          \
+              isa/rv32ui/jalr.S         \
+              isa/rv32ui/lb.S           \
+              isa/rv32ui/lbu.S          \
+              isa/rv32ui/lh.S           \
+              isa/rv32ui/lhu.S          \
+              isa/rv32ui/lui.S          \
+              isa/rv32ui/lw.S           \
+              isa/rv32mi/ma_addr.S      \
+              isa/rv32mi/ma_fetch.S     \
+              isa/rv32mi/mcsr.S         \
+              isa/rv32ui/or.S           \
+              isa/rv32ui/ori.S          \
+              isa/rv32ui/sb.S           \
+              isa/rv32mi/sbreak.S       \
+              isa/rv32mi/scall.S        \
+              isa/rv32ui/sh.S           \
+              isa/rv32mi/shamt.S        \
+              isa/rv32ui/simple.S       \
+              isa/rv32ui/sll.S          \
+              isa/rv32ui/slli.S         \
+              isa/rv32ui/slt.S          \
+              isa/rv32ui/slti.S         \
+              isa/rv32ui/sltiu.S        \
+              isa/rv32ui/sltu.S         \
+              isa/rv32ui/sra.S          \
+              isa/rv32ui/srai.S         \
+              isa/rv32ui/srl.S          \
+              isa/rv32ui/srli.S         \
+              isa/rv32ui/sub.S          \
+              isa/rv32ui/sw.S           \
+              isa/rv32ui/xor.S          \
+              isa/rv32ui/xori.S
+
+ifneq (,$(findstring m,$(ARCH_lowercase)))
+rv32_isa_tests += isa/rv32um/div.S      \
+              isa/rv32um/divu.S         \
+              isa/rv32um/mul.S          \
+              isa/rv32um/mulh.S         \
+              isa/rv32um/mulhsu.S       \
+              isa/rv32um/mulhu.S        \
+              isa/rv32um/rem.S          \
+              isa/rv32um/remu.S
+endif ## ifeq (m,$(findstring m,$(ARCH_lowercase)))
+
+ifneq (,$(findstring c,$(ARCH_lowercase)))
+rv32_isa_tests += isa/rv32uc/rvc.S
+endif ## ifeq (m,$(findstring c,$(ARCH_lowercase)))
\ No newline at end of file
diff --git a/verilog/dv/riscv_regress/tests/riscv_isa/test_macros.h b/verilog/dv/riscv_regress/tests/riscv_isa/test_macros.h
new file mode 100644
index 0000000..743918d
--- /dev/null
+++ b/verilog/dv/riscv_regress/tests/riscv_isa/test_macros.h
@@ -0,0 +1,5 @@
+#ifndef __TEST__MACROS__H
+#define __TEST__MACROS__H
+
+
+#endif
diff --git a/verilog/dv/riscv_regress/user_risc_regress_tb.v b/verilog/dv/riscv_regress/user_risc_regress_tb.v
new file mode 100644
index 0000000..ca9ee0a
--- /dev/null
+++ b/verilog/dv/riscv_regress/user_risc_regress_tb.v
@@ -0,0 +1,537 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  Standalone User validation Test bench                       ////
+////                                                              ////
+////  This file is part of the YIFive cores project               ////
+////  https://github.com/dineshannayya/yifive_r0.git              ////
+////  http://www.opencores.org/cores/yifive/                      ////
+////                                                              ////
+////  Description                                                 ////
+////   This is a standalone test bench to validate the            ////
+////   Digital core.                                              ////
+////   1. User Risc core is booted using  compiled code of        ////
+////      user_risc_boot.c                                        ////
+////   2. User Risc core uses Serial Flash and SDRAM to boot      ////
+////   3. After successful boot, Risc core will  write signature  ////
+////      in to  user register from 0x3000_0018 to 0x3000_002C    ////
+////   4. Through the External Wishbone Interface we read back    ////
+////       and validate the user register to declared pass fail   ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      - Dinesh Annayya, dinesha@opencores.org                 ////
+////                                                              ////
+////  Revision :                                                  ////
+////    0.1 - 16th Feb 2021, Dinesh A                             ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+`default_nettype wire
+
+`timescale 1 ns / 1 ns
+
+`include "s25fl256s.sv"
+`include "uprj_netlists.v"
+`include "mt48lc8m8a2.v"
+`include "spiram.v"
+
+localparam [31:0]      YCR1_SIM_EXIT_ADDR      = 32'h0000_00F8;
+localparam [31:0]      YCR1_SIM_PRINT_ADDR     = 32'hF000_0000;
+localparam [31:0]      YCR1_SIM_EXT_IRQ_ADDR   = 32'hF000_0100;
+localparam [31:0]      YCR1_SIM_SOFT_IRQ_ADDR  = 32'hF000_0200;
+
+ `define QSPIM_GLBL_CTRL          32'h10000000
+ `define QSPIM_DMEM_G0_RD_CTRL    32'h10000004
+ `define QSPIM_DMEM_G0_WR_CTRL    32'h10000008
+ `define QSPIM_DMEM_G1_RD_CTRL    32'h1000000C
+ `define QSPIM_DMEM_G1_WR_CTRL    32'h10000010
+
+ `define QSPIM_DMEM_CS_AMAP        32'h10000014
+ `define QSPIM_DMEM_CA_AMASK       32'h10000018
+
+ `define QSPIM_IMEM_CTRL1          32'h1000001C
+ `define QSPIM_IMEM_CTRL2          32'h10000020
+ `define QSPIM_IMEM_ADDR           32'h10000024
+ `define QSPIM_IMEM_WDATA          32'h10000028
+ `define QSPIM_IMEM_RDATA          32'h1000002C
+ `define QSPIM_SPI_STATUS          32'h10000030
+
+module user_risc_regress_tb;
+	reg clock;
+	reg wb_rst_i;
+	reg power1, power2;
+	reg power3, power4;
+
+        reg        wbd_ext_cyc_i;  // strobe/request
+        reg        wbd_ext_stb_i;  // strobe/request
+        reg [31:0] wbd_ext_adr_i;  // address
+        reg        wbd_ext_we_i;  // write
+        reg [31:0] wbd_ext_dat_i;  // data output
+        reg [3:0]  wbd_ext_sel_i;  // byte enable
+
+        wire [31:0] wbd_ext_dat_o;  // data input
+        wire        wbd_ext_ack_o;  // acknowlegement
+        wire        wbd_ext_err_o;  // error
+	wire        clk;
+
+	// User I/O
+	wire [37:0] io_oeb;
+	wire [37:0] io_out;
+	wire [37:0] io_in;
+
+	wire gpio;
+	wire [37:0] mprj_io;
+	wire [7:0] mprj_io_0;
+	reg         test_fail;
+	reg [31:0] read_data;
+
+
+	int unsigned                f_results;
+        int unsigned                f_info;
+        
+        string                      s_results;
+        string                      s_info;
+        `ifdef SIGNATURE_OUT
+        string                      s_testname;
+        bit                         b_single_run_flag;
+        `endif  //  SIGNATURE_OUT
+
+
+	`ifdef VERILATOR
+         logic [255:0]          test_file;
+	 logic [255:0]          test_ram_file;
+         `else // VERILATOR
+         string                 test_file;
+	 string                 test_ram_file;
+
+         `endif // VERILATOR
+
+
+        event	               reinit_event;
+	bit                    test_running;
+        int unsigned           tests_passed;
+        int unsigned           tests_total;
+
+	logic  [7:0]           tem_mem[0:4095];
+	logic  [31:0]          mem_data;
+
+
+parameter P_FSM_C      = 4'b0000; // Command Phase Only
+parameter P_FSM_CW     = 4'b0001; // Command + Write DATA Phase Only
+parameter P_FSM_CA     = 4'b0010; // Command -> Address Phase Only
+
+parameter P_FSM_CAR    = 4'b0011; // Command -> Address -> Read Data
+parameter P_FSM_CADR   = 4'b0100; // Command -> Address -> Dummy -> Read Data
+parameter P_FSM_CAMR   = 4'b0101; // Command -> Address -> Mode -> Read Data
+parameter P_FSM_CAMDR  = 4'b0110; // Command -> Address -> Mode -> Dummy -> Read Data
+
+parameter P_FSM_CAW    = 4'b0111; // Command -> Address ->Write Data
+parameter P_FSM_CADW   = 4'b1000; // Command -> Address -> DUMMY + Write Data
+parameter P_FSM_CAMW   = 4'b1001; // Command -> Address -> MODE + Write Data
+
+parameter P_FSM_CDR    = 4'b1010; // COMMAND -> DUMMY -> READ
+parameter P_FSM_CDW    = 4'b1011; // COMMAND -> DUMMY -> WRITE
+parameter P_FSM_CR     = 4'b1100;  // COMMAND -> READ
+
+parameter P_MODE_SWITCH_IDLE     = 2'b00;
+parameter P_MODE_SWITCH_AT_ADDR  = 2'b01;
+parameter P_MODE_SWITCH_AT_DATA  = 2'b10;
+
+parameter P_SINGLE = 2'b00;
+parameter P_DOUBLE = 2'b01;
+parameter P_QUAD   = 2'b10;
+parameter P_QDDR   = 2'b11;
+	//-----------------------------------------------------------------
+	// Since this is regression, reset will be applied multiple time
+	// Reset logic
+	// ----------------------------------------------------------------
+	bit [1:0]     rst_cnt;
+        bit           rst_init;
+	wire          rst_n;
+
+
+        assign rst_n = &rst_cnt;
+	assign wb_rst_i    =  !rst_n;
+        
+        always_ff @(posedge clk) begin
+	if (rst_init)   begin
+	     rst_cnt <= '0;
+	     -> reinit_event;
+	end
+            else if (~&rst_cnt) rst_cnt <= rst_cnt + 1'b1;
+        end
+
+	// External clock is used by default.  Make this artificially fast for the
+	// simulation.  Normally this would be a slow clock and the digital PLL
+	// would be the fast clock.
+
+	always #12.5 clock <= (clock === 1'b0);
+
+	assign clk = clock;
+
+	initial begin
+		clock = 0;
+                wbd_ext_cyc_i ='h0;  // strobe/request
+                wbd_ext_stb_i ='h0;  // strobe/request
+                wbd_ext_adr_i ='h0;  // address
+                wbd_ext_we_i  ='h0;  // write
+                wbd_ext_dat_i ='h0;  // data output
+                wbd_ext_sel_i ='h0;  // byte enable
+	end
+
+	`ifdef WFDUMP
+	   initial begin
+	   	$dumpfile("simx.vcd");
+	   	$dumpvars(1, user_risc_regress_tb);
+	   	$dumpvars(1, user_risc_regress_tb.u_top);
+	   	$dumpvars(0, user_risc_regress_tb.u_top.u_riscv_top);
+	   	$dumpvars(0, user_risc_regress_tb.u_top.u_qspi_master);
+	   	$dumpvars(0, user_risc_regress_tb.u_top.u_intercon);
+	   	$dumpvars(0, user_risc_regress_tb.u_top.u_mbist);
+	   end
+       `endif
+
+        integer i;
+
+        always @reinit_event
+	begin
+		// Initialize the SPI memory with hex content
+		// Wait for reset removal
+		wait (rst_n == 1);
+
+
+		// Initialize the SPI memory with hex content
+                $write("\033[0;34m---Initializing the SPI Memory with Hexfile: %s\033[0m\n", test_file);
+                $readmemh(test_file,u_spi_flash_256mb.Mem);
+
+		// some of the RISCV test need SRAM area for specific
+		// instruction execution like fence
+		$sformat(test_ram_file, "%s.ram",test_file);
+                $readmemh(test_ram_file,u_sram.memory);
+
+		/***
+		// Split the Temp memory content to two sram file
+                $readmemh(test_ram_file,tem_mem);
+		// Load the SRAM0/SRAM1 with 2KB data
+                $write("\033[0;34m---Initializing the u_sram0_2kb Memory with Hexfile: %s\033[0m\n",test_ram_file);
+		// Initializing the SRAM
+		for(i = 0 ; i < 2048; i = i +4) begin
+		    mem_data = {tem_mem[i+3],tem_mem[i+2],tem_mem[i+1],tem_mem[i+0]};
+		    //$display("Filling Mem Location : %x with data : %x",i, mem_data);
+		    u_top.u_sram0_2kb.mem[i/4] = mem_data;
+		end
+		for(i = 2048 ; i < 4096; i = i +4) begin
+		  mem_data = {tem_mem[i+3],tem_mem[i+2],tem_mem[i+1],tem_mem[i+0]};
+		  //$display("Filling Mem Location : %x with data : %x",i, mem_data);
+		  u_top.u_sram1_2kb.mem[(2048-i)/4] = mem_data;
+		end
+		***/
+
+		//for(i =32'h00; i < 32'h100; i = i+1)
+                //    $display("Location: %x, Data: %x", i, u_top.u_tsram0_2kb.mem[i]);
+
+
+		#200; 
+	        repeat (10) @(posedge clock);
+		$display("Monitor: Core reset removal");
+
+		// Remove Wb Reset
+		wb_user_core_write('h3080_0000,'h1);
+	        repeat (2) @(posedge clock);
+		#1;
+		//------------ fuse_mhartid= 0x00
+                wb_user_core_write('h3002_0004,'h0);
+
+
+	        repeat (2) @(posedge clock);
+		#1;
+		// Remove WB and SPI Reset, Keep SDARM and CORE under Reset
+                wb_user_core_write('h3080_0000,'h5);
+
+		// CS#2 Switch to QSPI Mode
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0100});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h0,2'b00,2'b00,P_FSM_C,8'h00,8'h38});
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h0);
+
+		// Enable the DCACHE Remap to SRAM region
+		//wb_user_core_write('h3080_000C,{4'b0000,4'b1111, 24'h0});
+		//
+		// Remove all the reset
+                wb_user_core_write('h3080_0000,'h8F);
+
+	end
+
+wire USER_VDD1V8 = 1'b1;
+wire VSS = 1'b0;
+
+//-------------------------------------------------------------------------------
+// Run tests
+//-------------------------------------------------------------------------------
+
+`include "riscv_runtests.sv"
+
+
+//-------------------------------------------------------------------------------
+// Core instance
+//-------------------------------------------------------------------------------
+
+user_project_wrapper u_top(
+`ifdef USE_POWER_PINS
+    .vccd1(USER_VDD1V8),	// User area 1 1.8V supply
+    .vssd1(VSS),	// User area 1 digital ground
+`endif
+    .wb_clk_i        (clock),  // System clock
+    .user_clock2     (1'b1),  // Real-time clock
+    .wb_rst_i        (wb_rst_i),  // Regular Reset signal
+
+    .wbs_cyc_i   (wbd_ext_cyc_i),  // strobe/request
+    .wbs_stb_i   (wbd_ext_stb_i),  // strobe/request
+    .wbs_adr_i   (wbd_ext_adr_i),  // address
+    .wbs_we_i    (wbd_ext_we_i),  // write
+    .wbs_dat_i   (wbd_ext_dat_i),  // data output
+    .wbs_sel_i   (wbd_ext_sel_i),  // byte enable
+
+    .wbs_dat_o   (wbd_ext_dat_o),  // data input
+    .wbs_ack_o   (wbd_ext_ack_o),  // acknowlegement
+
+ 
+    // Logic Analyzer Signals
+    .la_data_in      ('1) ,
+    .la_data_out     (),
+    .la_oenb         ('0),
+ 
+
+    // IOs
+    .io_in          (io_in)  ,
+    .io_out         (io_out) ,
+    .io_oeb         (io_oeb) ,
+
+    .user_irq       () 
+
+);
+
+
+logic [31:0] riscv_dmem_req_cnt; // cnt dmem req
+initial 
+begin
+   riscv_dmem_req_cnt = 0;
+end
+
+always @(posedge u_top.wbd_riscv_dmem_stb_i)
+begin
+    riscv_dmem_req_cnt = riscv_dmem_req_cnt+1;
+    if((riscv_dmem_req_cnt %200) == 0)
+	$display("STATUS: Total Dmem Req Cnt: %d ",riscv_dmem_req_cnt);
+end
+
+
+`ifndef GL // Drive Power for Hold Fix Buf
+    // All standard cell need power hook-up for functionality work
+    initial begin
+    end
+`endif    
+
+//------------------------------------------------------
+//  Integrate the Serial flash with qurd support to
+//  user core using the gpio pads
+//  ----------------------------------------------------
+
+   wire flash_clk = io_out[24];
+   wire flash_csb = io_out[28];
+   // Creating Pad Delay
+   wire #1 io_oeb_29 = io_oeb[29];
+   wire #1 io_oeb_30 = io_oeb[30];
+   wire #1 io_oeb_31 = io_oeb[31];
+   wire #1 io_oeb_32 = io_oeb[32];
+   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[29] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[30] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[31] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[32] : 1'bz;
+
+   assign io_in[29] = flash_io0;
+   assign io_in[30] = flash_io1;
+   assign io_in[31] = flash_io2;
+   assign io_in[32] = flash_io3;
+
+
+   // Quard flash
+     s25fl256s #(.mem_file_name("add.hex"),
+	         .otp_file_name("none"),
+                 .TimingModel("S25FL512SAGMFI010_F_30pF")) 
+		 u_spi_flash_256mb (
+           // Data Inputs/Outputs
+       .SI      (flash_io0),
+       .SO      (flash_io1),
+       // Controls
+       .SCK     (flash_clk),
+       .CSNeg   (flash_csb),
+       .WPNeg   (flash_io2),
+       .HOLDNeg (flash_io3),
+       .RSTNeg  (!wb_rst_i)
+
+       );
+
+
+   wire spiram_csb = io_out[26];
+
+   spiram #(.mem_file_name("none"))
+	u_sram (
+         // Data Inputs/Outputs
+           .io0     (flash_io0),
+           .io1     (flash_io1),
+           // Controls
+           .clk    (flash_clk),
+           .csb    (spiram_csb),
+           .io2    (flash_io2),
+           .io3    (flash_io3)
+    );
+
+
+
+task wb_user_core_write;
+input [31:0] address;
+input [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h1;  // write
+  wbd_ext_dat_i =data;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("DEBUG WB USER ACCESS WRITE Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read;
+input [31:0] address;
+output [31:0] data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("DEBUG WB USER ACCESS READ Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+`ifdef GL
+
+wire        wbd_spi_stb_i   = u_top.u_spi_master.wbd_stb_i;
+wire        wbd_spi_ack_o   = u_top.u_spi_master.wbd_ack_o;
+wire        wbd_spi_we_i    = u_top.u_spi_master.wbd_we_i;
+wire [31:0] wbd_spi_adr_i   = u_top.u_spi_master.wbd_adr_i;
+wire [31:0] wbd_spi_dat_i   = u_top.u_spi_master.wbd_dat_i;
+wire [31:0] wbd_spi_dat_o   = u_top.u_spi_master.wbd_dat_o;
+wire [3:0]  wbd_spi_sel_i   = u_top.u_spi_master.wbd_sel_i;
+
+wire        wbd_sdram_stb_i = u_top.u_sdram_ctrl.wb_stb_i;
+wire        wbd_sdram_ack_o = u_top.u_sdram_ctrl.wb_ack_o;
+wire        wbd_sdram_we_i  = u_top.u_sdram_ctrl.wb_we_i;
+wire [31:0] wbd_sdram_adr_i = u_top.u_sdram_ctrl.wb_addr_i;
+wire [31:0] wbd_sdram_dat_i = u_top.u_sdram_ctrl.wb_dat_i;
+wire [31:0] wbd_sdram_dat_o = u_top.u_sdram_ctrl.wb_dat_o;
+wire [3:0]  wbd_sdram_sel_i = u_top.u_sdram_ctrl.wb_sel_i;
+
+wire        wbd_uart_stb_i  = u_top.u_uart_i2c_usb.reg_cs;
+wire        wbd_uart_ack_o  = u_top.u_uart_i2c_usb.reg_ack;
+wire        wbd_uart_we_i   = u_top.u_uart_i2c_usb.reg_wr;
+wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_i2c_usb.reg_addr;
+wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_i2c_usb.reg_wdata;
+wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_i2c_usb.reg_rdata;
+wire        wbd_uart_sel_i  = u_top.u_uart_i2c_usb.reg_be;
+
+`endif
+
+/**
+`ifdef GL
+//-----------------------------------------------------------------------------
+// RISC IMEM amd DMEM Monitoring TASK
+//-----------------------------------------------------------------------------
+
+`define RISC_CORE  user_uart_tb.u_top.u_core.u_riscv_top
+
+always@(posedge `RISC_CORE.wb_clk) begin
+    if(`RISC_CORE.wbd_imem_ack_i)
+          $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x", `RISC_CORE.wbd_imem_adr_o,`RISC_CORE.wbd_imem_dat_i);
+    if(`RISC_CORE.wbd_dmem_ack_i && `RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_o);
+    if(`RISC_CORE.wbd_dmem_ack_i && !`RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_i);
+end
+
+`endif
+**/
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/uart_master/Makefile b/verilog/dv/uart_master/Makefile
new file mode 100644
index 0000000..ec6f963
--- /dev/null
+++ b/verilog/dv/uart_master/Makefile
@@ -0,0 +1,120 @@
+# 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
+
+## PDK 
+PDK_PATH = $(PDK_ROOT)/sky130A
+
+## 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_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_BEHAVIOURAL_AGENTS = ../agents
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/yifive/ycr1c/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include
+## RISCV GCC 
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+GCC64_PREFIX?=riscv64-unknown-elf
+
+## Simulation mode: RTL/GL
+SIM_DEFINES = -DFUNCTIONAL -DSIM
+SIM?=RTL
+DUMP?=OFF
+
+.SUFFIXES:
+
+PATTERN = uart_master
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v %.hex
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2005-sv $(SIM_DEFINES) -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+    else  
+	iverilog -g2005-sv -DWFDUMP $(SIM_DEFINES) -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+   endif
+else  
+	iverilog $(SIM_DEFINES) -DGL -I $(PDK_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS) -I$(UPRJ_GL_PATH)  -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 check-env
+	${GCC64_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
+	${GCC64_PREFIX}-objcopy -O verilog $< $@ 
+	# to fix flash base address
+	sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+	${GCC64_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+check-env:
+ifndef PDK_ROOT
+	$(error PDK_ROOT is undefined, please export it before running make)
+endif
+ifeq (,$(wildcard $(PDK_ROOT)/sky130A))
+	$(error $(PDK_ROOT)/sky130A not found, please install pdk before running make)
+endif
+#ifeq (,$(wildcard $(GCC64_PREFIX)-gcc ))
+#	$(error $(GCC64_PREFIX)-gcc is not found, please export GCC_PATH and GCC_PREFIX before running make)
+#endif
+# check for efabless style installation
+ifeq (,$(wildcard $(PDK_ROOT)/sky130A/libs.ref/*/verilog))
+SIM_DEFINES := ${SIM_DEFINES} -DEF_STYLE
+endif
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
diff --git a/verilog/dv/uart_master/run_verilog b/verilog/dv/uart_master/run_verilog
new file mode 100644
index 0000000..5ffed3c
--- /dev/null
+++ b/verilog/dv/uart_master/run_verilog
@@ -0,0 +1,20 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# // 
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# //      http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+
+#iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I /home/dinesha/workarea/pdk/sky130A -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog/dv/caravel -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog/rtl -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog -I ../ -I../../../verilog/rtl -I../../../verilog/gl  -I ../../../verilog wb_port_tb.v -o wb_port.vvp
+iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -DGL -I /home/dinesha/workarea/pdk/sky130A -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog/dv/caravel -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog/rtl -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog -I ../ -I../../../verilog/rtl -I../../../verilog/gl  -I ../../../verilog wb_port_tb.v -o wb_port.vvp
diff --git a/verilog/dv/uart_master/uart_master.c b/verilog/dv/uart_master/uart_master.c
new file mode 100644
index 0000000..1f5912a
--- /dev/null
+++ b/verilog/dv/uart_master/uart_master.c
@@ -0,0 +1,156 @@
+/*
+ * 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 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;
+int uart_cfg = 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;
+
+
+    reg_la0_oenb = reg_la0_iena =  0x0000000;
+     /* Apply configuration */
+    reg_mprj_xfer = 1;
+    while (reg_mprj_xfer == 1);
+    reg_mprj_datal = 0xAB600000;
+
+    reg_la0_oenb = reg_la0_iena =  0x0000000;
+
+    //-----------------------------------------------------
+    // 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);
+
+    reg_la0_data = 0x000;
+    //reg_la0_data = 0x000;
+    //reg_la0_data |= 0x1; // bit[0] - Remove Software Reset
+    //reg_la0_data |= 0x1; // bit[1] - Enable Transmit Path
+    //reg_la0_data |= 0x2; // bit[2] - Enable Receive Path
+    //reg_la0_data |= 0x4; // bit[3] - Set 2 Stop Bit
+    //reg_la0_data |= 0x0; // bit[15:4] - 16x Baud Clock
+    //reg_la0_data |= 0x0; // bit[17:16] - Priority mode = 0
+    reg_la0_data = 0x001;
+    reg_la0_data = 0x00F;
+
+
+
+}
diff --git a/verilog/dv/uart_master/uart_master_tb.v b/verilog/dv/uart_master/uart_master_tb.v
new file mode 100644
index 0000000..8a7f66e
--- /dev/null
+++ b/verilog/dv/uart_master/uart_master_tb.v
@@ -0,0 +1,279 @@
+// 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
+
+`timescale 1 ns / 1 ps
+
+`include "uprj_netlists.v"
+`include "caravel_netlists.v"
+`include "spiflash.v"
+`include "uart_agent.v"
+
+module uart_master_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;
+
+//----------------------------------
+// Uart Configuration
+// ---------------------------------
+reg [1:0]      uart_data_bit        ;
+reg	       uart_stop_bits       ; // 0: 1 stop bit; 1: 2 stop bit;
+reg	       uart_stick_parity    ; // 1: force even parity
+reg	       uart_parity_en       ; // parity enable
+reg	       uart_even_odd_parity ; // 0: odd parity; 1: even parity
+
+reg [7:0]      uart_data            ;
+reg [15:0]     uart_divisor         ;	// divided by n * 16
+reg [15:0]     uart_timeout         ;// wait time limit
+
+reg [15:0]     uart_rx_nu           ;
+reg [15:0]     uart_tx_nu           ;
+reg [7:0]      uart_write_data [0:39];
+reg 	       uart_fifo_enable     ;	// fifo mode disable
+
+reg [31:0]     read_data     ;
+reg            flag;
+reg            test_fail     ;
+
+
+	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, uart_master_tb);
+		$dumpvars(1, uart_master_tb.uut);
+		$dumpvars(1, uart_master_tb.uut.mprj);
+		$dumpvars(1, uart_master_tb.uut.mprj.u_wb_host);
+		$dumpvars(1, uart_master_tb.uut.mprj.u_wb_host.u_uart2wb);
+		$dumpvars(1, uart_master_tb.tb_master_uart);
+		//$dumpvars(2, uart_master_tb.uut.mprj.u_pinmux);
+	end
+       `endif
+
+	initial begin
+
+		// Repeat cycles of 1000 clock edges as needed to complete testbench
+		repeat (400) begin
+			repeat (1000) @(posedge clock);
+			// $display("+1000 cycles");
+		end
+		$display("%c[1;31m",27);
+		$display ("##########################################################");
+		`ifdef GL
+		   $display ("Monitor: Timeout, Test UART Master (GL) Failed");
+		`else
+		   $display ("Monitor: Timeout, Test UART Master (RTL) Failed");
+		`endif
+		$display ("##########################################################");
+		$display("%c[0m",27);
+		$finish;
+	end
+
+	initial begin
+            uart_data_bit           = 2'b11;
+            uart_stop_bits          = 1; // 0: 1 stop bit; 1: 2 stop bit;
+            uart_stick_parity       = 0; // 1: force even parity
+            uart_parity_en          = 0; // parity enable
+            uart_even_odd_parity    = 1; // 0: odd parity; 1: even parity
+            uart_divisor            = 15;// divided by n * 16
+            uart_timeout            = 600;// wait time limit
+            uart_fifo_enable        = 0;	// fifo mode disable
+            tb_master_uart.debug_mode = 0; // disable debug display
+            tb_master_uart.uart_init;
+            tb_master_uart.control_setup (uart_data_bit, uart_stop_bits, uart_parity_en, uart_even_odd_parity, 
+        	                          uart_stick_parity, uart_timeout, uart_divisor);
+	   wait(checkbits == 16'h AB60);
+		$display("Monitor: UART Master Test Started");
+
+           repeat (4000) @(posedge clock);
+           //$write ("\n(%t)Response:\n",$time);
+           flag = 0;
+           while(flag == 0)
+           begin
+                tb_master_uart.read_char(read_data,flag);
+                $write ("%c",read_data);
+           end
+
+
+
+           // Remove Wb Reset
+           uartm_reg_write('h3080_0000,'h1);
+
+           repeat (2) @(posedge clock);
+           #1;
+
+           $display("Monitor: Writing  expected value");
+           
+           test_fail = 0;
+           uartm_reg_write(32'h30020058,32'h11223344);
+           uartm_reg_write(32'h3002005C,32'h22334455);
+           uartm_reg_write(32'h30020060,32'h33445566);
+           uartm_reg_write(32'h30020064,32'h44556677);
+           uartm_reg_write(32'h30020068,32'h55667788);
+           uartm_reg_write(32'h3002006C,32'h66778899);
+
+           uartm_reg_read_check(32'h30020058,32'h11223344);
+           uartm_reg_read_check(32'h3002005C,32'h22334455);
+           uartm_reg_read_check(32'h30020060,32'h33445566);
+           uartm_reg_read_check(32'h30020064,32'h44556677);
+           uartm_reg_read_check(32'h30020068,32'h55667788);
+           uartm_reg_read_check(32'h3002006C,32'h66778899);
+
+           $display("###################################################");
+           if(test_fail == 0) begin
+              `ifdef GL
+                  $display("Monitor: Standalone User UART Master (GL) Passed");
+              `else
+                  $display("Monitor: Standalone User Uart Master (RTL) Passed");
+              `endif
+           end else begin
+               `ifdef GL
+                   $display("Monitor: Standalone User Uart Master (GL) Failed");
+               `else
+                   $display("Monitor: Standalone User Uart Master (RTL) Failed");
+               `endif
+            end
+           $display("###################################################");
+           #100
+
+	    $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("uart_master.hex")
+	) spiflash (
+		.csb(flash_csb),
+		.clk(flash_clk),
+		.io0(flash_io0),
+		.io1(flash_io1),
+		.io2(),			// not used
+		.io3()			// not used
+	);
+
+
+
+
+`ifndef GL // Drive Power for Hold Fix Buf
+    // All standard cell need power hook-up for functionality work
+    initial begin
+    end
+`endif    
+
+
+//---------------------------
+//  UART Agent integration
+// --------------------------
+wire uart_txd,uart_rxd;
+
+assign uart_txd   = mprj_io[35];
+assign mprj_io[34]  = uart_rxd ;
+ 
+uart_agent tb_master_uart(
+	.mclk                (clock              ),
+	.txd                 (uart_rxd           ),
+	.rxd                 (uart_txd           )
+	);
+
+
+`include "uart_master_tasks.sv"
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/user_basic/Makefile b/verilog/dv/user_basic/Makefile
new file mode 100644
index 0000000..e1558d4
--- /dev/null
+++ b/verilog/dv/user_basic/Makefile
@@ -0,0 +1,105 @@
+# 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_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_BEHAVIOURAL_AGENTS = ../agents
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/yifive/ycr1c/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include
+
+## YIFIVE FIRMWARE
+YIFIVE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/dv/firmware
+GCC64_PREFIX?=riscv64-unknown-elf
+
+## RISCV GCC 
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+DUMP?=OFF
+
+.SUFFIXES:
+
+PATTERN = user_basic
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+    else  
+	iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+   endif
+else  
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_GL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	$< -o $@ 
+endif
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c $(CARAVEL_FIRMWARE_PATH)/sections.lds $(CARAVEL_FIRMWARE_PATH)/start.s
+	${GCC64_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: 
+	echo @"This is user boot test, noting to compile the mangment core code"
+
+%.bin: %.elf
+	${GCC64_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log *.dump
+
+.PHONY: clean hex all
diff --git a/verilog/dv/user_basic/user_basic_tb.v b/verilog/dv/user_basic/user_basic_tb.v
new file mode 100644
index 0000000..70d9821
--- /dev/null
+++ b/verilog/dv/user_basic/user_basic_tb.v
@@ -0,0 +1,517 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  Standalone User validation Test bench                       ////
+////                                                              ////
+////  This file is part of the YIFive cores project               ////
+////  https://github.com/dineshannayya/yifive_r0.git              ////
+////  http://www.opencores.org/cores/yifive/                      ////
+////                                                              ////
+////  Description                                                 ////
+////   This is a standalone test bench to validate the            ////
+////   Digital core.                                              ////
+////   1. User Risc core is booted using  compiled code of        ////
+////      user_risc_boot.c                                        ////
+////   2. User Risc core uses Serial Flash and SDRAM to boot      ////
+////   3. After successful boot, Risc core will check the UART    ////
+////      RX Data, If it's available then it loop back the same   ////
+////      data in uart tx                                         ////
+////   4. Test bench send random 40 character towards User uart   ////
+////      and expect same data to return back                     ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      - Dinesh Annayya, dinesha@opencores.org                 ////
+////                                                              ////
+////  Revision :                                                  ////
+////    0.1 - 16th Feb 2021, Dinesh A                             ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+`default_nettype wire
+
+`timescale 1 ns/10 ps
+
+`include "uprj_netlists.v"
+
+
+module user_basic_tb;
+parameter CLK1_PERIOD = 10;
+parameter CLK2_PERIOD = 2;
+
+reg            clock         ;
+reg            clock2        ;
+reg            wb_rst_i      ;
+reg            power1, power2;
+reg            power3, power4;
+
+reg            wbd_ext_cyc_i;  // strobe/request
+reg            wbd_ext_stb_i;  // strobe/request
+reg [31:0]     wbd_ext_adr_i;  // address
+reg            wbd_ext_we_i;  // write
+reg [31:0]     wbd_ext_dat_i;  // data output
+reg [3:0]      wbd_ext_sel_i;  // byte enable
+
+wire [31:0]    wbd_ext_dat_o;  // data input
+wire           wbd_ext_ack_o;  // acknowlegement
+wire           wbd_ext_err_o;  // error
+
+// User I/O
+wire [37:0]    io_oeb        ;
+wire [37:0]    io_out        ;
+wire [37:0]    io_in         ;
+
+wire [37:0]    mprj_io       ;
+wire [7:0]     mprj_io_0     ;
+reg            test_fail     ;
+reg [31:0]     read_data     ;
+//----------------------------------
+// Uart Configuration
+// ---------------------------------
+reg [1:0]      uart_data_bit        ;
+reg	       uart_stop_bits       ; // 0: 1 stop bit; 1: 2 stop bit;
+reg	       uart_stick_parity    ; // 1: force even parity
+reg	       uart_parity_en       ; // parity enable
+reg	       uart_even_odd_parity ; // 0: odd parity; 1: even parity
+
+reg [7:0]      uart_data            ;
+reg [15:0]     uart_divisor         ;	// divided by n * 16
+reg [15:0]     uart_timeout         ;// wait time limit
+
+reg [15:0]     uart_rx_nu           ;
+reg [15:0]     uart_tx_nu           ;
+reg [7:0]      uart_write_data [0:39];
+reg 	       uart_fifo_enable     ;	// fifo mode disable
+
+wire           clock_mon;
+integer        test_step;
+
+integer i,j;
+
+	// 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 #(CLK1_PERIOD/2) clock  <= (clock === 1'b0);
+	always #(CLK2_PERIOD/2) clock2 <= (clock2 === 1'b0);
+
+	initial begin
+		test_step = 0;
+		clock = 0;
+		clock2 = 0;
+                wbd_ext_cyc_i ='h0;  // strobe/request
+                wbd_ext_stb_i ='h0;  // strobe/request
+                wbd_ext_adr_i ='h0;  // address
+                wbd_ext_we_i  ='h0;  // write
+                wbd_ext_dat_i ='h0;  // data output
+                wbd_ext_sel_i ='h0;  // byte enable
+	end
+
+	`ifdef WFDUMP
+	   initial begin
+	   	$dumpfile("simx.vcd");
+	   	$dumpvars(4, user_basic_tb);
+	   end
+       `endif
+
+	initial begin
+		wb_rst_i <= 1'b1;
+		#100;
+		wb_rst_i <= 1'b0;	    	// Release reset
+	end
+initial
+begin
+
+   #200; // Wait for reset removal
+   repeat (10) @(posedge clock);
+   $display("Monitor: Standalone User Basic Test Started");
+   
+   repeat (2) @(posedge clock);
+
+   test_fail=0;
+   fork
+      begin
+	  // Default Value Check
+          // cfg_glb_ctrl         = reg_0[6:0];
+          // uart_i2c_usb_sel     = reg_0[8:7];
+          // cfg_wb_clk_ctrl      = reg_0[11:9];
+          // cfg_rtc_clk_ctrl     = reg_0[19:12];
+          // cfg_cpu_clk_ctrl     = reg_0[23:20];
+          // cfg_sdram_clk_ctrl   = reg_0[27:24];
+          // cfg_usb_clk_ctrl     = reg_0[31:28];
+	  $display("Step-1, CPU: CLOCK1, RTC: CLOCK2/2, USB: CLOCK2, WBS:CLOCK1");
+	  test_step = 1;
+          wb_user_core_write('h3080_0000,{4'h0,4'h0,4'h0,8'h0,3'b000,2'b00,7'h00});
+	  clock_monitor(CLK1_PERIOD,CLK2_PERIOD*2,CLK2_PERIOD,CLK1_PERIOD);
+
+	  $display("Step-2, CPU: CLOCK2, RTC: CLOCK2/(2+1), USB: CLOCK2/2, WBS:CLOCK1/2");
+	  test_step = 2;
+          wb_user_core_write('h3080_0000,{4'h8,4'h0,4'h8,8'h1,3'b100,2'b00,7'h00});
+	  clock_monitor(CLK2_PERIOD,(3)*CLK2_PERIOD,2*CLK2_PERIOD,2*CLK1_PERIOD);
+
+	  $display("Step-3, CPU: CLOCK1/2, RTC: CLOCK2/(2+2), USB: CLOCK2/(2+1), WBS:CLOCK1/(2+1)");
+	  test_step = 3;
+          wb_user_core_write('h3080_0000,{4'h9,4'h0,4'h4,8'h2,3'b101,2'b00,7'h00});
+	  clock_monitor(2*CLK1_PERIOD,(4)*CLK2_PERIOD,3*CLK2_PERIOD,3*CLK1_PERIOD);
+
+	  $display("Step-4, CPU: CLOCK1/3, RTC: CLOCK2/(2+3), USB: CLOCK2/(2+2), WBS:CLOCK1/(2+2)");
+	  test_step = 4;
+          wb_user_core_write('h3080_0000,{4'hA,4'h0,4'h5,8'h3,3'b110,2'b00,7'h00});
+	  clock_monitor(3*CLK1_PERIOD,5*CLK2_PERIOD,4*CLK2_PERIOD,4*CLK1_PERIOD);
+
+	  $display("Step-5, CPU: CLOCK1/4, RTC: CLOCK2/(2+4), USB: CLOCK2/(2+3), WBS:CLOCK1/(2+3)");
+	  test_step = 5;
+          wb_user_core_write('h3080_0000,{4'hB,4'h0,4'h6,8'h4,3'b111,2'b00,7'h00});
+	  clock_monitor(4*CLK1_PERIOD,6*CLK2_PERIOD,5*CLK2_PERIOD,5*CLK1_PERIOD);
+
+	  $display("Step-6, CPU: CLOCK1/(2+3), RTC: CLOCK2/(2+5), USB: CLOCK2/(2+4), WBS:CLOCK1/(2+3)");
+	  test_step = 6;
+          wb_user_core_write('h3080_0000,{4'hC,4'h0,4'h7,8'h5,3'b111,2'b00,7'h00});
+	  clock_monitor(5*CLK1_PERIOD,7*CLK2_PERIOD,6*CLK2_PERIOD,5*CLK1_PERIOD);
+
+	  $display("Step-7, CPU: CLOCK1/(2+3), RTC: CLOCK2/(2+6), USB: CLOCK2/(2+5), WBS:CLOCK1/(2+3)");
+	  test_step = 7;
+          wb_user_core_write('h3080_0000,{4'hD,4'h0,4'h7,8'h6,3'b111,2'b00,7'h00});
+	  clock_monitor(5*CLK1_PERIOD,8*CLK2_PERIOD,7*CLK2_PERIOD,5*CLK1_PERIOD);
+
+	  $display("Step-8, CPU: CLOCK1/(2+3), RTC: CLOCK2/(2+7), USB: CLOCK2/(2+6), WBS:CLOCK1/(2+3)");
+	  test_step = 8;
+          wb_user_core_write('h3080_0000,{4'hE,4'h0,4'h7,8'h7,3'b111,2'b00,7'h00});
+	  clock_monitor(5*CLK1_PERIOD,9*CLK2_PERIOD,8*CLK2_PERIOD,5*CLK1_PERIOD);
+
+	  $display("Step-9, CPU: CLOCK1/(2+3), RTC: CLOCK2/(2+8), USB: CLOCK2/(2+7), WBS:CLOCK1/(2+3)");
+	  test_step = 9;
+          wb_user_core_write('h3080_0000,{4'hF,4'h0,4'h7,8'h8,3'b111,2'b00,7'h00});
+	  clock_monitor(5*CLK1_PERIOD,10*CLK2_PERIOD,9*CLK2_PERIOD,5*CLK1_PERIOD);
+
+	  $display("Step-10, CPU: CLOCK1/(2+3), RTC: CLOCK2/(2+128), USB: CLOCK2/(2+7), WBS:CLOCK1/(2+3)");
+	  test_step = 10;
+          wb_user_core_write('h3080_0000,{4'hF,4'h0,4'h7,8'h80,3'b111,2'b00,7'h00});
+	  clock_monitor(5*CLK1_PERIOD,130*CLK2_PERIOD,9*CLK2_PERIOD,5*CLK1_PERIOD);
+
+	  $display("Step-10, CPU: CLOCK1/(2+3), RTC: CLOCK2/(2+255), USB: CLOCK2/(2+7), WBS:CLOCK1/(2+3)");
+	  test_step = 10;
+          wb_user_core_write('h3080_0000,{4'hF,4'h0,4'h7,8'hFF,3'b111,2'b00,7'h00});
+	  clock_monitor(5*CLK1_PERIOD,257*CLK2_PERIOD,9*CLK2_PERIOD,5*CLK1_PERIOD);
+
+         $display("###################################################");
+         $display("Monitor: Checking the chip signature :");
+         // Remove Wb/PinMux Reset
+         wb_user_core_write('h3080_0000,'h1);
+
+	 wb_user_core_read_check(32'h30020058,read_data,32'h8273_8343);
+	 wb_user_core_read_check(32'h3002005C,read_data,32'h1402_2022);
+	 wb_user_core_read_check(32'h30020060,read_data,32'h0003_4000);
+
+      end
+   
+      begin
+      repeat (20000) @(posedge clock);
+   		// $display("+1000 cycles");
+      test_fail = 1;
+      end
+      join_any
+      disable fork; //disable pending fork activity
+
+   
+      $display("###################################################");
+      if(test_fail == 0) begin
+         `ifdef GL
+             $display("Monitor: Standalone User UART Test (GL) Passed");
+         `else
+             $display("Monitor: Standalone User UART Test (RTL) Passed");
+         `endif
+      end else begin
+          `ifdef GL
+              $display("Monitor: Standalone User UART Test (GL) Failed");
+          `else
+              $display("Monitor: Standalone User UART Test (RTL) Failed");
+          `endif
+       end
+      $display("###################################################");
+      #100
+      $finish;
+end
+
+
+wire USER_VDD1V8 = 1'b1;
+wire VSS = 1'b0;
+
+
+user_project_wrapper u_top(
+`ifdef USE_POWER_PINS
+    .vccd1(USER_VDD1V8),	// User area 1 1.8V supply
+    .vssd1(VSS),	// User area 1 digital ground
+`endif
+    .wb_clk_i        (clock),  // System clock
+    .user_clock2     (clock2),  // Real-time clock
+    .wb_rst_i        (wb_rst_i),  // Regular Reset signal
+
+    .wbs_cyc_i   (wbd_ext_cyc_i),  // strobe/request
+    .wbs_stb_i   (wbd_ext_stb_i),  // strobe/request
+    .wbs_adr_i   (wbd_ext_adr_i),  // address
+    .wbs_we_i    (wbd_ext_we_i),  // write
+    .wbs_dat_i   (wbd_ext_dat_i),  // data output
+    .wbs_sel_i   (wbd_ext_sel_i),  // byte enable
+
+    .wbs_dat_o   (wbd_ext_dat_o),  // data input
+    .wbs_ack_o   (wbd_ext_ack_o),  // acknowlegement
+
+ 
+    // Logic Analyzer Signals
+    .la_data_in      ('1) ,
+    .la_data_out     (),
+    .la_oenb         ('0),
+ 
+
+    // IOs
+    .io_in          (io_in)  ,
+    .io_out         (io_out) ,
+    .io_oeb         (io_oeb) ,
+
+    .user_irq       () 
+
+);
+
+`ifndef GL // Drive Power for Hold Fix Buf
+    // All standard cell need power hook-up for functionality work
+    initial begin
+
+
+    end
+`endif    
+
+
+task clock_monitor;
+input [15:0] exp_cpu_period;
+input [15:0] exp_rtc_period;
+input [15:0] exp_usb_period;
+input [15:0] exp_wbs_period;
+begin
+   force clock_mon = u_top.u_wb_host.cpu_clk;
+   check_clock_period("CPU CLock",exp_cpu_period);
+   release clock_mon;
+
+   force clock_mon = u_top.u_wb_host.rtc_clk;
+   check_clock_period("RTC Clock",exp_rtc_period);
+   release clock_mon;
+
+   force clock_mon = u_top.u_wb_host.usb_clk;
+   check_clock_period("USB Clock",exp_usb_period);
+   release clock_mon;
+
+   force clock_mon = u_top.u_wb_host.wbs_clk_out;
+   check_clock_period("WBS Clock",exp_wbs_period);
+   release clock_mon;
+end
+endtask
+
+//----------------------------------
+// Check the clock period
+//----------------------------------
+task check_clock_period;
+input [127:0] clk_name;
+input [15:0] clk_period; // in NS
+time prev_t, next_t, periodd;
+begin
+	$timeformat(-12,3,"ns",10);
+   repeat(1) @(posedge clock_mon);
+   repeat(1) @(posedge clock_mon);
+   prev_t  = $realtime;
+   repeat(100) @(posedge clock_mon);
+   next_t  = $realtime;
+   periodd = (next_t-prev_t)/100;
+   //periodd = (periodd)/1e9;
+   if(clk_period != periodd) begin
+       $display("STATUS: FAIL => %s Exp Period: %d Rxd: %d",clk_name,clk_period,periodd);
+       test_fail = 1;
+   end else begin
+       $display("STATUS: PASS => %s  Period: %d ",clk_name,clk_period);
+   end
+end
+endtask
+
+
+
+
+
+
+task wb_user_core_write;
+input [31:0] address;
+input [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h1;  // write
+  wbd_ext_dat_i =data;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("DEBUG WB USER ACCESS WRITE Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read;
+input [31:0] address;
+output [31:0] data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("DEBUG WB USER ACCESS READ Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read_check;
+input [31:0] address;
+output [31:0] data;
+input [31:0] cmp_data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  if(data !== cmp_data) begin
+     $display("ERROR : WB USER ACCESS READ  Address : 0x%x, Exd: 0x%x Rxd: 0x%x ",address,cmp_data,data);
+     test_fail = 1;
+  end else begin
+     $display("STATUS: WB USER ACCESS READ  Address : 0x%x, Data : 0x%x",address,data);
+  end
+  repeat (2) @(posedge clock);
+end
+endtask
+
+`ifdef GL
+
+wire        wbd_spi_stb_i   = u_top.u_spi_master.wbd_stb_i;
+wire        wbd_spi_ack_o   = u_top.u_spi_master.wbd_ack_o;
+wire        wbd_spi_we_i    = u_top.u_spi_master.wbd_we_i;
+wire [31:0] wbd_spi_adr_i   = u_top.u_spi_master.wbd_adr_i;
+wire [31:0] wbd_spi_dat_i   = u_top.u_spi_master.wbd_dat_i;
+wire [31:0] wbd_spi_dat_o   = u_top.u_spi_master.wbd_dat_o;
+wire [3:0]  wbd_spi_sel_i   = u_top.u_spi_master.wbd_sel_i;
+
+wire        wbd_sdram_stb_i = u_top.u_sdram_ctrl.wb_stb_i;
+wire        wbd_sdram_ack_o = u_top.u_sdram_ctrl.wb_ack_o;
+wire        wbd_sdram_we_i  = u_top.u_sdram_ctrl.wb_we_i;
+wire [31:0] wbd_sdram_adr_i = u_top.u_sdram_ctrl.wb_addr_i;
+wire [31:0] wbd_sdram_dat_i = u_top.u_sdram_ctrl.wb_dat_i;
+wire [31:0] wbd_sdram_dat_o = u_top.u_sdram_ctrl.wb_dat_o;
+wire [3:0]  wbd_sdram_sel_i = u_top.u_sdram_ctrl.wb_sel_i;
+
+wire        wbd_uart_stb_i  = u_top.u_uart_i2c_usb.reg_cs;
+wire        wbd_uart_ack_o  = u_top.u_uart_i2c_usb.reg_ack;
+wire        wbd_uart_we_i   = u_top.u_uart_i2c_usb.reg_wr;
+wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_i2c_usb.reg_addr;
+wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_i2c_usb.reg_wdata;
+wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_i2c_usb.reg_rdata;
+wire        wbd_uart_sel_i  = u_top.u_uart_i2c_usb.reg_be;
+
+`endif
+
+/**
+`ifdef GL
+//-----------------------------------------------------------------------------
+// RISC IMEM amd DMEM Monitoring TASK
+//-----------------------------------------------------------------------------
+
+`define RISC_CORE  user_uart_tb.u_top.u_core.u_riscv_top
+
+always@(posedge `RISC_CORE.wb_clk) begin
+    if(`RISC_CORE.wbd_imem_ack_i)
+          $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x", `RISC_CORE.wbd_imem_adr_o,`RISC_CORE.wbd_imem_dat_i);
+    if(`RISC_CORE.wbd_dmem_ack_i && `RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_o);
+    if(`RISC_CORE.wbd_dmem_ack_i && !`RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_i);
+end
+
+`endif
+**/
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/user_i2cm/Makefile b/verilog/dv/user_i2cm/Makefile
new file mode 100644
index 0000000..5788ed8
--- /dev/null
+++ b/verilog/dv/user_i2cm/Makefile
@@ -0,0 +1,111 @@
+# 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_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_BEHAVIOURAL_AGENTS = ../agents
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/yifive/ycr1c/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include
+
+## YIFIVE FIRMWARE
+YIFIVE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/dv/firmware
+GCC64_PREFIX?=riscv64-unknown-elf
+
+## RISCV GCC 
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+DUMP?=OFF
+
+.SUFFIXES:
+
+PATTERN = user_i2cm
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v
+	${GCC64_PREFIX}-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$(YIFIVE_FIRMWARE_PATH)  user_uart.c -o user_uart.o
+	${GCC64_PREFIX}-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$(YIFIVE_FIRMWARE_PATH)  $(YIFIVE_FIRMWARE_PATH)/crt_tcm.S -o crt_tcm.o
+	${GCC64_PREFIX}-gcc -o user_uart.elf -T $(YIFIVE_FIRMWARE_PATH)/link_tcm.ld user_uart.o crt_tcm.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32
+	${GCC64_PREFIX}-objcopy -O verilog user_uart.elf user_uart.hex
+	${GCC64_PREFIX}-objdump -D user_uart.elf > user_uart.dump
+	rm crt_tcm.o user_uart.o
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+    else  
+	iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+   endif
+else  
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_GL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	$< -o $@ 
+endif
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c $(CARAVEL_FIRMWARE_PATH)/sections.lds $(CARAVEL_FIRMWARE_PATH)/start.s
+	${GCC64_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: 
+	echo @"This is user boot test, noting to compile the mangment core code"
+
+%.bin: %.elf
+	${GCC64_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log *.dump
+
+.PHONY: clean hex all
diff --git a/verilog/dv/user_i2cm/run_iverilog b/verilog/dv/user_i2cm/run_iverilog
new file mode 100755
index 0000000..3ae1ffd
--- /dev/null
+++ b/verilog/dv/user_i2cm/run_iverilog
@@ -0,0 +1,37 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# // 
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# //      http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+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_uart.c -o user_uart.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_uart.elf -T ../../rtl/syntacore/scr1/sim/tests/common/link_tcm.ld user_uart.o crt_tcm.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32
+
+riscv64-unknown-elf-objcopy -O verilog user_uart.elf user_uart.hex
+
+riscv64-unknown-elf-objdump -D user_uart.elf > user_uart.dump
+
+rm crt_tcm.o user_uart.o
+
+#iverilog with waveform dump
+iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $PDK_PATH -I  ../../../caravel/verilog/rtl  -I ../ -I ../../../verilog/rtl -I ../ -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I ../../../verilog/rtl/i2cm/src/includes -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_i2cm_tb.v -o user_i2cm_tb.vvp
+
+
+
+vvp user_i2cm_tb.vvp | tee test.log
+
+\rm -rf user_i2cm_tb.vvp
diff --git a/verilog/dv/user_i2cm/user_i2cm_tb.v b/verilog/dv/user_i2cm/user_i2cm_tb.v
new file mode 100644
index 0000000..826774d
--- /dev/null
+++ b/verilog/dv/user_i2cm/user_i2cm_tb.v
@@ -0,0 +1,552 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  Standalone User validation Test bench                       ////
+////                                                              ////
+////  This file is part of the YIFive cores project               ////
+////  https://github.com/dineshannayya/yifive_r0.git              ////
+////                                                              ////
+////  Description                                                 ////
+////   This is a standalone test bench to validate the            ////
+////   i2c Master .                                               ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      - Dinesh Annayya, dinesha@opencores.org                 ////
+////                                                              ////
+////  Revision :                                                  ////
+////    0.1 - 16th Feb 2021, Dinesh A                             ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+`default_nettype wire
+
+`timescale 1 ns / 1 ns
+
+`include "s25fl256s.sv"
+`include "uprj_netlists.v"
+`include "mt48lc8m8a2.v"
+`include "i2c_slave_model.v"
+
+
+`define ADDR_SPACE_UART  32'h3001_0000
+`define ADDR_SPACE_I2CM  32'h3001_0040
+`define ADDR_SPACE_PINMUX  32'h3002_0000
+
+
+module tb_top;
+
+reg            clock         ;
+reg            wb_rst_i      ;
+reg            power1, power2;
+reg            power3, power4;
+
+reg            wbd_ext_cyc_i;  // strobe/request
+reg            wbd_ext_stb_i;  // strobe/request
+reg [31:0]     wbd_ext_adr_i;  // address
+reg            wbd_ext_we_i;  // write
+reg [31:0]     wbd_ext_dat_i;  // data output
+reg [3:0]      wbd_ext_sel_i;  // byte enable
+
+wire [31:0]    wbd_ext_dat_o;  // data input
+wire           wbd_ext_ack_o;  // acknowlegement
+wire           wbd_ext_err_o;  // error
+
+// User I/O
+wire [37:0]    io_oeb        ;
+wire [37:0]    io_out        ;
+wire [37:0]    io_in         ;
+
+wire [37:0]    mprj_io       ;
+wire [7:0]     mprj_io_0     ;
+reg            test_fail     ;
+reg [31:0]     read_data     ;
+//----------------------------------
+// Uart Configuration
+// ---------------------------------
+
+integer i,j;
+
+	// 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("tb_top.vcd");
+	   	$dumpvars(0, tb_top);
+	   end
+       `endif
+
+	initial begin
+		wb_rst_i <= 1'b1;
+		#100;
+		wb_rst_i <= 1'b0;	    	// Release reset
+	end
+initial
+begin
+   test_fail = 0;
+
+   #200; // Wait for reset removal
+   repeat (10) @(posedge clock);
+   $display("############################################");
+   $display("   Testing I2CM Read/Write Access           ");
+   $display("############################################");
+   
+
+   repeat (10) @(posedge clock);
+   #1;
+   // Enable I2M Block & WB Reset and Enable I2CM Mux Select
+   wb_user_core_write('h3080_0000,'hA1);
+
+   // Enable I2C Multi Functional Ports
+   wb_user_core_write(`ADDR_SPACE_PINMUX+'h0038,'h200);
+
+   repeat (100) @(posedge clock);  
+
+    @(posedge  clock);
+    $display("---------- Initialize I2C Master ----------"); 
+
+    //Wrire Prescale registers
+     wb_user_core_write(`ADDR_SPACE_I2CM+(8'h0<<2),8'hC7);  
+     wb_user_core_write(`ADDR_SPACE_I2CM+(8'h1<<2),8'h00);  
+    // Core Enable
+     wb_user_core_write(`ADDR_SPACE_I2CM+(8'h2<<2),8'h80);  
+    
+    // Writing Data
+
+    $display("---------- Writing Data ----------"); 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h20); // Slave Addr + WR  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h90);  
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+     
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h66);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h10);  
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+   
+   /* Byte1: 12 */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h12);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h10); // No Stop + Write  
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+   
+   /* Byte1: 34 */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h34);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h10); // No Stop + Write 
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+   /* Byte1: 56 */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h56);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h10); // No Stop + Write 
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+   /* Byte1: 78 */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h78);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h50); // Stop + Write 
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+    //Reading Data
+    
+    //Wrire Address
+    $display("---------- Writing Data ----------"); 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h20);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h90);  
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+     
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h66);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h50);  
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+    //Generate Read
+    $display("---------- Writing Data ----------"); 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h21); // Slave Addr + RD  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h90);  
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+    /* BYTE-1 : 0x12  */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h20);  // RD + ACK
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+    //Compare received data
+    wb_user_core_read_cmp(`ADDR_SPACE_I2CM+(8'h3<<2),8'h12);  
+     
+    /* BYTE-2 : 0x34  */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h20);  // RD + ACK
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+    //Compare received data
+    wb_user_core_read_cmp(`ADDR_SPACE_I2CM+(8'h3<<2),8'h34);  
+
+    /* BYTE-3 : 0x56  */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4 <<2),8'h20);  // RD + ACK
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+    //Compare received data
+    wb_user_core_read_cmp(`ADDR_SPACE_I2CM+(8'h3<<2),8'h56);  
+
+    /* BYTE-4 : 0x78  */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h68);  // STOP + RD + NACK 
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4 <<2),read_data);  
+
+    //Compare received data
+    wb_user_core_read_cmp(`ADDR_SPACE_I2CM+(8'h3 <<2),8'h78);  
+
+    repeat(100)@(posedge clock);
+
+
+
+     $display("###################################################");
+     if(test_fail == 0) begin
+        `ifdef GL
+            $display("Monitor: Standalone User I2M Test (GL) Passed");
+        `else
+            $display("Monitor: Standalone User I2M Test (RTL) Passed");
+        `endif
+     end else begin
+         `ifdef GL
+             $display("Monitor: Standalone User I2M Test (GL) Failed");
+         `else
+             $display("Monitor: Standalone User I2M Test (RTL) Failed");
+         `endif
+      end
+     $display("###################################################");
+     #100
+     $finish;
+end
+
+
+wire USER_VDD1V8 = 1'b1;
+wire VSS = 1'b0;
+
+
+user_project_wrapper u_top(
+`ifdef USE_POWER_PINS
+    .vccd1(USER_VDD1V8),	// User area 1 1.8V supply
+    .vssd1(VSS),	// User area 1 digital ground
+`endif
+    .wb_clk_i        (clock),  // System clock
+    .user_clock2     (1'b1),  // Real-time clock
+    .wb_rst_i        (wb_rst_i),  // Regular Reset signal
+
+    .wbs_cyc_i   (wbd_ext_cyc_i),  // strobe/request
+    .wbs_stb_i   (wbd_ext_stb_i),  // strobe/request
+    .wbs_adr_i   (wbd_ext_adr_i),  // address
+    .wbs_we_i    (wbd_ext_we_i),  // write
+    .wbs_dat_i   (wbd_ext_dat_i),  // data output
+    .wbs_sel_i   (wbd_ext_sel_i),  // byte enable
+
+    .wbs_dat_o   (wbd_ext_dat_o),  // data input
+    .wbs_ack_o   (wbd_ext_ack_o),  // acknowlegement
+
+ 
+    // Logic Analyzer Signals
+    .la_data_in      ('1) ,
+    .la_data_out     (),
+    .la_oenb         ('0),
+ 
+
+    // IOs
+    .io_in          (io_in)  ,
+    .io_out         (io_out) ,
+    .io_oeb         (io_oeb) ,
+
+    .user_irq       () 
+
+);
+
+`ifndef GL // Drive Power for Hold Fix Buf
+    // All standard cell need power hook-up for functionality work
+    initial begin
+
+    end
+`endif    
+//------------------------------------------------------
+//  Integrate the Serial flash with qurd support to
+//  user core using the gpio pads
+//  ----------------------------------------------------
+
+   wire flash_clk = io_out[24];
+   wire flash_csb = io_out[28];
+   // Creating Pad Delay
+   wire #1 io_oeb_29 = io_oeb[29];
+   wire #1 io_oeb_30 = io_oeb[30];
+   wire #1 io_oeb_31 = io_oeb[31];
+   wire #1 io_oeb_32 = io_oeb[32];
+   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[29] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[30] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[31] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[32] : 1'bz;
+
+   assign io_in[29] = flash_io0;
+   assign io_in[30] = flash_io1;
+   assign io_in[31] = flash_io2;
+   assign io_in[32] = flash_io3;
+
+
+   // Quard flash
+     s25fl256s #(.mem_file_name("user_uart.hex"),
+	         .otp_file_name("none"), 
+                 .TimingModel("S25FL512SAGMFI010_F_30pF")) 
+		 u_spi_flash_256mb
+       (
+           // Data Inputs/Outputs
+       .SI      (flash_io0),
+       .SO      (flash_io1),
+       // Controls
+       .SCK     (flash_clk),
+       .CSNeg   (flash_csb),
+       .WPNeg   (flash_io2),
+       .HOLDNeg (flash_io3),
+       .RSTNeg  (!wb_rst_i)
+
+       );
+
+
+
+//---------------------------
+// I2C
+// --------------------------
+tri scl,sda;
+
+assign sda  =  (io_oeb[22] == 1'b0) ? io_out[22] : 1'bz;
+assign scl   = (io_oeb[23] == 1'b0) ? io_out[23]: 1'bz;
+assign io_in[22]  =  sda;
+assign io_in[23]  =  scl;
+
+pullup p1(scl); // pullup scl line
+pullup p2(sda); // pullup sda line
+
+ 
+i2c_slave_model u_i2c_slave (
+	.scl   (scl), 
+	.sda   (sda)
+       );
+
+
+task wb_user_core_write;
+input [31:0] address;
+input [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h1;  // write
+  wbd_ext_dat_i =data;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("DEBUG WB USER ACCESS WRITE Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read;
+input [31:0] address;
+output [31:0] data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  //$display("DEBUG WB USER ACCESS READ Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read_cmp;
+input [31:0] address;
+input [31:0] cmp_data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  if(data === cmp_data) begin
+     $display("STATUS: DEBUG WB USER ACCESS READ Address : %x, Data : %x",address,data);
+  end else begin
+     $display("ERROR: DEBUG WB USER ACCESS READ Address : %x, Exp Data : %x Rxd Data: ",address,cmp_data,data);
+     test_fail= 1;
+     #100
+     $finish;
+  end
+  repeat (2) @(posedge clock);
+end
+endtask
+
+`ifdef GL
+
+wire        wbd_spi_stb_i   = u_top.u_spi_master.wbd_stb_i;
+wire        wbd_spi_ack_o   = u_top.u_spi_master.wbd_ack_o;
+wire        wbd_spi_we_i    = u_top.u_spi_master.wbd_we_i;
+wire [31:0] wbd_spi_adr_i   = u_top.u_spi_master.wbd_adr_i;
+wire [31:0] wbd_spi_dat_i   = u_top.u_spi_master.wbd_dat_i;
+wire [31:0] wbd_spi_dat_o   = u_top.u_spi_master.wbd_dat_o;
+wire [3:0]  wbd_spi_sel_i   = u_top.u_spi_master.wbd_sel_i;
+
+wire        wbd_sdram_stb_i = u_top.u_sdram_ctrl.wb_stb_i;
+wire        wbd_sdram_ack_o = u_top.u_sdram_ctrl.wb_ack_o;
+wire        wbd_sdram_we_i  = u_top.u_sdram_ctrl.wb_we_i;
+wire [31:0] wbd_sdram_adr_i = u_top.u_sdram_ctrl.wb_addr_i;
+wire [31:0] wbd_sdram_dat_i = u_top.u_sdram_ctrl.wb_dat_i;
+wire [31:0] wbd_sdram_dat_o = u_top.u_sdram_ctrl.wb_dat_o;
+wire [3:0]  wbd_sdram_sel_i = u_top.u_sdram_ctrl.wb_sel_i;
+
+wire        wbd_uart_stb_i  = u_top.u_uart_i2c.u_uart_core.reg_cs;
+wire        wbd_uart_ack_o  = u_top.u_uart_i2c.u_uart_core.reg_ack;
+wire        wbd_uart_we_i   = u_top.u_uart_i2c.u_uart_core.reg_wr;
+wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_i2c.u_uart_core.reg_addr;
+wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_i2c.u_uart_core.reg_wdata;
+wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_i2c.u_uart_core.reg_rdata;
+wire        wbd_uart_sel_i  = u_top.u_uart_i2c.u_uart_core.reg_be;
+
+`endif
+
+/**
+`ifdef GL
+//-----------------------------------------------------------------------------
+// RISC IMEM amd DMEM Monitoring TASK
+//-----------------------------------------------------------------------------
+
+`define RISC_CORE  user_uart_tb.u_top.u_core.u_riscv_top
+
+always@(posedge `RISC_CORE.wb_clk) begin
+    if(`RISC_CORE.wbd_imem_ack_i)
+          $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x", `RISC_CORE.wbd_imem_adr_o,`RISC_CORE.wbd_imem_dat_i);
+    if(`RISC_CORE.wbd_dmem_ack_i && `RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_o);
+    if(`RISC_CORE.wbd_dmem_ack_i && !`RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_i);
+end
+
+`endif
+**/
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/user_i2cm/user_uart.c b/verilog/dv/user_i2cm/user_uart.c
new file mode 100644
index 0000000..b86f23b
--- /dev/null
+++ b/verilog/dv/user_i2cm/user_uart.c
@@ -0,0 +1,42 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+// //////////////////////////////////////////////////////////////////////////
+#define SC_SIM_OUTPORT (0xf0000000)
+#define uint32_t  long
+
+#define reg_mprj_uart_reg0 (*(volatile uint32_t*)0x30010000)
+#define reg_mprj_uart_reg1 (*(volatile uint32_t*)0x30010004)
+#define reg_mprj_uart_reg2 (*(volatile uint32_t*)0x30010008)
+#define reg_mprj_uart_reg3 (*(volatile uint32_t*)0x3001000C)
+#define reg_mprj_uart_reg4 (*(volatile uint32_t*)0x30010010)
+#define reg_mprj_uart_reg5 (*(volatile uint32_t*)0x30010014)
+#define reg_mprj_uart_reg6 (*(volatile uint32_t*)0x30010018)
+#define reg_mprj_uart_reg7 (*(volatile uint32_t*)0x3001001C)
+#define reg_mprj_uart_reg8 (*(volatile uint32_t*)0x30010020)
+
+int main()
+{
+
+    while(1) {
+       // Check UART RX fifo has data, if available loop back the data
+       if(reg_mprj_uart_reg8 != 0) { 
+	   reg_mprj_uart_reg5 = reg_mprj_uart_reg6;
+       }
+    }
+
+    return 0;
+}
diff --git a/verilog/dv/user_mbist_test1/Makefile b/verilog/dv/user_mbist_test1/Makefile
new file mode 100644
index 0000000..685d6ba
--- /dev/null
+++ b/verilog/dv/user_mbist_test1/Makefile
@@ -0,0 +1,109 @@
+# 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_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_BEHAVIOURAL_AGENTS = ../agents
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/yifive/ycr1c/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include
+
+## YIFIVE FIRMWARE
+YIFIVE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/dv/firmware
+GCC64_PREFIX?=riscv64-unknown-elf
+
+## RISCV GCC 
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+DUMP?=OFF
+
+.SUFFIXES:
+
+PATTERN = user_mbist_test1
+
+all:  ${PATTERN:=.vcd}
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v 
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+    else  
+	iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+   endif
+else  
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_GL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	$< -o $@ 
+endif
+
+%.vcd: %.vvp
+	vvp $<  | tee sim_result.log
+
+check-env:
+ifndef PDK_ROOT
+	$(error PDK_ROOT is undefined, please export it before running make)
+endif
+ifeq (,$(wildcard $(PDK_ROOT)/sky130A))
+	$(error $(PDK_ROOT)/sky130A not found, please install pdk before running make)
+endif
+#ifeq (,$(wildcard $(GCC64_PREFIX)-gcc ))
+#	$(error $(GCC64_PREFIX)-gcc is not found, please export GCC_PATH and GCC_PREFIX before running make)
+#endif
+# check for efabless style installation
+ifeq (,$(wildcard $(PDK_ROOT)/sky130A/libs.ref/*/verilog))
+SIM_DEFINES := ${SIM_DEFINES} -DEF_STYLE
+endif
+
+# ---- Clean ----
+
+clean:
+	rm -f *.vvp *.vcd *.log
+
+.PHONY: clean all
diff --git a/verilog/dv/user_mbist_test1/run_iverilog b/verilog/dv/user_mbist_test1/run_iverilog
new file mode 100755
index 0000000..e66b863
--- /dev/null
+++ b/verilog/dv/user_mbist_test1/run_iverilog
@@ -0,0 +1,31 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# // 
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# //      http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+
+#iverilog without Dump
+#
+iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I /home/dinesha/workarea/efabless/MPW-3/pdk/sky130A \
+-I /home/dinesha/workarea/opencore/git/riscduino/caravel/verilog/dv/caravel \
+-I /home/dinesha/workarea/opencore/git/riscduino/caravel/verilog/rtl \
+-I ../    -I ../../../verilog/rtl \
+-I ../../../verilog/rtl/mbist/include \
+user_mbist_test1_tb.v -o user_mbist_test1.vvp
+
+
+vvp user_mbist_test1.vvp | tee test.log
+
+\rm -rf user_mbist_test1.vvp
diff --git a/verilog/dv/user_mbist_test1/user_mbist_test1_tb.v b/verilog/dv/user_mbist_test1/user_mbist_test1_tb.v
new file mode 100644
index 0000000..c570e18
--- /dev/null
+++ b/verilog/dv/user_mbist_test1/user_mbist_test1_tb.v
@@ -0,0 +1,1139 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  Standalone User validation Test bench                       ////
+////                                                              ////
+////                                                              ////
+////  Description                                                 ////
+////   This is a standalone test bench to validate the            ////
+////   Digital core MBIST logic through External WB i/F.          ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      - Dinesh Annayya, dinesha@opencores.org                 ////
+////                                                              ////
+////  Revision :                                                  ////
+////    0.1 - 18 Oct 2021, Dinesh A                               ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+`default_nettype wire
+
+`timescale 1 ns / 1 ns
+
+`include "uprj_netlists.v"
+
+`define WB_MAP           `30080_0000
+`define GLBL_FUNC_MAP    'h3002_0000
+`define MBIST1_FUNC_MAP  'h3003_0000  // 0x3003_0000 to 0x3003_07FF
+`define MBIST2_FUNC_MAP  'h3003_0800  // 0x3003_0800 to 0x3003_0FFF
+`define MBIST3_FUNC_MAP  'h3003_1000  // 0x3003_1000 to 0x3003_17FF
+`define MBIST4_FUNC_MAP  'h3003_1800  // 0x3003_1800 to 0x3003_1FFF
+
+`define GLBL_BIST_CTRL1  'h3002_0070    
+`define GLBL_BIST_STAT1  'h3002_0074
+`define GLBL_BIST_SWDATA 'h3002_0078
+`define GLBL_BIST_SRDATA 'h3002_007C
+`define GLBL_BIST_SPDATA 'h3002_0078  #
+
+`define WB_GLBL_CTRL     'h3080_0000
+
+`define NO_SRAM          4 // 8
+
+
+
+module user_mbist_test1_tb;
+	reg clock;
+	reg wb_rst_i;
+	reg power1, power2;
+	reg power3, power4;
+
+        reg        wbd_ext_cyc_i;  // strobe/request
+        reg        wbd_ext_stb_i;  // strobe/request
+        reg [31:0] wbd_ext_adr_i;  // address
+        reg        wbd_ext_we_i;  // write
+        reg [31:0] wbd_ext_dat_i;  // data output
+        reg [3:0]  wbd_ext_sel_i;  // byte enable
+
+        wire [31:0] wbd_ext_dat_o;  // data input
+        wire        wbd_ext_ack_o;  // acknowlegement
+        wire        wbd_ext_err_o;  // error
+
+	// 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;
+        reg [31:0] writemem [0:511];
+        reg [8:0]  faultaddr [0:7];
+        integer i;
+        event      error_insert;
+
+
+	// 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("simx.vcd");
+	   	$dumpvars(2, user_mbist_test1_tb);
+	   	$dumpvars(0, user_mbist_test1_tb.u_top.u_mbist);
+	   	$dumpvars(0, user_mbist_test1_tb.u_top.u_intercon);
+		$dumpoff;
+	   end
+       `endif
+
+	initial begin
+		wb_rst_i <= 1'b1;
+		#100;
+		wb_rst_i <= 1'b0;	    	// Release reset
+
+		#200; // Wait for reset removal
+	        repeat (10) @(posedge clock);
+		$display("Monitor: Standalone User Test Started");
+
+		test_fail = 0;
+		// Remove Wb Reset
+		wb_user_core_write(`WB_GLBL_CTRL,'h1);
+
+		$dumpoff;
+	    	$display("###################################################");
+	    	$display(" MBIST Test with Without Address Failure");
+	    	$display("###################################################");
+
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 0
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h0
+		insert_fault(0,0,0,0,0,32'h01010101);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-1: BIST Test without any Memory Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-1: BIST Test without any Memory Error insertion test Failed");
+		end
+	    	$display("###################################################");
+	    	
+		$display("#########################################################");
+	    	$display(" MBIST Test with With Single Address Failure for MEM-0");
+	    	$display("#########################################################");
+
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h1
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(1,0,0,0,0,32'h01010115);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-2.1: BIST Test with Single Address Failure at MEM0 Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-2.1: BIST Test with Single Address Failure at MEM0 Error insertion test Failed");
+		end
+		$display("##########################################################");
+	    	$display(" MBIST Test with With Single Address Failure for MEM-0/1");
+	    	$display("##########################################################");
+
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h1
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(1,1,0,0,0,32'h01011515);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-2.2: BIST Test with Single Address Failure at MEM0/1 Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-2.2: BIST Test with Single Address Failure at MEM0/1 Error insertion test Failed");
+		end
+		$display("##########################################################");
+	    	$display(" MBIST Test with With Single Address Failure for MEM-0/1/2");
+	    	$display("##########################################################");
+
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h1
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(1,1,1,0,0,32'h01151515);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-2.3: BIST Test with Single Address Failure at MEM0/1/2 Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-2.3: BIST Test with Single Address Failure at MEM0/1/2 Error insertion test Failed");
+		end
+
+	    	$display("###################################################");
+	    	$display(" MBIST Test with Single Address Failure to All Memory");
+	    	$display("###################################################");
+		   // Check Is there is any BIST Error
+		   // [0]   - Bist Done      - 1
+		   // [1]   - Bist Error     - 0
+		   // [2]   - Bist Correct   - 1
+		   // [3]   - Reserved       - 0
+		   // [7:4] - Bist Error Cnt - 4'h1
+		   //if(read_data[6:0]  != 7'b0001101) test_fail = 1; // Bist correct = 1 and Bist Err Cnt - 0x1
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(1,1,1,1,1,32'h15151515);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-2.4: BIST Test with One Memory Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-2.4: BIST Test with One Memory Error insertion test Failed");
+		end
+	    	$display("###################################################");
+
+		$display("#########################################################");
+	    	$display(" MBIST Test with With Two Address Failure for MEM-0");
+	    	$display("#########################################################");
+
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h2
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(2,0,0,0,0,32'h01010125);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-3.1: BIST Test with Two Address Failure at MEM0 Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-3.1: BIST Test with Two Address Failure at MEM0 Error insertion test Failed");
+		end
+		$display("##########################################################");
+	    	$display(" MBIST Test with With Two Address Failure for MEM-0/1");
+	    	$display("##########################################################");
+
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h2
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(2,2,0,0,0,32'h01012525);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-3.2: BIST Test with Two Address Failure at MEM0/1 Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-3.2: BIST Test with Two Address Failure at MEM0/1 Error insertion test Failed");
+		end
+		$display("##########################################################");
+	    	$display(" MBIST Test with With Two Address Failure for MEM-0/1/2");
+	    	$display("##########################################################");
+
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h2
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(2,2,2,0,0,32'h01252525);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-3.3: BIST Test with Two Address Failure at MEM0/1/2 Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-3.3: BIST Test with Two Address Failure at MEM0/1/2 Error insertion test Failed");
+		end
+
+	    	$display("###################################################");
+	    	$display(" MBIST Test with Two Address Failure to All Memory");
+	    	$display("###################################################");
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h2
+		   //if(read_data[6:0]  != 7'b0001101) test_fail = 1; // Bist correct = 1 and Bist Err Cnt - 0x1
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(2,2,2,2,1,32'h25252525);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-3.4: BIST Test with Two Memory Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-3.4: BIST Test with Two Memory Error insertion test Failed");
+		end
+	    	$display("###################################################");
+
+		$display("#########################################################");
+	    	$display(" MBIST Test with With Three Address Failure for MEM-0");
+	    	$display("#########################################################");
+
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h3
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(3,0,0,0,0,32'h01010135);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-4.1: BIST Test with Three Address Failure at MEM0 Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-4.1: BIST Test with Three Address Failure at MEM0 Error insertion test Failed");
+		end
+		$display("##########################################################");
+	    	$display(" MBIST Test with With Three Address Failure for MEM-0/1");
+	    	$display("##########################################################");
+
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h3
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(3,3,0,0,0,32'h01013535);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-4.2: BIST Test with Three Address Failure at MEM0/1 Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-4.2: BIST Test with Three Address Failure at MEM0/1 Error insertion test Failed");
+		end
+		$display("##########################################################");
+	    	$display(" MBIST Test with With Three Address Failure for MEM-0/1/2");
+	    	$display("##########################################################");
+
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h3
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(3,3,3,0,0,32'h01353535);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-4.3: BIST Test with Three Address Failure at MEM0/1/2 Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-4.3: BIST Test with Three Address Failure at MEM0/1/2 Error insertion test Failed");
+		end
+
+	    	$display("###################################################");
+	    	$display(" MBIST Test with Three Address Failure to All Memory");
+	    	$display("###################################################");
+		   // Check Is there is any BIST Error
+		   // [0]   - Bist Done      - 1
+		   // [1]   - Bist Error     - 0
+		   // [2]   - Bist Correct   - 1
+		   // [3]   - Reserved       - 0
+		   // [7:4] - Bist Error Cnt - 4'h3
+		   //if(read_data[6:0]  != 7'b0001101) test_fail = 1; // Bist correct = 1 and Bist Err Cnt - 0x1
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(3,3,3,3,1,32'h35353535);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-4.4: BIST Test with Three Memory Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-4.4: BIST Test with Three Memory Error insertion test Failed");
+		end
+	    	$display("###################################################");
+
+		$display("#########################################################");
+	    	$display(" MBIST Test with With Four Address Failure for MEM-0");
+	    	$display("#########################################################");
+
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h4
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(4,0,0,0,0,32'h01010145);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-4.1: BIST Test with Four Address Failure at MEM0 Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-4.1: BIST Test with Four Address Failure at MEM0 Error insertion test Failed");
+		end
+		$display("##########################################################");
+	    	$display(" MBIST Test with With Four Address Failure for MEM-0/1");
+	    	$display("##########################################################");
+
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h4
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(4,4,0,0,0,32'h01014545);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-4.2: BIST Test with Four Address Failure at MEM0/1 Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-4.2: BIST Test with Four Address Failure at MEM0/1 Error insertion test Failed");
+		end
+		$display("##########################################################");
+	    	$display(" MBIST Test with With Four Address Failure for MEM-0/1/2");
+	    	$display("##########################################################");
+
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h3
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(4,4,4,0,0,32'h01454545);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-4.3: BIST Test with Four Address Failure at MEM0/1/2 Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-4.3: BIST Test with Four Address Failure at MEM0/1/2 Error insertion test Failed");
+		end
+
+	    	$display("###################################################");
+	    	$display(" MBIST Test with Four Address Failure to All Memory");
+	    	$display("###################################################");
+		   // Check Is there is any BIST Error
+		   // [0]   - Bist Done      - 1
+		   // [1]   - Bist Error     - 0
+		   // [2]   - Bist Correct   - 1
+		   // [3]   - Reserved       - 0
+		   // [7:4] - Bist Error Cnt - 4'h3
+		   //if(read_data[6:0]  != 7'b0001101) test_fail = 1; // Bist correct = 1 and Bist Err Cnt - 0x1
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		insert_fault(4,4,4,4,1,32'h45454545);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-4.4: BIST Test with Four Memory Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-4.4: BIST Test with Four Memory Error insertion test Failed");
+		end
+	    	$display("###################################################");
+
+
+	    	$display("###################################################");
+	    	$display(" MBIST Test with Fours Address(Continous Starting Addrsess) Failure");
+	    	$display("###################################################");
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h4
+		//if(read_data[6:0]  != 7'b0100101) test_fail = 1; // Bist correct = 1 and Bist Err Cnt - 0x4
+		faultaddr[0] = 9'h0;
+		faultaddr[1] = 9'h1;
+		faultaddr[2] = 9'h2;
+		faultaddr[3] = 9'h3;
+		insert_fault(4,4,4,4,0,32'h45454545);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-5.1: BIST Test with Four Memory Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-5.1: BIST Test with Four Memory Error insertion test Failed");
+		end
+
+	    	$display("###################################################");
+	    	$display(" MBIST Test with Fours Address(Last Addrsess) Failure");
+	    	$display("###################################################");
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 0
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h4
+		//if(read_data[6:0]  != 7'b0100101) test_fail = 1; // Bist correct = 1 and Bist Err Cnt - 0x4
+		faultaddr[0] = 9'hF0;
+		faultaddr[1] = 9'hF1;
+		faultaddr[2] = 9'hF2;
+		faultaddr[3] = 9'hF3;
+		insert_fault(4,4,4,4,0,32'h45454545);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-5.2: BIST Test with Four Memory Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-5.2: BIST Test with Four Memory Error insertion test Failed");
+		end
+	    	
+		$display("###################################################");
+	    	$display(" MBIST Test with Five Address Failure for MEM0");
+	    	$display("###################################################");
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 1
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h4
+		//if(read_data[6:0]  != 7'b0100101) test_fail = 1; // Bist correct = 1 and Bist Err Cnt - 0x4
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		faultaddr[4] = 9'h50;
+		insert_fault(5,0,0,0,1,32'h01010147);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-6.1: BIST Test with Five Memory Error insertion for MEM0 test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-6.1: BIST Test with Five Memory Error insertion for MEM0 test Failed");
+		 end
+
+		$display("###################################################");
+	    	$display(" MBIST Test with Five Address Failure for MEM0/1");
+	    	$display("###################################################");
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 1
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h4
+		//if(read_data[6:0]  != 7'b0100101) test_fail = 1; // Bist correct = 1 and Bist Err Cnt - 0x4
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		faultaddr[4] = 9'h50;
+		insert_fault(5,5,0,0,1,32'h01014747);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-6.2: BIST Test with Five Memory Error insertion for MEM0/1 test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-6.2: BIST Test with Five Memory Error insertion for MEM0/1 test Failed");
+		 end
+
+        	$display("###################################################");
+	    	$display(" MBIST Test with Five Address Failure for MEM0/1/2");
+	    	$display("###################################################");
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 1
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h4
+		//if(read_data[6:0]  != 7'b0100101) test_fail = 1; // Bist correct = 1 and Bist Err Cnt - 0x4
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		faultaddr[4] = 9'h50;
+		insert_fault(5,5,5,0,1,32'h01474747);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-6.3: BIST Test with Five Memory Error insertion for MEM0/1/2 test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-6.3: BIST Test with Five Memory Error insertion for MEM0/1/2 test Failed");
+		 end
+
+	    	$display("###################################################");
+	    	$display(" MBIST Test with Five Address Failure for All Memory");
+	    	$display("###################################################");
+		// Check Is there is any BIST Error
+		// [0]   - Bist Done      - 1
+		// [1]   - Bist Error     - 1
+		// [2]   - Bist Correct   - 1
+		// [3]   - Reserved       - 0
+		// [7:4] - Bist Error Cnt - 4'h4
+		//if(read_data[6:0]  != 7'b0100101) test_fail = 1; // Bist correct = 1 and Bist Err Cnt - 0x4
+		faultaddr[0] = 9'h10;
+		faultaddr[1] = 9'h20;
+		faultaddr[2] = 9'h30;
+		faultaddr[3] = 9'h40;
+		faultaddr[4] = 9'h50;
+		insert_fault(5,5,5,5,1,32'h47474747);
+
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-6.4: BIST Test with Five Memory Error insertion test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-6.4: BIST Test with Five Memory Error insertion test Failed");
+		 end
+		$dumpon;
+	    	$display("###################################################");
+	    	$display(" MBIST Test with Functional Access, continuation of previous MBIST Signature");
+	    	$display("###################################################");
+		fork
+		begin
+		    // Remove the Bist Enable and Bist Run
+                    wb_user_core_write(`GLBL_BIST_CTRL1,'h000);
+                    // Remove WB and BIST RESET
+                    wb_user_core_write(`WB_GLBL_CTRL,'h081);
+  
+	            // Fill Random Data	
+		    for (i=0; i< 9'h1FC; i=i+1) begin
+   	                writemem[i] = $random;
+                        wb_user_core_write(`MBIST1_FUNC_MAP+(i*4),writemem[i]);
+                        wb_user_core_write(`MBIST2_FUNC_MAP+(i*4),writemem[i]);
+                        wb_user_core_write(`MBIST3_FUNC_MAP+(i*4),writemem[i]);
+                        wb_user_core_write(`MBIST4_FUNC_MAP+(i*4),writemem[i]);
+		        //if(i < 9'h0FC) begin // SRAM5-SRAM8 are 1KB
+                        //   wb_user_core_write(`MBIST5_FUNC_MAP+(i*4),writemem[i]);
+                        //   wb_user_core_write(`MBIST6_FUNC_MAP+(i*4),writemem[i]);
+                        //   wb_user_core_write(`MBIST7_FUNC_MAP+(i*4),writemem[i]);
+                        //   wb_user_core_write(`MBIST8_FUNC_MAP+(i*4),writemem[i]);
+	                //end
+		    end
+		    // Read back data
+		    for (i=0; i< 9'h1FC; i=i+1) begin
+                        wb_user_core_read_check(`MBIST1_FUNC_MAP+(i*4),read_data,writemem[i],32'hFFFFFFFF);
+                        wb_user_core_read_check(`MBIST2_FUNC_MAP+(i*4),read_data,writemem[i],32'hFFFFFFFF);
+                        wb_user_core_read_check(`MBIST3_FUNC_MAP+(i*4),read_data,writemem[i],32'hFFFFFFFF);
+                        wb_user_core_read_check(`MBIST4_FUNC_MAP+(i*4),read_data,writemem[i],32'hFFFFFFFF);
+		        //if(i < 9'h0FC) begin // SRAM5 - SRAM8 are 1KB
+                        //   wb_user_core_read_check(`MBIST5_FUNC_MAP+(i*4),read_data,writemem[i],32'hFFFFFFFF);
+                        //   wb_user_core_read_check(`MBIST6_FUNC_MAP+(i*4),read_data,writemem[i],32'hFFFFFFFF);
+                        //   wb_user_core_read_check(`MBIST7_FUNC_MAP+(i*4),read_data,writemem[i],32'hFFFFFFFF);
+                        //   wb_user_core_read_check(`MBIST8_FUNC_MAP+(i*4),read_data,writemem[i],32'hFFFFFFFF);
+	                //end
+		    end
+
+		    // Cross-check Reducency address hold the failure address data
+		    // Is last Error inserted address are 0x10,0x20,0x30,0x40
+		    // So Address 0x1FC = Data[0x10], 0x1FD = Data[0x20]
+		    //    Address 0x1FE = Data[0x30], 0x1FF = Data[0x40]
+		    // Check 2kb SRAM1
+                    wb_user_core_read_check(`MBIST1_FUNC_MAP + (9'h1FC *4),read_data,writemem[9'h10],32'hFFFFFFFF);
+                    wb_user_core_read_check(`MBIST1_FUNC_MAP + (9'h1FD *4),read_data,writemem[9'h20],32'hFFFFFFFF);
+                    wb_user_core_read_check(`MBIST1_FUNC_MAP + (9'h1FE *4),read_data,writemem[9'h30],32'hFFFFFFFF);
+                    wb_user_core_read_check(`MBIST1_FUNC_MAP + (9'h1FF *4),read_data,writemem[9'h40],32'hFFFFFFFF);
+
+		    // Check 2kb SRAM2
+                    wb_user_core_read_check(`MBIST2_FUNC_MAP + (9'h1FC *4),read_data,writemem[9'h11],32'hFFFFFFFF);
+                    wb_user_core_read_check(`MBIST2_FUNC_MAP + (9'h1FD *4),read_data,writemem[9'h21],32'hFFFFFFFF);
+                    wb_user_core_read_check(`MBIST2_FUNC_MAP + (9'h1FE *4),read_data,writemem[9'h31],32'hFFFFFFFF);
+                    wb_user_core_read_check(`MBIST2_FUNC_MAP + (9'h1FF *4),read_data,writemem[9'h41],32'hFFFFFFFF);
+
+		    //// Check 2kb SRAM3
+                    wb_user_core_read_check(`MBIST3_FUNC_MAP + (9'h1FC *4),read_data,writemem[9'h12],32'hFFFFFFFF);
+                    wb_user_core_read_check(`MBIST3_FUNC_MAP + (9'h1FD *4),read_data,writemem[9'h22],32'hFFFFFFFF);
+                    wb_user_core_read_check(`MBIST3_FUNC_MAP + (9'h1FE *4),read_data,writemem[9'h32],32'hFFFFFFFF);
+                    wb_user_core_read_check(`MBIST3_FUNC_MAP + (9'h1FF *4),read_data,writemem[9'h42],32'hFFFFFFFF);
+
+		    //// Check 2kb SRAM4
+                    wb_user_core_read_check(`MBIST4_FUNC_MAP + (9'h1FC *4),read_data,writemem[9'h13],32'hFFFFFFFF);
+                    wb_user_core_read_check(`MBIST4_FUNC_MAP + (9'h1FD *4),read_data,writemem[9'h23],32'hFFFFFFFF);
+                    wb_user_core_read_check(`MBIST4_FUNC_MAP + (9'h1FE *4),read_data,writemem[9'h33],32'hFFFFFFFF);
+                    wb_user_core_read_check(`MBIST4_FUNC_MAP + (9'h1FF *4),read_data,writemem[9'h43],32'hFFFFFFFF);
+
+		    //// Check 1kb SRAM5
+                    //wb_user_core_read_check(`MBIST5_FUNC_MAP + (8'hFC *4),read_data,writemem[9'h14],32'hFFFFFFFF);
+                    //wb_user_core_read_check(`MBIST5_FUNC_MAP + (8'hFD *4),read_data,writemem[9'h24],32'hFFFFFFFF);
+                    //wb_user_core_read_check(`MBIST5_FUNC_MAP + (8'hFE *4),read_data,writemem[9'h34],32'hFFFFFFFF);
+                    //wb_user_core_read_check(`MBIST5_FUNC_MAP + (8'hFF *4),read_data,writemem[9'h44],32'hFFFFFFFF);
+
+		    //// Check 1kb SRAM6
+                    //wb_user_core_read_check(`MBIST6_FUNC_MAP + (8'hFC *4),read_data,writemem[9'h15],32'hFFFFFFFF);
+                    //wb_user_core_read_check(`MBIST6_FUNC_MAP + (8'hFD *4),read_data,writemem[9'h25],32'hFFFFFFFF);
+                    //wb_user_core_read_check(`MBIST6_FUNC_MAP + (8'hFE *4),read_data,writemem[9'h35],32'hFFFFFFFF);
+                    //wb_user_core_read_check(`MBIST6_FUNC_MAP + (8'hFF *4),read_data,writemem[9'h45],32'hFFFFFFFF);
+
+		    //// Check 1kb SRAM7
+                    //wb_user_core_read_check(`MBIST7_FUNC_MAP + (8'hFC *4),read_data,writemem[9'h16],32'hFFFFFFFF);
+                    //wb_user_core_read_check(`MBIST7_FUNC_MAP + (8'hFD *4),read_data,writemem[9'h26],32'hFFFFFFFF);
+                    //wb_user_core_read_check(`MBIST7_FUNC_MAP + (8'hFE *4),read_data,writemem[9'h36],32'hFFFFFFFF);
+                    //wb_user_core_read_check(`MBIST7_FUNC_MAP + (8'hFF *4),read_data,writemem[9'h46],32'hFFFFFFFF);
+
+		    //// Check 1kb SRAM8
+                    //wb_user_core_read_check(`MBIST8_FUNC_MAP + (8'hFC *4),read_data,writemem[9'h17],32'hFFFFFFFF);
+                    //wb_user_core_read_check(`MBIST8_FUNC_MAP + (8'hFD *4),read_data,writemem[9'h27],32'hFFFFFFFF);
+                    //wb_user_core_read_check(`MBIST8_FUNC_MAP + (8'hFE *4),read_data,writemem[9'h37],32'hFFFFFFFF);
+                    //wb_user_core_read_check(`MBIST8_FUNC_MAP + (8'hFF *4),read_data,writemem[9'h47],32'hFFFFFFFF);
+                end
+                begin
+                   // Loop for BIST TimeOut
+                   repeat (200000) @(posedge clock);
+                		// $display("+1000 cycles");
+                   test_fail = 1;
+                end
+                join_any
+                disable fork; //disable pending fork activity
+          	if(test_fail == 0) begin
+	    	    $display("Monitor: Step-7: BIST Test with Functional access test Passed");
+	        end else begin
+	    	    $display("Monitor: Step-7: BIST Test with Functional access test failed");
+		 end
+
+	    	$display("###################################################");
+	        $finish;
+	end
+
+wire USER_VDD1V8 = 1'b1;
+wire VSS = 1'b0;
+
+
+user_project_wrapper u_top(
+`ifdef USE_POWER_PINS
+    .vccd1(USER_VDD1V8),	// User area 1 1.8V supply
+    .vssd1(VSS),	// User area 1 digital ground
+`endif
+    .wb_clk_i        (clock),  // System clock
+    .user_clock2     (1'b1),  // Real-time clock
+    .wb_rst_i        (wb_rst_i),  // Regular Reset signal
+
+    .wbs_cyc_i   (wbd_ext_cyc_i),  // strobe/request
+    .wbs_stb_i   (wbd_ext_stb_i),  // strobe/request
+    .wbs_adr_i   (wbd_ext_adr_i),  // address
+    .wbs_we_i    (wbd_ext_we_i),  // write
+    .wbs_dat_i   (wbd_ext_dat_i),  // data output
+    .wbs_sel_i   (wbd_ext_sel_i),  // byte enable
+
+    .wbs_dat_o   (wbd_ext_dat_o),  // data input
+    .wbs_ack_o   (wbd_ext_ack_o),  // acknowlegement
+
+ 
+    // Logic Analyzer Signals
+    .la_data_in      ('1) ,
+    .la_data_out     (),
+    .la_oenb         ('0),
+ 
+
+    // IOs
+    .io_in          (io_in)  ,
+    .io_out         (io_out) ,
+    .io_oeb         (io_oeb) ,
+
+    .user_irq       () 
+
+);
+
+`ifndef GL // Drive Power for Hold Fix Buf
+    // All standard cell need power hook-up for functionality work
+    initial begin
+
+
+    end
+`endif    
+
+
+//-------------------------------------
+// Insert user defined number of fault 
+// -----------------------------------
+
+task insert_fault;
+input [3:0]  num0_fault;
+input [3:0]  num1_fault;
+input [3:0]  num2_fault;
+input [3:0]  num3_fault;
+input        fault_type; // 0 -> struck at 0 and 1 -> struck at 1
+input [31:0]  mbist_signature;
+reg [31:0] datain;
+reg [8:0]  fail_addr1;
+reg [8:0]  fail_addr2;
+reg [8:0]  fail_addr3;
+reg [8:0]  fail_addr4;
+reg [3:0]  num_fault[0:3];
+integer j;
+begin
+   num_fault[0] = num0_fault;
+   num_fault[1] = num1_fault;
+   num_fault[2] = num2_fault;
+   num_fault[3] = num3_fault;
+   repeat (2) @(posedge clock);
+   fork
+   begin
+       // Remove the Bist Enable and Bist Run
+       wb_user_core_write(`GLBL_BIST_CTRL1,'h000);
+       // Remove WB and BIST RESET
+       wb_user_core_write(`WB_GLBL_CTRL,'h001);
+       // Set the Bist Enable and Bist Run
+       wb_user_core_write(`GLBL_BIST_CTRL1,'h00000003);
+       // Remove WB and BIST RESET
+       wb_user_core_write(`WB_GLBL_CTRL,'h081);
+      // Check for MBIST Done
+      read_data = 'h0;
+      while (read_data[0] != 1'b1) begin
+         wb_user_core_read(`GLBL_BIST_STAT1,read_data);
+      end
+      // wait for some time for all the BIST to complete
+      repeat (1000) @(posedge clock);
+      // Toggle the Bist Load for update the shift data
+      wb_user_core_write(`GLBL_BIST_CTRL1,'h00000004);
+      wb_user_core_write(`GLBL_BIST_CTRL1,'h00000000);
+      // Check Is there is any BIST Error
+      // [0]   - Bist Done      
+      // [1]   - Bist Error     
+      // [2]   - Bist Correct   
+      // [3]   - Reserved
+      // [7:4] - Bist Error Cnt 
+      wb_user_core_read_check(`GLBL_BIST_STAT1,read_data,mbist_signature[31:0],32'hFFFFFFFF);
+      //wb_user_core_read_check(`GLBL_BIST_STAT2,read_data,mbist_signature[63:32],32'hFFFFFFFF);
+   end
+   // Insert  Error Insertion
+   begin
+      while(1) begin
+         repeat (1) @(posedge clock);
+         #1;
+
+         if(u_top.u_sram0_2kb.web0 == 1'b0 && 
+	   ((num_fault[0] > 0 && u_top.u_sram0_2kb.addr0 == faultaddr[0]) ||
+	    (num_fault[0] > 1 && u_top.u_sram0_2kb.addr0 == faultaddr[1]) ||
+	    (num_fault[0] > 2 && u_top.u_sram0_2kb.addr0 == faultaddr[2]) ||
+	    (num_fault[0] > 3 && u_top.u_sram0_2kb.addr0 == faultaddr[3]) ||
+	    (num_fault[0] > 4 && u_top.u_sram0_2kb.addr0 == faultaddr[4]) ||
+	    (num_fault[0] > 5 && u_top.u_sram0_2kb.addr0 == faultaddr[5]) ||
+	    (num_fault[0] > 6 && u_top.u_sram0_2kb.addr0 == faultaddr[6]) ||
+	    (num_fault[0] > 7 && u_top.u_sram0_2kb.addr0 == faultaddr[7])))
+             begin
+	   if(fault_type == 0) // Struck at 0
+	      force u_top.u_sram0_2kb.din0 = u_top.mem0_din_a  & 32'hFFFF_FFFE;
+	   else
+	      force u_top.u_sram0_2kb.din0 = u_top.mem0_din_a | 32'h1;
+   	   -> error_insert;
+         end else begin
+            release u_top.u_sram0_2kb.din0;
+         end
+
+         if(u_top.u_sram1_2kb.web0 == 1'b0 && 
+	   ((num_fault[1] > 0 && u_top.u_sram1_2kb.addr0 == faultaddr[0]+1) ||
+	    (num_fault[1] > 1 && u_top.u_sram1_2kb.addr0 == faultaddr[1]+1) ||
+	    (num_fault[1] > 2 && u_top.u_sram1_2kb.addr0 == faultaddr[2]+1) ||
+	    (num_fault[1] > 3 && u_top.u_sram1_2kb.addr0 == faultaddr[3]+1) ||
+	    (num_fault[1] > 4 && u_top.u_sram1_2kb.addr0 == faultaddr[4]+1) ||
+	    (num_fault[1] > 5 && u_top.u_sram1_2kb.addr0 == faultaddr[5]+1) ||
+	    (num_fault[1] > 6 && u_top.u_sram1_2kb.addr0 == faultaddr[6]+1) ||
+	    (num_fault[1] > 7 && u_top.u_sram1_2kb.addr0 == faultaddr[7]+1)))
+             begin
+	   if(fault_type == 0) // Struck at 0
+	      force u_top.u_sram1_2kb.din0 = u_top.mem1_din_a  & 32'hFFFF_FFFE;
+	   else
+	      force u_top.u_sram1_2kb.din0 = u_top.mem1_din_a | 32'h1;
+   	   -> error_insert;
+         end else begin
+            release u_top.u_sram1_2kb.din0;
+         end
+
+         if(u_top.u_sram2_2kb.web0 == 1'b0 && 
+	   ((num_fault[2] > 0 && u_top.u_sram2_2kb.addr0 == faultaddr[0]+2) ||
+	    (num_fault[2] > 1 && u_top.u_sram2_2kb.addr0 == faultaddr[1]+2) ||
+	    (num_fault[2] > 2 && u_top.u_sram2_2kb.addr0 == faultaddr[2]+2) ||
+	    (num_fault[2] > 3 && u_top.u_sram2_2kb.addr0 == faultaddr[3]+2) ||
+	    (num_fault[2] > 4 && u_top.u_sram2_2kb.addr0 == faultaddr[4]+2) ||
+	    (num_fault[2] > 5 && u_top.u_sram2_2kb.addr0 == faultaddr[5]+2) ||
+	    (num_fault[2] > 6 && u_top.u_sram2_2kb.addr0 == faultaddr[6]+2) ||
+	    (num_fault[2] > 7 && u_top.u_sram2_2kb.addr0 == faultaddr[7]+2)))
+             begin
+	   if(fault_type == 0) // Struck at 0
+	      force u_top.u_sram2_2kb.din0 = u_top.mem2_din_a  & 32'hFFFF_FFFE;
+	   else
+	      force u_top.u_sram2_2kb.din0 = u_top.mem2_din_a | 32'h1;
+   	   -> error_insert;
+         end else begin
+            release u_top.u_sram2_2kb.din0;
+         end
+
+         if(u_top.u_sram3_2kb.web0 == 1'b0 && 
+	   ((num_fault[3] > 0 && u_top.u_sram3_2kb.addr0 == faultaddr[0]+3) ||
+	    (num_fault[3] > 1 && u_top.u_sram3_2kb.addr0 == faultaddr[1]+3) ||
+	    (num_fault[3] > 2 && u_top.u_sram3_2kb.addr0 == faultaddr[2]+3) ||
+	    (num_fault[3] > 3 && u_top.u_sram3_2kb.addr0 == faultaddr[3]+3) ||
+	    (num_fault[3] > 4 && u_top.u_sram3_2kb.addr0 == faultaddr[4]+3) ||
+	    (num_fault[3] > 5 && u_top.u_sram3_2kb.addr0 == faultaddr[5]+3) ||
+	    (num_fault[3] > 6 && u_top.u_sram3_2kb.addr0 == faultaddr[6]+3) ||
+	    (num_fault[3] > 7 && u_top.u_sram3_2kb.addr0 == faultaddr[7]+3)))
+             begin
+	   if(fault_type == 0) // Struck at 0
+	      force u_top.u_sram3_2kb.din0 = u_top.mem3_din_a  & 32'hFFFF_FFFE;
+	   else
+	      force u_top.u_sram3_2kb.din0 = u_top.mem3_din_a | 32'h1;
+   	   -> error_insert;
+         end else begin
+            release u_top.u_sram3_2kb.din0;
+         end
+
+         //if(u_top.u_sram5_1kb.web0 == 1'b0 && 
+	 //  ((num_fault > 0 && u_top.u_sram5_1kb.addr0 == faultaddr[0]+4) ||
+	 //   (num_fault > 1 && u_top.u_sram5_1kb.addr0 == faultaddr[1]+4) ||
+	 //   (num_fault > 2 && u_top.u_sram5_1kb.addr0 == faultaddr[2]+4) ||
+	 //   (num_fault > 3 && u_top.u_sram5_1kb.addr0 == faultaddr[3]+4) ||
+	 //   (num_fault > 4 && u_top.u_sram5_1kb.addr0 == faultaddr[4]+4) ||
+	 //   (num_fault > 5 && u_top.u_sram5_1kb.addr0 == faultaddr[5]+4) ||
+	 //   (num_fault > 6 && u_top.u_sram5_1kb.addr0 == faultaddr[6]+4) ||
+	 //   (num_fault > 7 && u_top.u_sram5_1kb.addr0 == faultaddr[7]+4)))
+         //    begin
+	 //  if(fault_type == 0) // Struck at 0
+	 //     force u_top.u_sram5_1kb.din0 = u_top.mem5_din_b  & 32'hFFFF_FFFE;
+	 //  else
+	 //     force u_top.u_sram5_1kb.din0 = u_top.mem5_din_b | 32'h1;
+   	 //  -> error_insert;
+         //end else begin
+         //   release u_top.u_sram5_1kb.din0;
+         //end
+
+         //if(u_top.u_sram6_1kb.web0 == 1'b0 && 
+	 //  ((num_fault > 0 && u_top.u_sram6_1kb.addr0 == faultaddr[0]+5) ||
+	 //   (num_fault > 1 && u_top.u_sram6_1kb.addr0 == faultaddr[1]+5) ||
+	 //   (num_fault > 2 && u_top.u_sram6_1kb.addr0 == faultaddr[2]+5) ||
+	 //   (num_fault > 3 && u_top.u_sram6_1kb.addr0 == faultaddr[3]+5) ||
+	 //   (num_fault > 4 && u_top.u_sram6_1kb.addr0 == faultaddr[4]+5) ||
+	 //   (num_fault > 5 && u_top.u_sram6_1kb.addr0 == faultaddr[5]+5) ||
+	 //   (num_fault > 6 && u_top.u_sram6_1kb.addr0 == faultaddr[6]+5) ||
+	 //   (num_fault > 7 && u_top.u_sram6_1kb.addr0 == faultaddr[7]+5)))
+         //    begin
+	 //  if(fault_type == 0) // Struck at 0
+	 //     force u_top.u_sram6_1kb.din0 = u_top.mem6_din_b  & 32'hFFFF_FFFE;
+	 //  else
+	 //     force u_top.u_sram6_1kb.din0 = u_top.mem6_din_b | 32'h1;
+   	 //  -> error_insert;
+         //end else begin
+         //   release u_top.u_sram6_1kb.din0;
+         //end
+
+         //if(u_top.u_sram7_1kb.web0 == 1'b0 && 
+	 //  ((num_fault > 0 && u_top.u_sram7_1kb.addr0 == faultaddr[0]+6) ||
+	 //   (num_fault > 1 && u_top.u_sram7_1kb.addr0 == faultaddr[1]+6) ||
+	 //   (num_fault > 2 && u_top.u_sram7_1kb.addr0 == faultaddr[2]+6) ||
+	 //   (num_fault > 3 && u_top.u_sram7_1kb.addr0 == faultaddr[3]+6) ||
+	 //   (num_fault > 4 && u_top.u_sram7_1kb.addr0 == faultaddr[4]+6) ||
+	 //   (num_fault > 5 && u_top.u_sram7_1kb.addr0 == faultaddr[5]+6) ||
+	 //   (num_fault > 6 && u_top.u_sram7_1kb.addr0 == faultaddr[6]+6) ||
+	 //   (num_fault > 7 && u_top.u_sram7_1kb.addr0 == faultaddr[7]+6)))
+         //    begin
+	 //  if(fault_type == 0) // Struck at 0
+	 //     force u_top.u_sram7_1kb.din0 = u_top.mem7_din_b  & 32'hFFFF_FFFE;
+	 //  else
+	 //     force u_top.u_sram7_1kb.din0 = u_top.mem7_din_b | 32'h1;
+   	 //  -> error_insert;
+         //end else begin
+         //   release u_top.u_sram7_1kb.din0;
+         //end
+
+         //if(u_top.u_sram8_1kb.web0 == 1'b0 && 
+	 //  ((num_fault > 0 && u_top.u_sram8_1kb.addr0 == faultaddr[0]+7) ||
+	 //   (num_fault > 1 && u_top.u_sram8_1kb.addr0 == faultaddr[1]+7) ||
+	 //   (num_fault > 2 && u_top.u_sram8_1kb.addr0 == faultaddr[2]+7) ||
+	 //   (num_fault > 3 && u_top.u_sram8_1kb.addr0 == faultaddr[3]+7) ||
+	 //   (num_fault > 4 && u_top.u_sram8_1kb.addr0 == faultaddr[4]+7) ||
+	 //   (num_fault > 5 && u_top.u_sram8_1kb.addr0 == faultaddr[5]+7) ||
+	 //   (num_fault > 6 && u_top.u_sram8_1kb.addr0 == faultaddr[6]+7) ||
+	 //   (num_fault > 7 && u_top.u_sram8_1kb.addr0 == faultaddr[7]+7)))
+         //    begin
+	 //  if(fault_type == 0) // Struck at 0
+	 //     force u_top.u_sram8_1kb.din0 = u_top.mem8_din_b  & 32'hFFFF_FFFE;
+	 //  else
+	 //     force u_top.u_sram8_1kb.din0 = u_top.mem8_din_b | 32'h1;
+   	 //  -> error_insert;
+         //end else begin
+         //   release u_top.u_sram8_1kb.din0;
+         //end
+
+      end
+   end
+   begin
+      // Loop for BIST TimeOut
+      repeat (200000) @(posedge clock);
+   		// $display("+1000 cycles");
+      test_fail = 1;
+   end
+   join_any
+   disable fork; //disable pending fork activity
+
+   // Read Back the Failure Address and cross-check all the 8 MBIST
+   // Read Signature is comming is reverse order, MBIST4 => MBIST3 => MBIST2
+   for(j=`NO_SRAM; j > 0; j=j-1) begin
+      fail_addr1 = faultaddr[0]+j-1;
+      fail_addr2 = faultaddr[1]+j-1;
+      fail_addr3 = faultaddr[2]+j-1;
+      fail_addr4 = faultaddr[3]+j-1;
+
+      if(num_fault[j-1] == 1) begin
+          wb_user_core_read_check(`GLBL_BIST_SRDATA,read_data,{32'h0},32'hFFFF_FFFF);
+          wb_user_core_read_check(`GLBL_BIST_SRDATA,read_data,{7'h0,fail_addr1,16'h0},32'hFFFF_FFFF);
+      end else if(num_fault[j-1] == 2) begin
+          wb_user_core_read_check(`GLBL_BIST_SRDATA,read_data,{32'h0},32'hFFFF_FFFF);
+          wb_user_core_read_check(`GLBL_BIST_SRDATA,read_data,{7'h0,fail_addr1,7'h0,fail_addr2},32'hFFFF_FFFF);
+     end else if(num_fault[j-1] == 3) begin
+          wb_user_core_read_check(`GLBL_BIST_SRDATA,read_data,{7'h0,fail_addr3,16'h0},32'hFFFF_FFFF);
+          wb_user_core_read_check(`GLBL_BIST_SRDATA,read_data,{7'h0,fail_addr1,7'h0,fail_addr2},32'hFFFF_FFFF);
+      end else if(num_fault[j-1] >= 4) begin
+          wb_user_core_read_check(`GLBL_BIST_SRDATA,read_data,{7'h0,fail_addr3,7'h0,fail_addr4},32'hFFFF_FFFF);
+          wb_user_core_read_check(`GLBL_BIST_SRDATA,read_data,{7'h0,fail_addr1,7'h0,fail_addr2},32'hFFFF_FFFF);
+      end else begin
+          wb_user_core_read_check(`GLBL_BIST_SRDATA,read_data,32'h0,32'hFFFF_FFFF);
+          wb_user_core_read_check(`GLBL_BIST_SRDATA,read_data,32'h0,32'hFFFF_FFFF);
+      end
+   end
+end
+endtask
+
+
+task wb_user_core_write;
+input [31:0] address;
+input [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h1;  // write
+  wbd_ext_dat_i =data;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("STATUS: WB USER ACCESS WRITE Address : 0x%x, Data : 0x%x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read;
+input [31:0] address;
+output [31:0] data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  #1;
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  //$display("STATUS: WB USER ACCESS READ  Address : 0x%x, Data : 0x%x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read_check;
+input [31:0] address;
+output [31:0] data;
+input [31:0] cmp_data;
+input [31:0] cmp_mask;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  #1;
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  if((data & cmp_mask) !== (cmp_data & cmp_mask) ) begin
+     $display("ERROR : WB USER ACCESS READ  Address : 0x%x, Exd: 0x%x Rxd: 0x%x ",address,(cmp_data & cmp_mask),(data & cmp_mask));
+     test_fail = 1;
+  end else begin
+     $display("STATUS: WB USER ACCESS READ  Address : 0x%x, Data : 0x%x",address,(data & cmp_mask));
+  end
+  repeat (2) @(posedge clock);
+end
+endtask
+
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/user_risc_boot/Makefile b/verilog/dv/user_risc_boot/Makefile
new file mode 100644
index 0000000..1057c10
--- /dev/null
+++ b/verilog/dv/user_risc_boot/Makefile
@@ -0,0 +1,111 @@
+# 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_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_BEHAVIOURAL_AGENTS = ../agents
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/yifive/ycr1c/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include
+
+## YIFIVE FIRMWARE
+YIFIVE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/dv/firmware
+GCC64_PREFIX?=riscv64-unknown-elf
+
+## RISCV GCC 
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+DUMP?=OFF
+
+.SUFFIXES:
+
+PATTERN = user_risc_boot
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v
+	${GCC64_PREFIX}-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las  -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=0 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\"  -c -I./ -I$(YIFIVE_FIRMWARE_PATH)  user_risc_boot.c -o user_risc_boot.o
+	${GCC64_PREFIX}-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las  -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=0 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\"  -D__ASSEMBLY__=1 -c -I./ -I$(YIFIVE_FIRMWARE_PATH)  $(YIFIVE_FIRMWARE_PATH)/crt.S -o crt.o
+	${GCC64_PREFIX}-gcc -o user_risc_boot.elf -T $(YIFIVE_FIRMWARE_PATH)/link.ld user_risc_boot.o crt.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32 -N
+	${GCC64_PREFIX}-objcopy -O verilog user_risc_boot.elf user_risc_boot.hex
+	${GCC64_PREFIX}-objdump -D user_risc_boot.elf > user_risc_boot.dump
+	rm crt.o user_risc_boot.o
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+    else  
+	iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+   endif
+else  
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_GL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	$< -o $@ 
+endif
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c $(CARAVEL_FIRMWARE_PATH)/sections.lds $(CARAVEL_FIRMWARE_PATH)/start.s
+	${GCC64_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: 
+	echo @"This is user boot test, noting to compile the mangment core code"
+
+%.bin: %.elf
+	${GCC64_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log *.dump
+
+.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..f083d6d
--- /dev/null
+++ b/verilog/dv/user_risc_boot/run_iverilog
@@ -0,0 +1,42 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# // 
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# //      http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+
+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 -DFUNCTIONAL -DSIM -I $PDK_PATH -I  ../../../caravel/verilog/rtl  -I ../ -I ../../../verilog/rtl -I ../ -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_risc_boot_tb.v -o user_risc_boot_tb.vvp
+
+
+#iverilog -g2005-sv -I $PDK_PATH -DFUNCTIONAL -DSIM -I  ../../../caravel/verilog/rtl -I ../ -I ../../../verilog/rtl -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_risc_boot_tb.v -o user_risc_boot_tb.vvp
+
+# GLS
+#iverilog -g2005-sv -DGL -I $PDK_PATH -I  ../../../caravel/verilog/rtl  -I ../ -I ../../../verilog/rtl -I ../../../verilog -I /home/dinesha/workarea/pdk/sky130A -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_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/user_risc_boot.c b/verilog/dv/user_risc_boot/user_risc_boot.c
new file mode 100644
index 0000000..37e424b
--- /dev/null
+++ b/verilog/dv/user_risc_boot/user_risc_boot.c
@@ -0,0 +1,73 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+// //////////////////////////////////////////////////////////////////////////
+#define SC_SIM_OUTPORT (0xf0000000)
+#define uint32_t  long
+
+#define reg_mprj_globl_reg0  (*(volatile uint32_t*)0x10020000)
+#define reg_mprj_globl_reg1  (*(volatile uint32_t*)0x10020004)
+#define reg_mprj_globl_reg2  (*(volatile uint32_t*)0x10020008)
+#define reg_mprj_globl_reg3  (*(volatile uint32_t*)0x1002000C)
+#define reg_mprj_globl_reg4  (*(volatile uint32_t*)0x10020010)
+#define reg_mprj_globl_reg5  (*(volatile uint32_t*)0x10020014)
+#define reg_mprj_globl_reg6  (*(volatile uint32_t*)0x10020018)
+#define reg_mprj_globl_reg7  (*(volatile uint32_t*)0x1002001C)
+#define reg_mprj_globl_reg8  (*(volatile uint32_t*)0x10020020)
+#define reg_mprj_globl_reg9  (*(volatile uint32_t*)0x10020024)
+#define reg_mprj_globl_reg10 (*(volatile uint32_t*)0x10020028)
+#define reg_mprj_globl_reg11 (*(volatile uint32_t*)0x1002002C)
+#define reg_mprj_globl_reg12 (*(volatile uint32_t*)0x10020030)
+#define reg_mprj_globl_reg13 (*(volatile uint32_t*)0x10020034)
+#define reg_mprj_globl_reg14 (*(volatile uint32_t*)0x10020038)
+#define reg_mprj_globl_reg15 (*(volatile uint32_t*)0x1002003C)
+#define reg_mprj_globl_reg16 (*(volatile uint32_t*)0x10020040)
+#define reg_mprj_globl_reg17 (*(volatile uint32_t*)0x10020044)
+#define reg_mprj_globl_reg18 (*(volatile uint32_t*)0x10020048)
+#define reg_mprj_globl_reg19 (*(volatile uint32_t*)0x1002004C)
+#define reg_mprj_globl_reg20 (*(volatile uint32_t*)0x10020050)
+#define reg_mprj_globl_reg21 (*(volatile uint32_t*)0x10020054)
+#define reg_mprj_globl_reg22 (*(volatile uint32_t*)0x10020058)
+#define reg_mprj_globl_reg23 (*(volatile uint32_t*)0x1002005C)
+#define reg_mprj_globl_reg24 (*(volatile uint32_t*)0x10020060)
+#define reg_mprj_globl_reg25 (*(volatile uint32_t*)0x10020064)
+#define reg_mprj_globl_reg26 (*(volatile uint32_t*)0x10020068)
+#define reg_mprj_globl_reg27 (*(volatile uint32_t*)0x1002006C)
+
+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_reg22  = 0x11223344; 
+    reg_mprj_globl_reg23  = 0x22334455; 
+    reg_mprj_globl_reg24  = 0x33445566; 
+    reg_mprj_globl_reg25  = 0x44556677; 
+    reg_mprj_globl_reg26 = 0x55667788; 
+    reg_mprj_globl_reg27 = 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_tb.v b/verilog/dv/user_risc_boot/user_risc_boot_tb.v
new file mode 100644
index 0000000..fff2408
--- /dev/null
+++ b/verilog/dv/user_risc_boot/user_risc_boot_tb.v
@@ -0,0 +1,398 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  Standalone User validation Test bench                       ////
+////                                                              ////
+////  This file is part of the YIFive cores project               ////
+////  https://github.com/dineshannayya/yifive_r0.git              ////
+////  http://www.opencores.org/cores/yifive/                      ////
+////                                                              ////
+////  Description                                                 ////
+////   This is a standalone test bench to validate the            ////
+////   Digital core.                                              ////
+////   1. User Risc core is booted using  compiled code of        ////
+////      user_risc_boot.c                                        ////
+////   2. User Risc core uses Serial Flash and SDRAM to boot      ////
+////   3. After successful boot, Risc core will  write signature  ////
+////      in to  user register from 0x1003_0058 to 0x1003_006C    ////
+////   4. Through the External Wishbone Interface we read back    ////
+////       from 0x3003_0058 to 0x3003_006C                        ////
+////       and validate the user register to declared pass fail   ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      - Dinesh Annayya, dinesha@opencores.org                 ////
+////                                                              ////
+////  Revision :                                                  ////
+////    0.1 - 16th Feb 2021, Dinesh A                             ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+`default_nettype wire
+
+`timescale 1 ns / 1 ns
+
+`include "s25fl256s.sv"
+`include "uprj_netlists.v"
+`include "mt48lc8m8a2.v"
+
+module user_risc_boot_tb;
+	reg clock;
+	reg wb_rst_i;
+	reg power1, power2;
+	reg power3, power4;
+
+        reg        wbd_ext_cyc_i;  // strobe/request
+        reg        wbd_ext_stb_i;  // strobe/request
+        reg [31:0] wbd_ext_adr_i;  // address
+        reg        wbd_ext_we_i;  // write
+        reg [31:0] wbd_ext_dat_i;  // data output
+        reg [3:0]  wbd_ext_sel_i;  // byte enable
+
+        wire [31:0] wbd_ext_dat_o;  // data input
+        wire        wbd_ext_ack_o;  // acknowlegement
+        wire        wbd_ext_err_o;  // error
+
+	// 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(2, 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");
+
+		// Remove Wb Reset
+		wb_user_core_write('h3080_0000,'h1);
+
+	        repeat (2) @(posedge clock);
+		#1;
+		// Remove all the reset
+                wb_user_core_write('h3080_0000,'hF);
+
+
+		// 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'h30020058,read_data);
+		if(read_data != 32'h11223344) test_fail = 1;
+
+		wb_user_core_read(32'h3002005C,read_data);
+		if(read_data != 32'h22334455) test_fail = 1;
+
+		wb_user_core_read(32'h30020060,read_data);
+	        if(read_data != 32'h33445566) test_fail = 1;
+
+		wb_user_core_read(32'h30020064,read_data);
+                if(read_data!= 32'h44556677) test_fail = 1;
+
+		wb_user_core_read(32'h30020068,read_data);
+                if(read_data!= 32'h55667788) test_fail = 1;
+
+		wb_user_core_read(32'h3002006C,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
+		wb_rst_i <= 1'b1;
+		#100;
+		wb_rst_i <= 1'b0;	    	// Release reset
+	end
+wire USER_VDD1V8 = 1'b1;
+wire VSS = 1'b0;
+
+user_project_wrapper u_top(
+`ifdef USE_POWER_PINS
+    .vccd1(USER_VDD1V8),	// User area 1 1.8V supply
+    .vssd1(VSS),	// User area 1 digital ground
+`endif
+    .wb_clk_i        (clock),  // System clock
+    .user_clock2     (1'b1),  // Real-time clock
+    .wb_rst_i        (wb_rst_i),  // Regular Reset signal
+
+    .wbs_cyc_i   (wbd_ext_cyc_i),  // strobe/request
+    .wbs_stb_i   (wbd_ext_stb_i),  // strobe/request
+    .wbs_adr_i   (wbd_ext_adr_i),  // address
+    .wbs_we_i    (wbd_ext_we_i),  // write
+    .wbs_dat_i   (wbd_ext_dat_i),  // data output
+    .wbs_sel_i   (wbd_ext_sel_i),  // byte enable
+
+    .wbs_dat_o   (wbd_ext_dat_o),  // data input
+    .wbs_ack_o   (wbd_ext_ack_o),  // acknowlegement
+
+ 
+    // Logic Analyzer Signals
+    .la_data_in      ('1) ,
+    .la_data_out     (),
+    .la_oenb         ('0),
+ 
+
+    // IOs
+    .io_in          (io_in)  ,
+    .io_out         (io_out) ,
+    .io_oeb         (io_oeb) ,
+
+    .user_irq       () 
+
+);
+
+`ifndef GL // Drive Power for Hold Fix Buf
+    // All standard cell need power hook-up for functionality work
+    initial begin
+
+    end
+`endif    
+
+//------------------------------------------------------
+//  Integrate the Serial flash with qurd support to
+//  user core using the gpio pads
+//  ----------------------------------------------------
+
+   wire flash_clk = io_out[24];
+   wire flash_csb = io_out[28];
+   // Creating Pad Delay
+   wire #1 io_oeb_29 = io_oeb[29];
+   wire #1 io_oeb_30 = io_oeb[30];
+   wire #1 io_oeb_31 = io_oeb[31];
+   wire #1 io_oeb_32 = io_oeb[32];
+   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[29] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[30] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[31] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[32] : 1'bz;
+
+   assign io_in[29] = flash_io0;
+   assign io_in[30] = flash_io1;
+   assign io_in[31] = flash_io2;
+   assign io_in[32] = flash_io3;
+
+   // Quard flash
+     s25fl256s #(.mem_file_name("user_risc_boot.hex"),
+	         .otp_file_name("none"),
+                 .TimingModel("S25FL512SAGMFI010_F_30pF")) 
+		 u_spi_flash_256mb (
+           // Data Inputs/Outputs
+       .SI      (flash_io0),
+       .SO      (flash_io1),
+       // Controls
+       .SCK     (flash_clk),
+       .CSNeg   (flash_csb),
+       .WPNeg   (flash_io2),
+       .HOLDNeg (flash_io3),
+       .RSTNeg  (!wb_rst_i)
+
+       );
+
+
+
+
+task wb_user_core_write;
+input [31:0] address;
+input [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h1;  // write
+  wbd_ext_dat_i =data;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("DEBUG WB USER ACCESS WRITE Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read;
+input [31:0] address;
+output [31:0] data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("DEBUG WB USER ACCESS READ Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+`ifdef GL
+
+wire        wbd_spi_stb_i   = u_top.u_spi_master.wbd_stb_i;
+wire        wbd_spi_ack_o   = u_top.u_spi_master.wbd_ack_o;
+wire        wbd_spi_we_i    = u_top.u_spi_master.wbd_we_i;
+wire [31:0] wbd_spi_adr_i   = u_top.u_spi_master.wbd_adr_i;
+wire [31:0] wbd_spi_dat_i   = u_top.u_spi_master.wbd_dat_i;
+wire [31:0] wbd_spi_dat_o   = u_top.u_spi_master.wbd_dat_o;
+wire [3:0]  wbd_spi_sel_i   = u_top.u_spi_master.wbd_sel_i;
+
+wire        wbd_sdram_stb_i = u_top.u_sdram_ctrl.wb_stb_i;
+wire        wbd_sdram_ack_o = u_top.u_sdram_ctrl.wb_ack_o;
+wire        wbd_sdram_we_i  = u_top.u_sdram_ctrl.wb_we_i;
+wire [31:0] wbd_sdram_adr_i = u_top.u_sdram_ctrl.wb_addr_i;
+wire [31:0] wbd_sdram_dat_i = u_top.u_sdram_ctrl.wb_dat_i;
+wire [31:0] wbd_sdram_dat_o = u_top.u_sdram_ctrl.wb_dat_o;
+wire [3:0]  wbd_sdram_sel_i = u_top.u_sdram_ctrl.wb_sel_i;
+
+wire        wbd_uart_stb_i  = u_top.u_uart_i2c_usb.reg_cs;
+wire        wbd_uart_ack_o  = u_top.u_uart_i2c_usb.reg_ack;
+wire        wbd_uart_we_i   = u_top.u_uart_i2c_usb.reg_wr;
+wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_i2c_usb.reg_addr;
+wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_i2c_usb.reg_wdata;
+wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_i2c_usb.reg_rdata;
+wire        wbd_uart_sel_i  = u_top.u_uart_i2c_usb.reg_be;
+
+`endif
+
+/**
+`ifdef GL
+//-----------------------------------------------------------------------------
+// RISC IMEM amd DMEM Monitoring TASK
+//-----------------------------------------------------------------------------
+
+`define RISC_CORE  user_uart_tb.u_top.u_core.u_riscv_top
+
+always@(posedge `RISC_CORE.wb_clk) begin
+    if(`RISC_CORE.wbd_imem_ack_i)
+          $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x", `RISC_CORE.wbd_imem_adr_o,`RISC_CORE.wbd_imem_dat_i);
+    if(`RISC_CORE.wbd_dmem_ack_i && `RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_o);
+    if(`RISC_CORE.wbd_dmem_ack_i && !`RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_i);
+end
+
+`endif
+**/
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/user_risc_boot/user_uart.c b/verilog/dv/user_risc_boot/user_uart.c
new file mode 100644
index 0000000..04512bc
--- /dev/null
+++ b/verilog/dv/user_risc_boot/user_uart.c
@@ -0,0 +1,60 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+// //////////////////////////////////////////////////////////////////////////
+
+#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)
+
+#define reg_mprj_uart_reg0 (*(volatile uint32_t*)0x30010000)
+#define reg_mprj_uart_reg1 (*(volatile uint32_t*)0x30010004)
+#define reg_mprj_uart_reg2 (*(volatile uint32_t*)0x30010008)
+#define reg_mprj_uart_reg3 (*(volatile uint32_t*)0x3001000C)
+#define reg_mprj_uart_reg4 (*(volatile uint32_t*)0x30010010)
+#define reg_mprj_uart_reg5 (*(volatile uint32_t*)0x30010014)
+#define reg_mprj_uart_reg6 (*(volatile uint32_t*)0x30010018)
+#define reg_mprj_uart_reg7 (*(volatile uint32_t*)0x3001001C)
+#define reg_mprj_uart_reg8 (*(volatile uint32_t*)0x30010020)
+
+int main()
+{
+
+    while(1) {
+       // Check UART RX fifo has data, if available loop back the data
+       if(reg_mprj_uart_reg8 != 0) { 
+	   reg_mprj_uart_reg5 = reg_mprj_uart_reg6;
+       }
+    }
+
+    return 0;
+}
diff --git a/verilog/dv/user_risc_soft_boot/Makefile b/verilog/dv/user_risc_soft_boot/Makefile
new file mode 100644
index 0000000..12f65be
--- /dev/null
+++ b/verilog/dv/user_risc_soft_boot/Makefile
@@ -0,0 +1,111 @@
+# 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_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_BEHAVIOURAL_AGENTS = ../agents
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/yifive/ycr1c/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include
+
+## YIFIVE FIRMWARE
+YIFIVE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/dv/firmware
+GCC64_PREFIX?=riscv64-unknown-elf
+
+## RISCV GCC 
+GCC_PATH?=/ef/apps/bin
+GCC32_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+DUMP?=OFF
+
+.SUFFIXES:
+
+PATTERN = user_risc_soft_boot
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v
+	${GCC64_PREFIX}-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las  -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=0 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\"  -c -I./ -I$(YIFIVE_FIRMWARE_PATH)  user_risc_boot.c -o user_risc_boot.o
+	${GCC64_PREFIX}-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las  -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=0 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\"  -D__ASSEMBLY__=1 -c -I./ -I$(YIFIVE_FIRMWARE_PATH)  $(YIFIVE_FIRMWARE_PATH)/crt.S -o crt.o
+	${GCC64_PREFIX}-gcc -o user_risc_boot.elf -T $(YIFIVE_FIRMWARE_PATH)/link.ld user_risc_boot.o crt.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32 -N
+	${GCC64_PREFIX}-objcopy -O verilog user_risc_boot.elf user_risc_boot.hex
+	${GCC64_PREFIX}-objdump -D user_risc_boot.elf > user_risc_boot.dump
+	rm crt.o user_risc_boot.o
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+    else  
+	iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+   endif
+else  
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_GL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	$< -o $@ 
+endif
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c $(CARAVEL_FIRMWARE_PATH)/sections.lds $(CARAVEL_FIRMWARE_PATH)/start.s
+	${GCC64_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: 
+	echo @"This is user boot test, noting to compile the mangment core code"
+
+%.bin: %.elf
+	${GCC64_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log *.dump
+
+.PHONY: clean hex all
diff --git a/verilog/dv/user_risc_soft_boot/run_iverilog b/verilog/dv/user_risc_soft_boot/run_iverilog
new file mode 100755
index 0000000..56414f8
--- /dev/null
+++ b/verilog/dv/user_risc_soft_boot/run_iverilog
@@ -0,0 +1,49 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# // 
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# //      http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+
+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  -DFUNCTIONAL -DSIM -I $PDK_PATH \
+-I /home/dinesha/workarea/opencore/git/riscduino/caravel/verilog/dv/caravel -I /home/dinesha/workarea/opencore/git/riscduino/caravel/verilog/rtl \
+-I ../model    -I ../../../verilog/rtl -I ../../../verilog \
+-I ../agents    \
+-I ../../../verilog/rtl/syntacore/scr1/src/includes    -I ../../../verilog/rtl/sdram_ctrl/src/defs -I ../../../verilog/rtl/i2cm/src/includes \
+-I ../../../verilog/rtl/usb1_host/src/includes -I ../../../verilog/rtl/mbist/include \
+user_risc_soft_boot_tb.v -o user_risc_soft_boot.vvp 
+
+
+#iverilog -g2005-sv -I $PDK_PATH -DFUNCTIONAL -DSIM -I  ../../../caravel/verilog/rtl -I ../ -I ../../../verilog/rtl -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_risc_boot_tb.v -o user_risc_boot_tb.vvp
+
+# GLS
+#iverilog -g2005-sv -DGL -I $PDK_PATH -I  ../../../caravel/verilog/rtl  -I ../ -I ../../../verilog/rtl -I ../../../verilog -I /home/dinesha/workarea/pdk/sky130A -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_risc_boot_tb.vvp
+
+vvp user_risc_soft_boot.vvp | tee test.log
+
+\rm -rf user_risc_soft_boot.vvp
diff --git a/verilog/dv/user_risc_soft_boot/user_risc_boot.c b/verilog/dv/user_risc_soft_boot/user_risc_boot.c
new file mode 100644
index 0000000..37e424b
--- /dev/null
+++ b/verilog/dv/user_risc_soft_boot/user_risc_boot.c
@@ -0,0 +1,73 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+// //////////////////////////////////////////////////////////////////////////
+#define SC_SIM_OUTPORT (0xf0000000)
+#define uint32_t  long
+
+#define reg_mprj_globl_reg0  (*(volatile uint32_t*)0x10020000)
+#define reg_mprj_globl_reg1  (*(volatile uint32_t*)0x10020004)
+#define reg_mprj_globl_reg2  (*(volatile uint32_t*)0x10020008)
+#define reg_mprj_globl_reg3  (*(volatile uint32_t*)0x1002000C)
+#define reg_mprj_globl_reg4  (*(volatile uint32_t*)0x10020010)
+#define reg_mprj_globl_reg5  (*(volatile uint32_t*)0x10020014)
+#define reg_mprj_globl_reg6  (*(volatile uint32_t*)0x10020018)
+#define reg_mprj_globl_reg7  (*(volatile uint32_t*)0x1002001C)
+#define reg_mprj_globl_reg8  (*(volatile uint32_t*)0x10020020)
+#define reg_mprj_globl_reg9  (*(volatile uint32_t*)0x10020024)
+#define reg_mprj_globl_reg10 (*(volatile uint32_t*)0x10020028)
+#define reg_mprj_globl_reg11 (*(volatile uint32_t*)0x1002002C)
+#define reg_mprj_globl_reg12 (*(volatile uint32_t*)0x10020030)
+#define reg_mprj_globl_reg13 (*(volatile uint32_t*)0x10020034)
+#define reg_mprj_globl_reg14 (*(volatile uint32_t*)0x10020038)
+#define reg_mprj_globl_reg15 (*(volatile uint32_t*)0x1002003C)
+#define reg_mprj_globl_reg16 (*(volatile uint32_t*)0x10020040)
+#define reg_mprj_globl_reg17 (*(volatile uint32_t*)0x10020044)
+#define reg_mprj_globl_reg18 (*(volatile uint32_t*)0x10020048)
+#define reg_mprj_globl_reg19 (*(volatile uint32_t*)0x1002004C)
+#define reg_mprj_globl_reg20 (*(volatile uint32_t*)0x10020050)
+#define reg_mprj_globl_reg21 (*(volatile uint32_t*)0x10020054)
+#define reg_mprj_globl_reg22 (*(volatile uint32_t*)0x10020058)
+#define reg_mprj_globl_reg23 (*(volatile uint32_t*)0x1002005C)
+#define reg_mprj_globl_reg24 (*(volatile uint32_t*)0x10020060)
+#define reg_mprj_globl_reg25 (*(volatile uint32_t*)0x10020064)
+#define reg_mprj_globl_reg26 (*(volatile uint32_t*)0x10020068)
+#define reg_mprj_globl_reg27 (*(volatile uint32_t*)0x1002006C)
+
+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_reg22  = 0x11223344; 
+    reg_mprj_globl_reg23  = 0x22334455; 
+    reg_mprj_globl_reg24  = 0x33445566; 
+    reg_mprj_globl_reg25  = 0x44556677; 
+    reg_mprj_globl_reg26 = 0x55667788; 
+    reg_mprj_globl_reg27 = 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_soft_boot/user_risc_soft_boot_tb.v b/verilog/dv/user_risc_soft_boot/user_risc_soft_boot_tb.v
new file mode 100644
index 0000000..32a28b8
--- /dev/null
+++ b/verilog/dv/user_risc_soft_boot/user_risc_soft_boot_tb.v
@@ -0,0 +1,407 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  Standalone User validation Test bench                       ////
+////                                                              ////
+////  This file is part of the YIFive cores project               ////
+////  https://github.com/dineshannayya/yifive_r0.git              ////
+////  http://www.opencores.org/cores/yifive/                      ////
+////                                                              ////
+////  Description                                                 ////
+////   This is a standalone test bench to validate the            ////
+////   Digital core.                                              ////
+////   1. User Risc core is booted using  compiled code of        ////
+////      user_risc_boot.c                                        ////
+////   2. User Risc core uses Serial Flash and SDRAM to boot      ////
+////   3. After successful boot, Risc core will  write signature  ////
+////      in to  user register from 0x1003_0058 to 0x1003_006C    ////
+////   4. Through the External Wishbone Interface we read back    ////
+////       from 0x3003_0058 to 0x3003_006C                        ////
+////       and validate the user register to declared pass fail   ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      - Dinesh Annayya, dinesha@opencores.org                 ////
+////                                                              ////
+////  Revision :                                                  ////
+////    0.1 - 16th Feb 2021, Dinesh A                             ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+`default_nettype wire
+
+`timescale 1 ns / 1 ns
+
+`include "uprj_netlists.v"
+
+module user_risc_soft_boot_tb;
+	reg clock;
+	reg wb_rst_i;
+	reg power1, power2;
+	reg power3, power4;
+
+        reg        wbd_ext_cyc_i;  // strobe/request
+        reg        wbd_ext_stb_i;  // strobe/request
+        reg [31:0] wbd_ext_adr_i;  // address
+        reg        wbd_ext_we_i;  // write
+        reg [31:0] wbd_ext_dat_i;  // data output
+        reg [3:0]  wbd_ext_sel_i;  // byte enable
+
+        wire [31:0] wbd_ext_dat_o;  // data input
+        wire        wbd_ext_ack_o;  // acknowlegement
+        wire        wbd_ext_err_o;  // error
+
+	// 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;
+	logic  [7:0]           tem_mem[0:4095];
+	logic  [31:0]          tem_mem_32b[0:511];
+
+	`ifdef VERILATOR
+	 logic [255:0]          test_ram_file;
+         `else // VERILATOR
+	 
+	    string                 test_ram_file;
+
+         `endif // VERILATOR
+
+         integer i;
+
+
+	// 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("simx.vcd");
+	   	$dumpvars(4, user_risc_soft_boot_tb.u_top);
+	   	//$dumpvars(3, user_risc_soft_boot_tb.u_top.u_riscv_top);
+	   end
+       `endif
+
+	initial begin
+
+		#200; // Wait for reset removal
+	        repeat (10) @(posedge clock);
+		$display("Monitor: Standalone User Risc Boot Test Started");
+
+		// Remove Wb Reset
+		wb_user_core_write('h3080_0000,'h1);
+
+		$readmemh("user_risc_boot.hex",tem_mem);
+		// convert 8 bit 32 mem format
+		for(i =0; i < 511; i = i+1)
+		   tem_mem_32b[i] = {tem_mem[(i*4)+3],tem_mem[(i*4)+2],tem_mem[(i*4)+1],tem_mem[(i*4)]};
+
+	        $writememh("sram_bank0.hex",tem_mem_32b,0,511);
+	        $readmemh("sram_bank0.hex",u_top.u_sram0_2kb.mem,0,511);
+
+		for(i =512; i < 1023; i = i+1)
+		   tem_mem_32b[i-512] = {tem_mem[(i*4)+3],tem_mem[(i*4)+2],tem_mem[(i*4)+1],tem_mem[(i*4)]};
+
+	        $writememh("sram_bank1.hex",tem_mem_32b,0,511);
+	        $readmemh("sram_bank1.hex",u_top.u_sram1_2kb.mem,0,511);
+
+		// Enable the SRAM Remap to boot region
+		wb_user_core_write('h3080_000C,{4'b1111,28'h0});
+	        repeat (2) @(posedge clock);
+		#1;
+		// Remove the reset, mbist, wishbone, riscv
+                wb_user_core_write('h3080_0000,'h8F);
+
+
+		// Repeat cycles of 1000 clock edges as needed to complete testbench
+		repeat (24) begin
+			repeat (500) @(posedge clock);
+			//$display("+500 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_check(32'h30020058,read_data,32'h11223344);
+		wb_user_core_read_check(32'h3002005C,read_data,32'h22334455);
+		wb_user_core_read_check(32'h30020060,read_data,32'h33445566);
+		wb_user_core_read_check(32'h30020064,read_data,32'h44556677);
+		wb_user_core_read_check(32'h30020068,read_data,32'h55667788);
+		wb_user_core_read_check(32'h3002006C,read_data,32'h66778899) ;
+
+	   
+	    	$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
+		wb_rst_i <= 1'b1;
+		#100;
+		wb_rst_i <= 1'b0;	    	// Release reset
+	end
+wire USER_VDD1V8 = 1'b1;
+wire VSS = 1'b0;
+
+user_project_wrapper u_top(
+`ifdef USE_POWER_PINS
+    .vccd1(USER_VDD1V8),	// User area 1 1.8V supply
+    .vssd1(VSS),	// User area 1 digital ground
+`endif
+    .wb_clk_i        (clock),  // System clock
+    .user_clock2     (1'b1),  // Real-time clock
+    .wb_rst_i        (wb_rst_i),  // Regular Reset signal
+
+    .wbs_cyc_i   (wbd_ext_cyc_i),  // strobe/request
+    .wbs_stb_i   (wbd_ext_stb_i),  // strobe/request
+    .wbs_adr_i   (wbd_ext_adr_i),  // address
+    .wbs_we_i    (wbd_ext_we_i),  // write
+    .wbs_dat_i   (wbd_ext_dat_i),  // data output
+    .wbs_sel_i   (wbd_ext_sel_i),  // byte enable
+
+    .wbs_dat_o   (wbd_ext_dat_o),  // data input
+    .wbs_ack_o   (wbd_ext_ack_o),  // acknowlegement
+
+ 
+    // Logic Analyzer Signals
+    .la_data_in      ('1) ,
+    .la_data_out     (),
+    .la_oenb         ('0),
+ 
+
+    // IOs
+    .io_in          (io_in)  ,
+    .io_out         (io_out) ,
+    .io_oeb         (io_oeb) ,
+
+    .user_irq       () 
+
+);
+
+`ifndef GL // Drive Power for Hold Fix Buf
+    // All standard cell need power hook-up for functionality work
+    initial begin
+
+    end
+`endif    
+
+
+
+task wb_user_core_write;
+input [31:0] address;
+input [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h1;  // write
+  wbd_ext_dat_i =data;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("DEBUG WB USER ACCESS WRITE Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read;
+input [31:0] address;
+output [31:0] data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("DEBUG WB USER ACCESS READ Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read_check;
+input [31:0] address;
+output [31:0] data;
+input [31:0] cmp_data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  if(data !== cmp_data) begin
+     $display("ERROR : WB USER ACCESS READ  Address : 0x%x, Exd: 0x%x Rxd: 0x%x ",address,cmp_data,data);
+     test_fail = 1;
+  end else begin
+     $display("STATUS: WB USER ACCESS READ  Address : 0x%x, Data : 0x%x",address,data);
+  end
+  repeat (2) @(posedge clock);
+end
+endtask
+
+`ifdef GL
+
+wire        wbd_spi_stb_i   = u_top.u_spi_master.wbd_stb_i;
+wire        wbd_spi_ack_o   = u_top.u_spi_master.wbd_ack_o;
+wire        wbd_spi_we_i    = u_top.u_spi_master.wbd_we_i;
+wire [31:0] wbd_spi_adr_i   = u_top.u_spi_master.wbd_adr_i;
+wire [31:0] wbd_spi_dat_i   = u_top.u_spi_master.wbd_dat_i;
+wire [31:0] wbd_spi_dat_o   = u_top.u_spi_master.wbd_dat_o;
+wire [3:0]  wbd_spi_sel_i   = u_top.u_spi_master.wbd_sel_i;
+
+wire        wbd_sdram_stb_i = u_top.u_sdram_ctrl.wb_stb_i;
+wire        wbd_sdram_ack_o = u_top.u_sdram_ctrl.wb_ack_o;
+wire        wbd_sdram_we_i  = u_top.u_sdram_ctrl.wb_we_i;
+wire [31:0] wbd_sdram_adr_i = u_top.u_sdram_ctrl.wb_addr_i;
+wire [31:0] wbd_sdram_dat_i = u_top.u_sdram_ctrl.wb_dat_i;
+wire [31:0] wbd_sdram_dat_o = u_top.u_sdram_ctrl.wb_dat_o;
+wire [3:0]  wbd_sdram_sel_i = u_top.u_sdram_ctrl.wb_sel_i;
+
+wire        wbd_uart_stb_i  = u_top.u_uart_i2c_usb.reg_cs;
+wire        wbd_uart_ack_o  = u_top.u_uart_i2c_usb.reg_ack;
+wire        wbd_uart_we_i   = u_top.u_uart_i2c_usb.reg_wr;
+wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_i2c_usb.reg_addr;
+wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_i2c_usb.reg_wdata;
+wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_i2c_usb.reg_rdata;
+wire        wbd_uart_sel_i  = u_top.u_uart_i2c_usb.reg_be;
+
+`endif
+
+/**
+`ifdef GL
+//-----------------------------------------------------------------------------
+// RISC IMEM amd DMEM Monitoring TASK
+//-----------------------------------------------------------------------------
+
+`define RISC_CORE  user_uart_tb.u_top.u_core.u_riscv_top
+
+always@(posedge `RISC_CORE.wb_clk) begin
+    if(`RISC_CORE.wbd_imem_ack_i)
+          $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x", `RISC_CORE.wbd_imem_adr_o,`RISC_CORE.wbd_imem_dat_i);
+    if(`RISC_CORE.wbd_dmem_ack_i && `RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_o);
+    if(`RISC_CORE.wbd_dmem_ack_i && !`RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_i);
+end
+
+`endif
+**/
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/user_spi/Makefile b/verilog/dv/user_spi/Makefile
new file mode 100644
index 0000000..e0934e1
--- /dev/null
+++ b/verilog/dv/user_spi/Makefile
@@ -0,0 +1,99 @@
+# 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_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_BEHAVIOURAL_AGENTS = ../agents
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/yifive/ycr1c/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include
+
+## YIFIVE FIRMWARE
+YIFIVE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/dv/firmware
+GCC64_PREFIX?=riscv64-unknown-elf
+
+## RISCV GCC 
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+DUMP?=OFF
+
+.SUFFIXES:
+
+PATTERN = user_spi
+
+all:  ${PATTERN:=.vcd}
+
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+    else  
+	iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+   endif
+else  
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_GL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	$< -o $@ 
+endif
+
+%.vcd: %.vvp
+	vvp $<
+
+%.hex: 
+	echo @"This is user boot test, noting to compile the mangment core code"
+
+
+# ---- Clean ----
+
+clean:
+	rm -f *.vvp *.vcd *.log *.fst
+
+.PHONY: clean hex all
diff --git a/verilog/dv/user_spi/flash0.hex b/verilog/dv/user_spi/flash0.hex
new file mode 100755
index 0000000..24a2e47
--- /dev/null
+++ b/verilog/dv/user_spi/flash0.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 60 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 13 81 01 76 17 05 48 00 13 05

+65 DF 17 06 48 00 13 06 E6 DE B3 05 A6 40 13 87

+01 66 33 02 B7 40 92 85 17 06 48 00 13 06 86 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 A2 CC 97 02

+48 00 93 82 22 D2 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 DF 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 00 00 00 00 00 00 00 00

+@00000400

+37 37 22 11 B7 07 03 30 93 02 47 34 37 43 33 22

+23 AC 57 04 93 03 53 45 37 55 44 33 23 AE 77 04

+93 05 65 56 37 66 55 44 AC D3 93 06 76 67 37 78

+66 55 F4 D3 93 08 88 78 37 9E 77 66 23 A4 17 07

+93 0E 9E 89 23 A6 D7 07 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_spi/run_iverilog b/verilog/dv/user_spi/run_iverilog
new file mode 100755
index 0000000..fedabc3
--- /dev/null
+++ b/verilog/dv/user_spi/run_iverilog
@@ -0,0 +1,44 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# // 
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# //      http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+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 without Dump
+iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $PDK_PATH \
+-I ../../caravel/verilog/dv/caravel -I ../../caravel/verilog/rtl \
+-I ../model    -I ../../../verilog/rtl -I ../../../verilog \
+-I ../agents    \
+-I ../../../verilog/rtl/syntacore/scr1/src/includes    -I ../../../verilog/rtl/sdram_ctrl/src/defs -I ../../../verilog/rtl/i2cm/src/includes \
+-I ../../../verilog/rtl/usb1_host/src/includes \
+user_spi_tb.v -o user_spi.vvp 
+
+
+
+vvp user_spi_tb.vvp | tee test.log
+
+\rm -rf user_spi_tb.vvp
diff --git a/verilog/dv/user_spi/user_risc_boot.c b/verilog/dv/user_spi/user_risc_boot.c
new file mode 100644
index 0000000..0711b7b
--- /dev/null
+++ b/verilog/dv/user_spi/user_risc_boot.c
@@ -0,0 +1,69 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+// //////////////////////////////////////////////////////////////////////////
+#define SC_SIM_OUTPORT (0xf0000000)
+#define uint32_t  long
+
+#define reg_mprj_globl_reg0  (*(volatile uint32_t*)0x30030000)
+#define reg_mprj_globl_reg1  (*(volatile uint32_t*)0x30030004)
+#define reg_mprj_globl_reg2  (*(volatile uint32_t*)0x30030008)
+#define reg_mprj_globl_reg3  (*(volatile uint32_t*)0x3003000C)
+#define reg_mprj_globl_reg4  (*(volatile uint32_t*)0x30030010)
+#define reg_mprj_globl_reg5  (*(volatile uint32_t*)0x30030014)
+#define reg_mprj_globl_reg6  (*(volatile uint32_t*)0x30030018)
+#define reg_mprj_globl_reg7  (*(volatile uint32_t*)0x3003001C)
+#define reg_mprj_globl_reg8  (*(volatile uint32_t*)0x30030020)
+#define reg_mprj_globl_reg9  (*(volatile uint32_t*)0x30030024)
+#define reg_mprj_globl_reg10 (*(volatile uint32_t*)0x30030028)
+#define reg_mprj_globl_reg11 (*(volatile uint32_t*)0x3003002C)
+#define reg_mprj_globl_reg12 (*(volatile uint32_t*)0x30030030)
+#define reg_mprj_globl_reg13 (*(volatile uint32_t*)0x30030034)
+#define reg_mprj_globl_reg14 (*(volatile uint32_t*)0x30030038)
+#define reg_mprj_globl_reg15 (*(volatile uint32_t*)0x3003003C)
+#define reg_mprj_globl_reg16 (*(volatile uint32_t*)0x30030040)
+#define reg_mprj_globl_reg17 (*(volatile uint32_t*)0x30030044)
+#define reg_mprj_globl_reg18 (*(volatile uint32_t*)0x30030048)
+#define reg_mprj_globl_reg19 (*(volatile uint32_t*)0x3003004C)
+#define reg_mprj_globl_reg20 (*(volatile uint32_t*)0x30030050)
+#define reg_mprj_globl_reg21 (*(volatile uint32_t*)0x30030054)
+#define reg_mprj_globl_reg22 (*(volatile uint32_t*)0x30030058)
+#define reg_mprj_globl_reg23 (*(volatile uint32_t*)0x3003005C)
+#define reg_mprj_globl_reg24 (*(volatile uint32_t*)0x30030060)
+#define reg_mprj_globl_reg25 (*(volatile uint32_t*)0x30030064)
+#define reg_mprj_globl_reg26 (*(volatile uint32_t*)0x30030068)
+#define reg_mprj_globl_reg27 (*(volatile uint32_t*)0x3003006C)
+
+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_reg22  = 0x11223344; 
+    reg_mprj_globl_reg23  = 0x22334455; 
+    reg_mprj_globl_reg24  = 0x33445566; 
+    reg_mprj_globl_reg25  = 0x44556677; 
+    reg_mprj_globl_reg26 = 0x55667788; 
+    reg_mprj_globl_reg27 = 0x66778899; 
+
+    while(1) {}
+    return 0;
+}
diff --git a/verilog/dv/user_spi/user_spi_tb.v b/verilog/dv/user_spi/user_spi_tb.v
new file mode 100644
index 0000000..d16bfa8
--- /dev/null
+++ b/verilog/dv/user_spi/user_spi_tb.v
@@ -0,0 +1,1416 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  Standalone User validation Test bench                       ////
+////                                                              ////
+////  This file is part of the YIFive cores project               ////
+////  https://github.com/dineshannayya/yifive_r0.git              ////
+////  http://www.opencores.org/cores/yifive/                      ////
+////                                                              ////
+////  Description                                                 ////
+////   This is a standalone test bench to validate the            ////
+////   Digital core flash access through External WB i/F.         ////
+////   1.  Check SPI Read Identification                          ////
+////   2.  Check the Direct Memory Read (Qual/Single/Quad)        ////        
+////   3.  Direct SPI Memory Prefetch - 3DW                       ////
+////   4.  Direct SPI Memory Prefetch - 2DW                       ////
+////   5.  Direct SPI Memory Prefetch - 1DW                       ////
+////   6.  Direct SPI Memory Prefetch - 7DW                       ////
+////   7.  1DW  Indirect Read                                     ////
+////   8.  2DW  Indirect Read                                     ////
+////   9.  3DW  Indirect Read                                     ////
+////   10. 4DW  Indirect Read                                     ////
+////   11. 5DW  Indirect Read                                     ////
+////   12. 8DW  Indirect Read                                     ////
+////   13. Sector Erase command + Page Write & Read Back          ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      - Dinesh Annayya, dinesha@opencores.org                 ////
+////                                                              ////
+////  Revision :                                                  ////
+////    0.1 - 01 Oct 2021, Dinesh A                               ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+`default_nettype wire
+
+`timescale 1 ns / 1 ns
+
+`include "s25fl256s.sv"
+`include "uprj_netlists.v"
+`include "mt48lc8m8a2.v"
+`include "spiram.v"
+
+ // REGISTER MAP
+ `define QSPIM_GLBL_CTRL           32'h10000000
+ `define QSPIM_DMEM_G0_RD_CTRL    32'h10000004
+ `define QSPIM_DMEM_G0_WR_CTRL    32'h10000008
+ `define QSPIM_DMEM_G1_RD_CTRL    32'h1000000C
+ `define QSPIM_DMEM_G1_WR_CTRL    32'h10000010
+
+ `define QSPIM_DMEM_CS_AMAP        32'h10000014
+ `define QSPIM_DMEM_CA_AMASK       32'h10000018
+
+ `define QSPIM_IMEM_CTRL1          32'h1000001C
+ `define QSPIM_IMEM_CTRL2          32'h10000020
+ `define QSPIM_IMEM_ADDR           32'h10000024
+ `define QSPIM_IMEM_WDATA          32'h10000028
+ `define QSPIM_IMEM_RDATA          32'h1000002C
+ `define QSPIM_SPI_STATUS          32'h10000030
+
+module user_spi_tb;
+	reg clock;
+	reg wb_rst_i;
+	reg power1, power2;
+	reg power3, power4;
+
+        reg        wbd_ext_cyc_i;  // strobe/request
+        reg        wbd_ext_stb_i;  // strobe/request
+        reg [31:0] wbd_ext_adr_i;  // address
+        reg        wbd_ext_we_i;  // write
+        reg [31:0] wbd_ext_dat_i;  // data output
+        reg [3:0]  wbd_ext_sel_i;  // byte enable
+
+        wire [31:0] wbd_ext_dat_o;  // data input
+        wire        wbd_ext_ack_o;  // acknowlegement
+        wire        wbd_ext_err_o;  // error
+
+	// 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;
+
+/*************************************************************
+*  SPI FSM State Control
+*
+*   OPERATION   COMMAND                   SEQUENCE 
+*
+*    ERASE       P4E(0x20)           ->  COMMAND + ADDRESS
+*    ERASE       P8E(0x40)           ->  COMMAND + ADDRESS
+*    ERASE       SE(0xD8)            ->  COMMAND + ADDRESS
+*    ERASE       BE(0x60)            ->  COMMAND + ADDRESS
+*    ERASE       BE(0xC7)            ->  COMMAND 
+*    PROGRAM     PP(0x02)            ->  COMMAND + ADDRESS + Write DATA
+*    PROGRAM     QPP(0x32)           ->  COMMAND + ADDRESS + Write DATA
+*    READ        READ(0x3)           ->  COMMAND + ADDRESS + READ DATA
+*    READ        FAST_READ(0xB)      ->  COMMAND + ADDRESS + DUMMY + READ DATA
+*    READ        DOR (0x3B)          ->  COMMAND + ADDRESS + DUMMY + READ DATA
+*    READ        QOR (0x6B)          ->  COMMAND + ADDRESS + DUMMY + READ DATA
+*    READ        DIOR (0xBB)         ->  COMMAND + ADDRESS + MODE  + READ DATA
+*    READ        QIOR (0xEB)         ->  COMMAND + ADDRESS + MODE  + DUMMY + READ DATA
+*    READ        RDID (0x9F)         ->  COMMAND + READ DATA
+*    READ        READ_ID (0x90)      ->  COMMAND + ADDRESS + READ DATA
+*    WRITE       WREN(0x6)           ->  COMMAND
+*    WRITE       WRDI                ->  COMMAND
+*    STATUS      RDSR(0x05)          ->  COMMAND + READ DATA
+*    STATUS      RCR(0x35)           ->  COMMAND + READ DATA
+*    CONFIG      WRR(0x01)           ->  COMMAND + WRITE DATA
+*    CONFIG      CLSR(0x30)          ->  COMMAND
+*    Power Saving DP(0xB9)           ->  COMMAND
+*    Power Saving RES(0xAB)          ->  COMMAND + READ DATA
+*    OTP          OTPP(0x42)         ->  COMMAND + ADDR+ WRITE DATA
+*    OTP          OTPR(0x4B)         ->  COMMAND + ADDR + DUMMY + READ DATA
+*    ********************************************************************/
+parameter P_FSM_C      = 4'b0000; // Command Phase Only
+parameter P_FSM_CW     = 4'b0001; // Command + Write DATA Phase Only
+parameter P_FSM_CA     = 4'b0010; // Command -> Address Phase Only
+
+parameter P_FSM_CAR    = 4'b0011; // Command -> Address -> Read Data
+parameter P_FSM_CADR   = 4'b0100; // Command -> Address -> Dummy -> Read Data
+parameter P_FSM_CAMR   = 4'b0101; // Command -> Address -> Mode -> Read Data
+parameter P_FSM_CAMDR  = 4'b0110; // Command -> Address -> Mode -> Dummy -> Read Data
+
+parameter P_FSM_CAW    = 4'b0111; // Command -> Address ->Write Data
+parameter P_FSM_CADW   = 4'b1000; // Command -> Address -> DUMMY + Write Data
+parameter P_FSM_CAMW   = 4'b1001; // Command -> Address -> MODE + Write Data
+
+parameter P_FSM_CDR    = 4'b1010; // COMMAND -> DUMMY -> READ
+parameter P_FSM_CDW    = 4'b1011; // COMMAND -> DUMMY -> WRITE
+parameter P_FSM_CR     = 4'b1100;  // COMMAND -> READ
+
+parameter P_MODE_SWITCH_IDLE     = 2'b00;
+parameter P_MODE_SWITCH_AT_ADDR  = 2'b01;
+parameter P_MODE_SWITCH_AT_DATA  = 2'b10;
+
+parameter P_SINGLE = 2'b00;
+parameter P_DOUBLE = 2'b01;
+parameter P_QUAD   = 2'b10;
+parameter P_QDDR   = 2'b11;
+
+	// 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("simx.vcd");
+	   	$dumpvars(5, user_spi_tb);
+	   end
+       `endif
+
+	initial begin
+		$dumpon;
+
+		#200; // Wait for reset removal
+	        repeat (10) @(posedge clock);
+		$display("Monitor: Standalone User Risc Boot Test Started");
+
+		// Remove Wb Reset
+		wb_user_core_write('h3080_0000,'h1);
+
+	        repeat (2) @(posedge clock);
+		#1;
+		// Remove WB and SPI Reset, Keep SDARM and CORE under Reset
+                wb_user_core_write('h3080_0000,'h5);
+
+                wb_user_core_write('h3080_0004,'h0); // Change the Bank Sel 0
+
+
+		test_fail = 0;
+	        repeat (200) @(posedge clock);
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		// CS#2 SSPI Indirect RAM READ ACCESS-
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0100});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h4,2'b00,2'b10,P_FSM_CADR,8'h00,8'h03});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000000);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h03020100);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000004);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h07060504);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000008);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0b0a0908);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h0000000C);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0f0e0d0c);
+
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000200);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h11111111);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000204);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h22222222);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000208);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h33333333);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h0000020C);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h44444444);
+
+		// CS#2 SSPI Indiect Write DATA
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0100});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h10,2'b00,2'b10,P_FSM_CAW,8'h00,8'h02});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000000);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00112233);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h44556677);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h8899AABB);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'hCCDDEEFF);
+		
+		// CS#2 SSPI Indirect READ DATA
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0100});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h10,2'b00,2'b10,P_FSM_CADR,8'h00,8'h03});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000000);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00112233);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h44556677);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h8899AABB);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'hCCDDEEFF);
+
+
+		// CS#2 Switch to QSPI Mode
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0100});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h0,2'b00,2'b00,P_FSM_C,8'h00,8'h38});
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h0);
+
+
+		// CS#2 QUAD Indirect Write DATA
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_QUAD,P_QUAD,4'b0100});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h10,2'b00,2'b10,P_FSM_CAW,8'h00,8'h02});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000000);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h01234557);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h89ABCDEF);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h12345678);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h9ABCDEF0);
+
+
+		// CS#2 QUAD Indirect READ DATA
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_QUAD,P_QUAD,4'b0100});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h10,2'b00,2'b10,P_FSM_CADR,8'h00,8'h03});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000000);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h01234557);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h89ABCDEF);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h12345678);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h9ABCDEF0);
+
+		// CS#2 Switch From QSPI to SSPI Mode
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_QUAD,P_QUAD,4'b0100});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h0,2'b00,2'b00,P_FSM_C,8'h00,8'hFF});
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h0);
+		///////////////////// End of CS#1 Indirect Memory Access Testing ///////////////////////////////////
+
+		$display("#############################################");
+		$display("  Read Identification (RDID:0x9F)            ");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,2'b00,P_SINGLE,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h4,2'b00,2'b00,P_FSM_CR,8'h00,8'h9F});
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00190201);
+		$display("#############################################");
+		$display("Testing Direct SPI Memory Read              ");
+		$display(" SPI Mode: QDDR (Dual 4 bit)                ");
+		$display("Prefetch : 1DW, OPCODE:READ(0xED)           ");
+		$display("SEQ: Command -> Address -> Read Data        ");
+		$display("#############################################");
+		// QDDR Config
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_DMEM_G0_RD_CTRL,{P_FSM_CAMDR,4'b0100,2'b10,P_MODE_SWITCH_AT_ADDR,P_QDDR,P_SINGLE,8'h00,8'hED});
+                wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+		wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+		wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+		wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+		wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+		wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+		wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+		wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+		wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+		wb_user_core_read_check(32'h00000300,read_data,32'h0005A023);
+		wb_user_core_read_check(32'h00000304,read_data,32'h9DE30591);
+		wb_user_core_read_check(32'h00000308,read_data,32'h02B7FEE5);
+		wb_user_core_read_check(32'h0000030C,read_data,32'h43050049);
+		wb_user_core_read_check(32'h00000310,read_data,32'h0062A023);
+		wb_user_core_read_check(32'h00000314,read_data,32'h004902B7);
+		wb_user_core_read_check(32'h00000318,read_data,32'h03130291);
+		wb_user_core_read_check(32'h0000031C,read_data,32'ha0230630);
+		$dumpoff;
+		$display("#############################################");
+		$display("Testing Direct SPI Memory Read              ");
+		$display(" SPI Mode: Normal/Single Bit                ");
+		$display("Prefetch : 1DW, OPCODE:READ(0x3)            ");
+		$display("SEQ: Command -> Address -> Read Data        ");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_DMEM_G0_RD_CTRL,{P_FSM_CAR,4'b0000,2'b10,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,8'h00,8'h03});
+                wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+		wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+		wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+		wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+		wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+		wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+		wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+		wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+		wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+		wb_user_core_read_check(32'h00000300,read_data,32'h0005A023);
+		wb_user_core_read_check(32'h00000304,read_data,32'h9DE30591);
+		wb_user_core_read_check(32'h00000308,read_data,32'h02B7FEE5);
+		wb_user_core_read_check(32'h0000030C,read_data,32'h43050049);
+		wb_user_core_read_check(32'h00000310,read_data,32'h0062A023);
+		wb_user_core_read_check(32'h00000314,read_data,32'h004902B7);
+		wb_user_core_read_check(32'h00000318,read_data,32'h03130291);
+		wb_user_core_read_check(32'h0000031C,read_data,32'ha0230630);
+		$display("#############################################");
+		$display("Testing Direct SPI Memory Read              ");
+		$display(" SPI Mode: Normal/Single Bit                ");
+		$display("Prefetch : 1DW, OPCODE:FASTREAD(0xB)        ");
+		$display("SEQ: Command -> Address -> Dummy -> Read Data");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_DMEM_G0_RD_CTRL,{P_FSM_CADR,4'b0000,2'b10,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,8'h00,8'h0B});
+                wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+		wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+		wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+		wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+		wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+		wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+		wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+		wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+		wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+		wb_user_core_read_check(32'h00000300,read_data,32'h0005A023);
+		wb_user_core_read_check(32'h00000304,read_data,32'h9DE30591);
+		wb_user_core_read_check(32'h00000308,read_data,32'h02B7FEE5);
+		wb_user_core_read_check(32'h0000030C,read_data,32'h43050049);
+		wb_user_core_read_check(32'h00000310,read_data,32'h0062A023);
+		wb_user_core_read_check(32'h00000314,read_data,32'h004902B7);
+		wb_user_core_read_check(32'h00000318,read_data,32'h03130291);
+		wb_user_core_read_check(32'h0000031C,read_data,32'ha0230630);
+
+		$display("#############################################");
+		$display("Testing Direct SPI Memory Read              ");
+		$display(" SPI Mode: Dual Mode                        ");
+		$display("Prefetch : 1DW, OPCODE:DOR(0x3B)        ");
+		$display("SEQ: Command -> Address -> Dummy -> Read Data");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_DMEM_G0_RD_CTRL,{P_FSM_CADR,4'b0000,2'b10,P_MODE_SWITCH_AT_DATA,P_DOUBLE,P_SINGLE,8'h00,8'h3B});
+                wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+		wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+		wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+		wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+		wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+		wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+		wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+		wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+		wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+		wb_user_core_read_check(32'h00000300,read_data,32'h0005A023);
+		wb_user_core_read_check(32'h00000304,read_data,32'h9DE30591);
+		wb_user_core_read_check(32'h00000308,read_data,32'h02B7FEE5);
+		wb_user_core_read_check(32'h0000030C,read_data,32'h43050049);
+		wb_user_core_read_check(32'h00000310,read_data,32'h0062A023);
+		wb_user_core_read_check(32'h00000314,read_data,32'h004902B7);
+		wb_user_core_read_check(32'h00000318,read_data,32'h03130291);
+		wb_user_core_read_check(32'h0000031C,read_data,32'ha0230630);
+
+		$display("#############################################");
+		$display("Testing Direct SPI Memory Read with Prefetch");
+		$display(" SPI Mode: Quad                             ");
+		$display("Prefetch : 8DW, OPCODE:URAD READ(0xEB)      ");
+		$display("SEQ: Command -> Address -> Dummy -> Read Data");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_DMEM_G0_RD_CTRL,{P_FSM_CAMDR,4'b0001,2'b10,P_MODE_SWITCH_AT_ADDR,P_QUAD,P_SINGLE,8'h00,8'hEB});
+                wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+		wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+		wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+		wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+		wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+		wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+		wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+		wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+		wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+		wb_user_core_read_check(32'h00000300,read_data,32'h0005A023);
+		wb_user_core_read_check(32'h00000304,read_data,32'h9DE30591);
+		wb_user_core_read_check(32'h00000308,read_data,32'h02B7FEE5);
+		wb_user_core_read_check(32'h0000030C,read_data,32'h43050049);
+		wb_user_core_read_check(32'h00000310,read_data,32'h0062A023);
+		wb_user_core_read_check(32'h00000314,read_data,32'h004902B7);
+		wb_user_core_read_check(32'h00000318,read_data,32'h03130291);
+		wb_user_core_read_check(32'h0000031C,read_data,32'ha0230630);
+
+		$display("#############################################");
+		$display("Testing Direct SPI Memory Read with Prefetch:3DW");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_DMEM_G0_RD_CTRL,{P_FSM_CAMDR,4'b0001,2'b10,P_MODE_SWITCH_AT_ADDR,P_QUAD,P_SINGLE,8'h00,8'hEB});
+                wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+		wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+		wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+		wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+		wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+		wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+		wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+		wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+		wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+		wb_user_core_read_check(32'h00000300,read_data,32'h0005A023);
+		wb_user_core_read_check(32'h00000304,read_data,32'h9DE30591);
+		wb_user_core_read_check(32'h00000308,read_data,32'h02B7FEE5);
+		wb_user_core_read_check(32'h0000030C,read_data,32'h43050049);
+		wb_user_core_read_check(32'h00000310,read_data,32'h0062A023);
+		wb_user_core_read_check(32'h00000314,read_data,32'h004902B7);
+		wb_user_core_read_check(32'h00000318,read_data,32'h03130291);
+		wb_user_core_read_check(32'h0000031C,read_data,32'ha0230630);
+
+		$display("#############################################");
+		$display("Testing Direct SPI Memory Read with Prefetch:2DW");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_DMEM_G0_RD_CTRL,{P_FSM_CAMDR,4'b0001,2'b10,P_MODE_SWITCH_AT_ADDR,P_QUAD,P_SINGLE,8'h00,8'hEB});
+                wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+		wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+		wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+		wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+		wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+		wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+		wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+		wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+		wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+		wb_user_core_read_check(32'h00000300,read_data,32'h0005A023);
+		wb_user_core_read_check(32'h00000304,read_data,32'h9DE30591);
+		wb_user_core_read_check(32'h00000308,read_data,32'h02B7FEE5);
+		wb_user_core_read_check(32'h0000030C,read_data,32'h43050049);
+		wb_user_core_read_check(32'h00000310,read_data,32'h0062A023);
+		wb_user_core_read_check(32'h00000314,read_data,32'h004902B7);
+		wb_user_core_read_check(32'h00000318,read_data,32'h03130291);
+		wb_user_core_read_check(32'h0000031C,read_data,32'ha0230630);
+
+
+		$display("#############################################");
+		$display("Testing Direct SPI Memory Read with Prefetch:1DW");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_DMEM_G0_RD_CTRL,{P_FSM_CAMDR,4'b0001,2'b10,P_MODE_SWITCH_AT_ADDR,P_QUAD,P_SINGLE,8'h00,8'hEB});
+                wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+		wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+		wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+		wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+		wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+		wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+		wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+		wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+		wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+		wb_user_core_read_check(32'h00000300,read_data,32'h0005A023);
+		wb_user_core_read_check(32'h00000304,read_data,32'h9DE30591);
+		wb_user_core_read_check(32'h00000308,read_data,32'h02B7FEE5);
+		wb_user_core_read_check(32'h0000030C,read_data,32'h43050049);
+		wb_user_core_read_check(32'h00000310,read_data,32'h0062A023);
+		wb_user_core_read_check(32'h00000314,read_data,32'h004902B7);
+		wb_user_core_read_check(32'h00000318,read_data,32'h03130291);
+		wb_user_core_read_check(32'h0000031C,read_data,32'ha0230630);
+
+		$display("#############################################");
+		$display("Testing Direct SPI Memory Read with Prefetch:7DW");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_DMEM_G0_RD_CTRL,{P_FSM_CAMDR,4'b0001,2'b10,P_MODE_SWITCH_AT_ADDR,P_QUAD,P_SINGLE,8'h00,8'hEB});
+                wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+		wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+		wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+		wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+		wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+		wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+		wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+		wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+		wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+		wb_user_core_read_check(32'h00000300,read_data,32'h0005A023);
+		wb_user_core_read_check(32'h00000304,read_data,32'h9DE30591);
+		wb_user_core_read_check(32'h00000308,read_data,32'h02B7FEE5);
+		wb_user_core_read_check(32'h0000030C,read_data,32'h43050049);
+		wb_user_core_read_check(32'h00000310,read_data,32'h0062A023);
+		wb_user_core_read_check(32'h00000314,read_data,32'h004902B7);
+		wb_user_core_read_check(32'h00000318,read_data,32'h03130291);
+		wb_user_core_read_check(32'h0000031C,read_data,32'ha0230630);
+
+		$display("#############################################");
+		$display("  Testing Single Word Indirect SPI Memory Read");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0001,P_MODE_SWITCH_AT_ADDR,P_QUAD,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h4,2'b00,2'b10,P_FSM_CAMDR,8'h00,8'hEB});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000200);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000093);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000204);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000113);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000208);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000193);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h0000020C);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000213);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000210);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000293);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000214);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000313);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000218);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000393);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h0000021C);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000413);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000300);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0005A023);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000304);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h9DE30591);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000308);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h02B7FEE5);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h0000030C);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h43050049);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000310);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0062A023);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000314);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h004902B7);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000318);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h03130291);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h0000031C);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'ha0230630);
+		repeat (100) @(posedge clock);
+		$display("#############################################");
+		$display("  Testing Two Word Indirect SPI Memory Read");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0001,P_MODE_SWITCH_AT_ADDR,P_QUAD,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h8,2'b00,2'b10,P_FSM_CAMDR,8'h00,8'hEB});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000200);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000093);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000113);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000208);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000193);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000213);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000210);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000293);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000313);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000218);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000393);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000413);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000300);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0005A023);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h9DE30591);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000308);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h02B7FEE5);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h43050049);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000310);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0062A023);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h004902B7);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000318);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h03130291);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'ha0230630);
+		repeat (100) @(posedge clock);
+		$display("#############################################");
+		$display("  Testing Three Word Indirect SPI Memory Read");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0001,P_MODE_SWITCH_AT_ADDR,P_QUAD,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'hC,2'b00,2'b10,P_FSM_CAMDR,8'h00,8'hEB});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000200);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000093);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000113);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000193);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h0000020C);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000213);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000293);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000313);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000300);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0005A023);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h9DE30591);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h02B7FEE5);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h0000030C);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h43050049);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0062A023);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h004902B7);
+		repeat (100) @(posedge clock);
+		$display("#############################################");
+		$display("  Testing Four Word Indirect SPI Memory Read");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0001,P_MODE_SWITCH_AT_ADDR,P_QUAD,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h10,2'b00,2'b10,P_FSM_CAMDR,8'h00,8'hEB});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000200);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000093);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000113);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000193);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000213);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000210);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000293);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000313);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000393);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000413);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000300);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0005A023);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h9DE30591);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h02B7FEE5);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h43050049);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000310);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0062A023);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h004902B7);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h03130291);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'ha0230630);
+		repeat (100) @(posedge clock);
+		$display("#############################################");
+		$display("  Testing Five Word Indirect SPI Memory Read");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0001,P_MODE_SWITCH_AT_ADDR,P_QUAD,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h14,2'b00,2'b10,P_FSM_CAMDR,8'h00,8'hEB});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000200);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000093);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000113);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000193);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000213);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000293);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000300);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0005A023);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h9DE30591);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h02B7FEE5);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h43050049);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0062A023);
+		$display("#############################################");
+		$display("  Testing Eight Word Indirect SPI Memory Read");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0001,P_MODE_SWITCH_AT_ADDR,P_QUAD,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h20,2'b00,2'b10,P_FSM_CAMDR,8'h00,8'hEB});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000200);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000093);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000113);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000193);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000213);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000293);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000313);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000393);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00000413);
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000300);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0005A023);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h9DE30591);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h02B7FEE5);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h43050049);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h0062A023);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h004902B7);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h03130291);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'ha0230630);
+
+		$display("#############################################");
+		$display("  Sector Erase Command            ");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		// WEN COMMAND
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h0,2'b00,2'b00,P_FSM_C,8'h00,8'h06});
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h0);
+                // Sector Erase
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h0,2'b00,2'b10,P_FSM_CA,8'h00,8'hD8});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000000);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h0);
+
+		// RDSR
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h4,2'b00,2'b00,P_FSM_CR,8'h00,8'h05});
+		read_data = 32'hFFFF_FFFF;
+		while (read_data[1:0] == 2'b11) begin
+		    wb_user_core_read(`QSPIM_IMEM_RDATA,read_data);
+		    repeat (10) @(posedge clock);
+		end
+
+		$display("#############################################");
+		$display("  Page Write Command Address: 0x00          ");
+		$display("#############################################");
+		// WEN COMMAND
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h0,2'b00,2'b00,P_FSM_C,8'h00,8'h06});
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h0);
+		 // Page Programing
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'hF0,2'b00,2'b10,P_FSM_CAW,8'h00,8'h02});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000000);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010000);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010001);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010002);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010003);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010004);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010005);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010006);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010007);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010008);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010009);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010010);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010011);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010012);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010013);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010014);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010015);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010016);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010017);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010018);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010019);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010020);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010021);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010022);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010023);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010024);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010025);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010026);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010027);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010028);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010029);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010030);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010031);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010032);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010033);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010034);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010035);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010036);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010037);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010038);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010039);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010040);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010041);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010042);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010043);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010044);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010045);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010046);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010047);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010048);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010049);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010050);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010051);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010052);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010053);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010054);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010055);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010056);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010057);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010058);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00010059);
+
+		// RDSR
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h4,2'b00,2'b00,P_FSM_CR,8'h00,8'h05});
+		read_data = 32'hFFFF_FFFF;
+		while (read_data[1:0] == 2'b11) begin
+		    wb_user_core_read(`QSPIM_IMEM_RDATA,read_data);
+		    repeat (10) @(posedge clock);
+		 end
+
+		$display("#############################################");
+		$display("  Page Read through Direct Access            ");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+		wb_user_core_read_check(32'h00000000,read_data,32'h00010000);
+		wb_user_core_read_check(32'h00000004,read_data,32'h00010001);
+		wb_user_core_read_check(32'h00000008,read_data,32'h00010002);
+		wb_user_core_read_check(32'h0000000C,read_data,32'h00010003);
+		wb_user_core_read_check(32'h00000010,read_data,32'h00010004);
+		wb_user_core_read_check(32'h00000014,read_data,32'h00010005);
+		wb_user_core_read_check(32'h00000018,read_data,32'h00010006);
+		wb_user_core_read_check(32'h0000001C,read_data,32'h00010007);
+		wb_user_core_read_check(32'h00000020,read_data,32'h00010008);
+		wb_user_core_read_check(32'h00000024,read_data,32'h00010009);
+		wb_user_core_read_check(32'h00000028,read_data,32'h00010010);
+		wb_user_core_read_check(32'h0000002C,read_data,32'h00010011);
+		wb_user_core_read_check(32'h00000030,read_data,32'h00010012);
+		wb_user_core_read_check(32'h00000034,read_data,32'h00010013);
+		wb_user_core_read_check(32'h00000038,read_data,32'h00010014);
+		wb_user_core_read_check(32'h0000003C,read_data,32'h00010015);
+		wb_user_core_read_check(32'h00000040,read_data,32'h00010016);
+		wb_user_core_read_check(32'h00000044,read_data,32'h00010017);
+		wb_user_core_read_check(32'h00000048,read_data,32'h00010018);
+		wb_user_core_read_check(32'h0000004C,read_data,32'h00010019);
+		wb_user_core_read_check(32'h00000050,read_data,32'h00010020);
+		wb_user_core_read_check(32'h00000054,read_data,32'h00010021);
+		wb_user_core_read_check(32'h00000058,read_data,32'h00010022);
+		wb_user_core_read_check(32'h0000005C,read_data,32'h00010023);
+		wb_user_core_read_check(32'h00000060,read_data,32'h00010024);
+		wb_user_core_read_check(32'h00000064,read_data,32'h00010025);
+		wb_user_core_read_check(32'h00000068,read_data,32'h00010026);
+		wb_user_core_read_check(32'h0000006C,read_data,32'h00010027);
+		wb_user_core_read_check(32'h00000070,read_data,32'h00010028);
+		wb_user_core_read_check(32'h00000074,read_data,32'h00010029);
+		wb_user_core_read_check(32'h00000078,read_data,32'h00010030);
+		wb_user_core_read_check(32'h0000007C,read_data,32'h00010031);
+		wb_user_core_read_check(32'h00000080,read_data,32'h00010032);
+		wb_user_core_read_check(32'h00000084,read_data,32'h00010033);
+		wb_user_core_read_check(32'h00000088,read_data,32'h00010034);
+		wb_user_core_read_check(32'h0000008C,read_data,32'h00010035);
+		wb_user_core_read_check(32'h00000090,read_data,32'h00010036);
+		wb_user_core_read_check(32'h00000094,read_data,32'h00010037);
+		wb_user_core_read_check(32'h00000098,read_data,32'h00010038);
+		wb_user_core_read_check(32'h0000009C,read_data,32'h00010039);
+		wb_user_core_read_check(32'h000000A0,read_data,32'h00010040);
+		wb_user_core_read_check(32'h000000A4,read_data,32'h00010041);
+		wb_user_core_read_check(32'h000000A8,read_data,32'h00010042);
+		wb_user_core_read_check(32'h000000AC,read_data,32'h00010043);
+		wb_user_core_read_check(32'h000000B0,read_data,32'h00010044);
+		wb_user_core_read_check(32'h000000B4,read_data,32'h00010045);
+		wb_user_core_read_check(32'h000000B8,read_data,32'h00010046);
+		wb_user_core_read_check(32'h000000BC,read_data,32'h00010047);
+		wb_user_core_read_check(32'h000000C0,read_data,32'h00010048);
+		wb_user_core_read_check(32'h000000C4,read_data,32'h00010049);
+		wb_user_core_read_check(32'h000000C8,read_data,32'h00010050);
+		wb_user_core_read_check(32'h000000CC,read_data,32'h00010051);
+		wb_user_core_read_check(32'h000000D0,read_data,32'h00010052);
+		wb_user_core_read_check(32'h000000D4,read_data,32'h00010053);
+		wb_user_core_read_check(32'h000000D8,read_data,32'h00010054);
+		wb_user_core_read_check(32'h000000DC,read_data,32'h00010055);
+		wb_user_core_read_check(32'h000000E0,read_data,32'h00010056);
+		wb_user_core_read_check(32'h000000E4,read_data,32'h00010057);
+		wb_user_core_read_check(32'h000000E8,read_data,32'h00010058);
+		wb_user_core_read_check(32'h000000EC,read_data,32'h00010059);
+
+		repeat (100) @(posedge clock);
+		$display("#############################################");
+		$display("  Page Read through Indirect Access           ");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0001,P_MODE_SWITCH_AT_ADDR,P_QUAD,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'hF0,2'b00,2'b10,P_FSM_CAMDR,8'h00,8'hEB});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000000);
+
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010000);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010001);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010002);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010003);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010004);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010005);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010006);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010007);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010008);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010009);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010010);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010011);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010012);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010013);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010014);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010015);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010016);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010017);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010018);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010019);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010020);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010021);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010022);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010023);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010024);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010025);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010026);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010027);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010028);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010029);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010030);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010031);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010032);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010033);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010034);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010035);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010036);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010037);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010038);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010039);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010040);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010041);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010042);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010043);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010044);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010045);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010046);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010047);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010048);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010049);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010050);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010051);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010052);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010053);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010054);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010055);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010056);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010057);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010058);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00010059);
+
+		repeat (100) @(posedge clock);
+		$display("#############################################");
+		$display("  Page Write Command Address: 0x200          ");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		// WEN COMMAND
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h0,2'b00,2'b00,P_FSM_C,8'h00,8'h06});
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h0);
+		 // Page Programing
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'hF0,2'b00,2'b10,P_FSM_CAW,8'h00,8'h02});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000200);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020000);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020001);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020002);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020003);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020004);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020005);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020006);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020007);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020008);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020009);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020010);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020011);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020012);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020013);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020014);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020015);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020016);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020017);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020018);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020019);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020020);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020021);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020022);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020023);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020024);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020025);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020026);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020027);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020028);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020029);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020030);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020031);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020032);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020033);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020034);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020035);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020036);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020037);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020038);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020039);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020040);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020041);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020042);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020043);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020044);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020045);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020046);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020047);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020048);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020049);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020050);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020051);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020052);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020053);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020054);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020055);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020056);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020057);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020058);
+		wb_user_core_write(`QSPIM_IMEM_WDATA,32'h00020059);
+
+		// RDSR
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0000,P_MODE_SWITCH_IDLE,P_SINGLE,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'h4,2'b00,2'b00,P_FSM_CR,8'h00,8'h05});
+		read_data = 32'hFFFF_FFFF;
+		while (read_data[1:0] == 2'b11) begin
+		    wb_user_core_read(`QSPIM_IMEM_RDATA,read_data);
+		    repeat (10) @(posedge clock);
+		 end
+
+		$display("#############################################");
+		$display("  Page Read through Direct Access            ");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+		wb_user_core_read_check(32'h00000200,read_data,32'h00020000);
+		wb_user_core_read_check(32'h00000204,read_data,32'h00020001);
+		wb_user_core_read_check(32'h00000208,read_data,32'h00020002);
+		wb_user_core_read_check(32'h0000020C,read_data,32'h00020003);
+		wb_user_core_read_check(32'h00000210,read_data,32'h00020004);
+		wb_user_core_read_check(32'h00000214,read_data,32'h00020005);
+		wb_user_core_read_check(32'h00000218,read_data,32'h00020006);
+		wb_user_core_read_check(32'h0000021C,read_data,32'h00020007);
+		wb_user_core_read_check(32'h00000220,read_data,32'h00020008);
+		wb_user_core_read_check(32'h00000224,read_data,32'h00020009);
+		wb_user_core_read_check(32'h00000228,read_data,32'h00020010);
+		wb_user_core_read_check(32'h0000022C,read_data,32'h00020011);
+		wb_user_core_read_check(32'h00000230,read_data,32'h00020012);
+		wb_user_core_read_check(32'h00000234,read_data,32'h00020013);
+		wb_user_core_read_check(32'h00000238,read_data,32'h00020014);
+		wb_user_core_read_check(32'h0000023C,read_data,32'h00020015);
+		wb_user_core_read_check(32'h00000240,read_data,32'h00020016);
+		wb_user_core_read_check(32'h00000244,read_data,32'h00020017);
+		wb_user_core_read_check(32'h00000248,read_data,32'h00020018);
+		wb_user_core_read_check(32'h0000024C,read_data,32'h00020019);
+		wb_user_core_read_check(32'h00000250,read_data,32'h00020020);
+		wb_user_core_read_check(32'h00000254,read_data,32'h00020021);
+		wb_user_core_read_check(32'h00000258,read_data,32'h00020022);
+		wb_user_core_read_check(32'h0000025C,read_data,32'h00020023);
+		wb_user_core_read_check(32'h00000260,read_data,32'h00020024);
+		wb_user_core_read_check(32'h00000264,read_data,32'h00020025);
+		wb_user_core_read_check(32'h00000268,read_data,32'h00020026);
+		wb_user_core_read_check(32'h0000026C,read_data,32'h00020027);
+		wb_user_core_read_check(32'h00000270,read_data,32'h00020028);
+		wb_user_core_read_check(32'h00000274,read_data,32'h00020029);
+		wb_user_core_read_check(32'h00000278,read_data,32'h00020030);
+		wb_user_core_read_check(32'h0000027C,read_data,32'h00020031);
+		wb_user_core_read_check(32'h00000280,read_data,32'h00020032);
+		wb_user_core_read_check(32'h00000284,read_data,32'h00020033);
+		wb_user_core_read_check(32'h00000288,read_data,32'h00020034);
+		wb_user_core_read_check(32'h0000028C,read_data,32'h00020035);
+		wb_user_core_read_check(32'h00000290,read_data,32'h00020036);
+		wb_user_core_read_check(32'h00000294,read_data,32'h00020037);
+		wb_user_core_read_check(32'h00000298,read_data,32'h00020038);
+		wb_user_core_read_check(32'h0000029C,read_data,32'h00020039);
+		wb_user_core_read_check(32'h000002A0,read_data,32'h00020040);
+		wb_user_core_read_check(32'h000002A4,read_data,32'h00020041);
+		wb_user_core_read_check(32'h000002A8,read_data,32'h00020042);
+		wb_user_core_read_check(32'h000002AC,read_data,32'h00020043);
+		wb_user_core_read_check(32'h000002B0,read_data,32'h00020044);
+		wb_user_core_read_check(32'h000002B4,read_data,32'h00020045);
+		wb_user_core_read_check(32'h000002B8,read_data,32'h00020046);
+		wb_user_core_read_check(32'h000002BC,read_data,32'h00020047);
+		wb_user_core_read_check(32'h000002C0,read_data,32'h00020048);
+		wb_user_core_read_check(32'h000002C4,read_data,32'h00020049);
+		wb_user_core_read_check(32'h000002C8,read_data,32'h00020050);
+		wb_user_core_read_check(32'h000002CC,read_data,32'h00020051);
+		wb_user_core_read_check(32'h000002D0,read_data,32'h00020052);
+		wb_user_core_read_check(32'h000002D4,read_data,32'h00020053);
+		wb_user_core_read_check(32'h000002D8,read_data,32'h00020054);
+		wb_user_core_read_check(32'h000002DC,read_data,32'h00020055);
+		wb_user_core_read_check(32'h000002E0,read_data,32'h00020056);
+		wb_user_core_read_check(32'h000002E4,read_data,32'h00020057);
+		wb_user_core_read_check(32'h000002E8,read_data,32'h00020058);
+		wb_user_core_read_check(32'h000002EC,read_data,32'h00020059);
+
+		repeat (10) @(posedge clock);
+		$display("#############################################");
+		$display("  Page Read through Indirect Access           ");
+		$display("#############################################");
+                wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+		wb_user_core_write(`QSPIM_IMEM_CTRL1,{16'h0,1'b0,1'b0,4'b0001,P_MODE_SWITCH_AT_ADDR,P_QUAD,P_SINGLE,4'b0001});
+		wb_user_core_write(`QSPIM_IMEM_CTRL2,{8'hF0,2'b00,2'b10,P_FSM_CAMDR,8'h00,8'hEB});
+		wb_user_core_write(`QSPIM_IMEM_ADDR,32'h00000200);
+
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020000);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020001);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020002);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020003);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020004);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020005);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020006);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020007);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020008);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020009);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020010);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020011);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020012);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020013);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020014);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020015);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020016);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020017);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020018);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020019);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020020);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020021);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020022);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020023);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020024);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020025);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020026);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020027);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020028);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020029);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020030);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020031);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020032);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020033);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020034);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020035);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020036);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020037);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020038);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020039);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020040);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020041);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020042);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020043);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020044);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020045);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020046);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020047);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020048);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020049);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020050);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020051);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020052);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020053);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020054);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020055);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020056);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020057);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020058);
+		wb_user_core_read_check(`QSPIM_IMEM_RDATA,read_data,32'h00020059);
+
+		repeat (100) @(posedge clock);
+			// $display("+1000 cycles");
+
+          	if(test_fail == 0) begin
+		   `ifdef GL
+	    	       $display("Monitor: SPI Master Mode (GL) Passed");
+		   `else
+		       $display("Monitor: SPI Master Mode (RTL) Passed");
+		   `endif
+	        end else begin
+		    `ifdef GL
+	    	        $display("Monitor: SPI Master Mode (GL) Failed");
+		    `else
+		        $display("Monitor: SPI Master Mode (RTL) Failed");
+		    `endif
+		 end
+	    	$display("###################################################");
+	        $finish;
+	end
+
+	initial begin
+		wb_rst_i <= 1'b1;
+		#100;
+		wb_rst_i <= 1'b0;	    	// Release reset
+	end
+wire USER_VDD1V8 = 1'b1;
+wire VSS = 1'b0;
+
+user_project_wrapper u_top(
+`ifdef USE_POWER_PINS
+    .vccd1(USER_VDD1V8),	// User area 1 1.8V supply
+    .vssd1(VSS),	// User area 1 digital ground
+`endif
+    .wb_clk_i        (clock),  // System clock
+    .user_clock2     (1'b1),  // Real-time clock
+    .wb_rst_i        (wb_rst_i),  // Regular Reset signal
+
+    .wbs_cyc_i   (wbd_ext_cyc_i),  // strobe/request
+    .wbs_stb_i   (wbd_ext_stb_i),  // strobe/request
+    .wbs_adr_i   (wbd_ext_adr_i),  // address
+    .wbs_we_i    (wbd_ext_we_i),  // write
+    .wbs_dat_i   (wbd_ext_dat_i),  // data output
+    .wbs_sel_i   (wbd_ext_sel_i),  // byte enable
+
+    .wbs_dat_o   (wbd_ext_dat_o),  // data input
+    .wbs_ack_o   (wbd_ext_ack_o),  // acknowlegement
+
+ 
+    // Logic Analyzer Signals
+    .la_data_in      ('1) ,
+    .la_data_out     (),
+    .la_oenb         ('0),
+ 
+
+    // IOs
+    .io_in          (io_in)  ,
+    .io_out         (io_out) ,
+    .io_oeb         (io_oeb) ,
+
+    .user_irq       () 
+
+);
+
+`ifndef GL // Drive Power for Hold Fix Buf
+    // All standard cell need power hook-up for functionality work
+    initial begin
+
+    end
+`endif    
+
+//------------------------------------------------------
+//  Integrate the Serial flash with qurd support to
+//  user core using the gpio pads
+//  ----------------------------------------------------
+
+   wire flash_clk = io_out[24];
+   wire flash_csb = io_out[28];
+   // Creating Pad Delay
+   wire #1 io_oeb_29 = io_oeb[29];
+   wire #1 io_oeb_30 = io_oeb[30];
+   wire #1 io_oeb_31 = io_oeb[31];
+   wire #1 io_oeb_32 = io_oeb[32];
+   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[29] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[30] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[31] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[32] : 1'bz;
+
+   assign io_in[29] = flash_io0;
+   assign io_in[30] = flash_io1;
+   assign io_in[31] = flash_io2;
+   assign io_in[32] = flash_io3;
+
+
+   // Quad flash
+     s25fl256s #(.mem_file_name("flash0.hex"),
+	         .otp_file_name("none"),
+                 .TimingModel("S25FL512SAGMFI010_F_30pF")) 
+		 u_spi_flash_256mb (
+           // Data Inputs/Outputs
+       .SI      (flash_io0),
+       .SO      (flash_io1),
+       // Controls
+       .SCK     (flash_clk),
+       .CSNeg   (flash_csb),
+       .WPNeg   (flash_io2),
+       .HOLDNeg (flash_io3),
+       .RSTNeg  (!wb_rst_i)
+
+       );
+
+   wire spiram_csb = io_out[26];
+
+   spiram #(.mem_file_name("flash1.hex"))
+	u_sfram (
+         // Data Inputs/Outputs
+           .io0     (flash_io0),
+           .io1     (flash_io1),
+           // Controls
+           .clk    (flash_clk),
+           .csb    (spiram_csb),
+           .io2    (flash_io2),
+           .io3    (flash_io3)
+    );
+
+
+task wb_user_core_write;
+input [31:0] address;
+input [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h1;  // write
+  wbd_ext_dat_i =data;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("STATUS: WB USER ACCESS WRITE Address : 0x%x, Data : 0x%x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read;
+input [31:0] address;
+output [31:0] data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("STATUS: WB USER ACCESS READ  Address : 0x%x, Data : 0x%x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read_check;
+input [31:0] address;
+output [31:0] data;
+input [31:0] cmp_data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  if(data !== cmp_data) begin
+     $display("ERROR : WB USER ACCESS READ  Address : 0x%x, Exd: 0x%x Rxd: 0x%x ",address,cmp_data,data);
+     user_spi_tb.test_fail = 1;
+  end else begin
+     $display("STATUS: WB USER ACCESS READ  Address : 0x%x, Data : 0x%x",address,data);
+  end
+  repeat (2) @(posedge clock);
+end
+endtask
+
+
+`ifdef GL
+
+wire        wbd_spi_stb_i   = u_top.u_spi_master.wbd_stb_i;
+wire        wbd_spi_ack_o   = u_top.u_spi_master.wbd_ack_o;
+wire        wbd_spi_we_i    = u_top.u_spi_master.wbd_we_i;
+wire [31:0] wbd_spi_adr_i   = u_top.u_spi_master.wbd_adr_i;
+wire [31:0] wbd_spi_dat_i   = u_top.u_spi_master.wbd_dat_i;
+wire [31:0] wbd_spi_dat_o   = u_top.u_spi_master.wbd_dat_o;
+wire [3:0]  wbd_spi_sel_i   = u_top.u_spi_master.wbd_sel_i;
+
+wire        wbd_sdram_stb_i = u_top.u_sdram_ctrl.wb_stb_i;
+wire        wbd_sdram_ack_o = u_top.u_sdram_ctrl.wb_ack_o;
+wire        wbd_sdram_we_i  = u_top.u_sdram_ctrl.wb_we_i;
+wire [31:0] wbd_sdram_adr_i = u_top.u_sdram_ctrl.wb_addr_i;
+wire [31:0] wbd_sdram_dat_i = u_top.u_sdram_ctrl.wb_dat_i;
+wire [31:0] wbd_sdram_dat_o = u_top.u_sdram_ctrl.wb_dat_o;
+wire [3:0]  wbd_sdram_sel_i = u_top.u_sdram_ctrl.wb_sel_i;
+
+wire        wbd_uart_stb_i  = u_top.u_uart_i2c_usb.reg_cs;
+wire        wbd_uart_ack_o  = u_top.u_uart_i2c_usb.reg_ack;
+wire        wbd_uart_we_i   = u_top.u_uart_i2c_usb.reg_wr;
+wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_i2c_usb.reg_addr;
+wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_i2c_usb.reg_wdata;
+wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_i2c_usb.reg_rdata;
+wire        wbd_uart_sel_i  = u_top.u_uart_i2c_usb.reg_be;
+
+`endif
+
+/**
+`ifdef GL
+//-----------------------------------------------------------------------------
+// RISC IMEM amd DMEM Monitoring TASK
+//-----------------------------------------------------------------------------
+
+`define RISC_CORE  user_uart_tb.u_top.u_core.u_riscv_top
+
+always@(posedge `RISC_CORE.wb_clk) begin
+    if(`RISC_CORE.wbd_imem_ack_i)
+          $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x", `RISC_CORE.wbd_imem_adr_o,`RISC_CORE.wbd_imem_dat_i);
+    if(`RISC_CORE.wbd_dmem_ack_i && `RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_o);
+    if(`RISC_CORE.wbd_dmem_ack_i && !`RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_i);
+end
+
+`endif
+**/
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/user_uart/.user_uart.c.un~ b/verilog/dv/user_uart/.user_uart.c.un~
new file mode 100644
index 0000000..5835313
--- /dev/null
+++ b/verilog/dv/user_uart/.user_uart.c.un~
Binary files differ
diff --git a/verilog/dv/user_uart/Makefile b/verilog/dv/user_uart/Makefile
new file mode 100644
index 0000000..387f35d
--- /dev/null
+++ b/verilog/dv/user_uart/Makefile
@@ -0,0 +1,111 @@
+# 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_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_BEHAVIOURAL_AGENTS = ../agents
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/yifive/ycr1c/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include
+
+## YIFIVE FIRMWARE
+YIFIVE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/dv/firmware
+GCC64_PREFIX?=riscv64-unknown-elf
+
+## RISCV GCC 
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+DUMP?=OFF
+
+.SUFFIXES:
+
+PATTERN = user_uart
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v
+	${GCC64_PREFIX}-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las  -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=0 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\"  -c -I./ -I$(YIFIVE_FIRMWARE_PATH) user_uart.c -o user_uart.o
+	${GCC64_PREFIX}-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las  -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=0 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\"  -D__ASSEMBLY__=1 -c -I./ -I$(YIFIVE_FIRMWARE_PATH)  $(YIFIVE_FIRMWARE_PATH)/crt.S -o crt.o
+	${GCC64_PREFIX}-gcc -o user_uart.elf -T $(YIFIVE_FIRMWARE_PATH)/link.ld user_uart.o crt.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32 -N
+	${GCC64_PREFIX}-objcopy -O verilog user_uart.elf user_uart.hex
+	${GCC64_PREFIX}-objdump -D user_uart.elf > user_uart.dump
+	rm crt.o user_uart.o
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+    else  
+	iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+   endif
+else  
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_GL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	$< -o $@ 
+endif
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c $(CARAVEL_FIRMWARE_PATH)/sections.lds $(CARAVEL_FIRMWARE_PATH)/start.s
+	${GCC64_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: 
+	echo @"This is user boot test, noting to compile the mangment core code"
+
+%.bin: %.elf
+	${GCC64_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log *.dump
+
+.PHONY: clean hex all
diff --git a/verilog/dv/user_uart/run_iverilog b/verilog/dv/user_uart/run_iverilog
new file mode 100755
index 0000000..e461fd1
--- /dev/null
+++ b/verilog/dv/user_uart/run_iverilog
@@ -0,0 +1,42 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# // 
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# //      http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+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_uart.c -o user_uart.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_uart.elf -T ../../rtl/syntacore/scr1/sim/tests/common/link_tcm.ld user_uart.o crt_tcm.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32
+
+riscv64-unknown-elf-objcopy -O verilog user_uart.elf user_uart.hex
+
+riscv64-unknown-elf-objdump -D user_uart.elf > user_uart.dump
+
+rm crt_tcm.o user_uart.o
+
+#iverilog with waveform dump
+iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $PDK_PATH -I  ../../../caravel/verilog/rtl  -I ../ -I ../../../verilog/rtl -I ../ -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I ../../../verilog/rtl/i2cm/src/includes -I ../../../verilog/rtl/usb1_host/src/includes -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp
+
+
+#iverilog -g2005-sv -I $PDK_PATH -DFUNCTIONAL -DSIM -I  ../../../caravel/verilog/rtl -I ../ -I ../../../verilog/rtl -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp
+
+# GLS 
+#iverilog -g2005-sv -D GL -D FUNCTIONAL -I $PDK_PATH -I  ../../../caravel/verilog/rtl  -I ../ -I ../../../verilog/gl -I ../../../verilog -I /home/dinesha/workarea/pdk/sky130A -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp
+#
+
+vvp user_uart_tb.vvp | tee test.log
+
+\rm -rf user_uart_tb.vvp
diff --git a/verilog/dv/user_uart/user_uart.c b/verilog/dv/user_uart/user_uart.c
new file mode 100644
index 0000000..99e0204
--- /dev/null
+++ b/verilog/dv/user_uart/user_uart.c
@@ -0,0 +1,43 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+// //////////////////////////////////////////////////////////////////////////
+#define SC_SIM_OUTPORT (0xf0000000)
+#define uint32_t  long
+
+
+#define reg_mprj_uart_reg0 (*(volatile uint32_t*)0x10010000)
+#define reg_mprj_uart_reg1 (*(volatile uint32_t*)0x10010004)
+#define reg_mprj_uart_reg2 (*(volatile uint32_t*)0x10010008)
+#define reg_mprj_uart_reg3 (*(volatile uint32_t*)0x1001000C)
+#define reg_mprj_uart_reg4 (*(volatile uint32_t*)0x10010010)
+#define reg_mprj_uart_reg5 (*(volatile uint32_t*)0x10010014)
+#define reg_mprj_uart_reg6 (*(volatile uint32_t*)0x10010018)
+#define reg_mprj_uart_reg7 (*(volatile uint32_t*)0x1001001C)
+#define reg_mprj_uart_reg8 (*(volatile uint32_t*)0x10010020)
+
+int main()
+{
+
+    while(1) {
+       // Check UART RX fifo has data, if available loop back the data
+       if(reg_mprj_uart_reg8 != 0) { 
+	   reg_mprj_uart_reg5 = reg_mprj_uart_reg6;
+       }
+    }
+
+    return 0;
+}
diff --git a/verilog/dv/user_uart/user_uart_tb.v b/verilog/dv/user_uart/user_uart_tb.v
new file mode 100644
index 0000000..6c7f255
--- /dev/null
+++ b/verilog/dv/user_uart/user_uart_tb.v
@@ -0,0 +1,456 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  Standalone User validation Test bench                       ////
+////                                                              ////
+////  This file is part of the YIFive cores project               ////
+////  https://github.com/dineshannayya/yifive_r0.git              ////
+////  http://www.opencores.org/cores/yifive/                      ////
+////                                                              ////
+////  Description                                                 ////
+////   This is a standalone test bench to validate the            ////
+////   Digital core.                                              ////
+////   1. User Risc core is booted using  compiled code of        ////
+////      user_risc_boot.c                                        ////
+////   2. User Risc core uses Serial Flash and SDRAM to boot      ////
+////   3. After successful boot, Risc core will check the UART    ////
+////      RX Data, If it's available then it loop back the same   ////
+////      data in uart tx                                         ////
+////   4. Test bench send random 40 character towards User uart   ////
+////      and expect same data to return back                     ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      - Dinesh Annayya, dinesha@opencores.org                 ////
+////                                                              ////
+////  Revision :                                                  ////
+////    0.1 - 16th Feb 2021, Dinesh A                             ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+`default_nettype wire
+
+`timescale 1 ns / 1 ns
+
+`include "s25fl256s.sv"
+`include "uprj_netlists.v"
+`include "mt48lc8m8a2.v"
+`include "uart_agent.v"
+
+
+`define ADDR_SPACE_UART    32'h3001_0000
+`define ADDR_SPACE_PINMUX  32'h3002_0000
+
+
+module user_uart_tb;
+
+reg            clock         ;
+reg            wb_rst_i      ;
+reg            power1, power2;
+reg            power3, power4;
+
+reg            wbd_ext_cyc_i;  // strobe/request
+reg            wbd_ext_stb_i;  // strobe/request
+reg [31:0]     wbd_ext_adr_i;  // address
+reg            wbd_ext_we_i;  // write
+reg [31:0]     wbd_ext_dat_i;  // data output
+reg [3:0]      wbd_ext_sel_i;  // byte enable
+
+wire [31:0]    wbd_ext_dat_o;  // data input
+wire           wbd_ext_ack_o;  // acknowlegement
+wire           wbd_ext_err_o;  // error
+
+// User I/O
+wire [37:0]    io_oeb        ;
+wire [37:0]    io_out        ;
+wire [37:0]    io_in         ;
+
+wire [37:0]    mprj_io       ;
+wire [7:0]     mprj_io_0     ;
+reg            test_fail     ;
+reg [31:0]     read_data     ;
+//----------------------------------
+// Uart Configuration
+// ---------------------------------
+reg [1:0]      uart_data_bit        ;
+reg	       uart_stop_bits       ; // 0: 1 stop bit; 1: 2 stop bit;
+reg	       uart_stick_parity    ; // 1: force even parity
+reg	       uart_parity_en       ; // parity enable
+reg	       uart_even_odd_parity ; // 0: odd parity; 1: even parity
+
+reg [7:0]      uart_data            ;
+reg [15:0]     uart_divisor         ;	// divided by n * 16
+reg [15:0]     uart_timeout         ;// wait time limit
+
+reg [15:0]     uart_rx_nu           ;
+reg [15:0]     uart_tx_nu           ;
+reg [7:0]      uart_write_data [0:39];
+reg 	       uart_fifo_enable     ;	// fifo mode disable
+
+integer i,j;
+
+	// 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("simx.vcd");
+	   	$dumpvars(1, user_uart_tb);
+	   	$dumpvars(0, user_uart_tb.u_top);
+	   end
+       `endif
+
+	initial begin
+		wb_rst_i <= 1'b1;
+		#100;
+		wb_rst_i <= 1'b0;	    	// Release reset
+	end
+initial
+begin
+   uart_data_bit           = 2'b11;
+   uart_stop_bits          = 0; // 0: 1 stop bit; 1: 2 stop bit;
+   uart_stick_parity       = 0; // 1: force even parity
+   uart_parity_en          = 0; // parity enable
+   uart_even_odd_parity    = 1; // 0: odd parity; 1: even parity
+   uart_divisor            = 15;// divided by n * 16
+   uart_timeout            = 500;// wait time limit
+   uart_fifo_enable        = 0;	// fifo mode disable
+
+   #200; // Wait for reset removal
+   repeat (10) @(posedge clock);
+   $display("Monitor: Standalone User Uart Test Started");
+   
+   // Remove Wb Reset
+   wb_user_core_write('h3080_0000,'h1);
+
+   // Enable UART Multi Functional Ports
+   wb_user_core_write(`ADDR_SPACE_PINMUX+'h0038,'h100);
+   
+   repeat (2) @(posedge clock);
+   #1;
+   // Remove all the reset
+   wb_user_core_write('h3080_0000,'h1F);
+
+   repeat (20000) @(posedge clock);  // wait for Processor Get Ready
+   tb_uart.uart_init;
+   wb_user_core_write(`ADDR_SPACE_UART+8'h0,{3'h0,2'b00,1'b1,1'b1,1'b1});  
+   
+   tb_uart.control_setup (uart_data_bit, uart_stop_bits, uart_parity_en, uart_even_odd_parity, 
+	                          uart_stick_parity, uart_timeout, uart_divisor);
+   
+   for (i=0; i<40; i=i+1)
+   	uart_write_data[i] = $random;
+   
+   
+   
+   fork
+      begin
+         for (i=0; i<40; i=i+1)
+         begin
+           $display ("\n... UART Agent Writing char %x ...", uart_write_data[i]);
+            user_uart_tb.tb_uart.write_char (uart_write_data[i]);
+         end
+      end
+   
+      begin
+         for (j=0; j<40; j=j+1)
+         begin
+           user_uart_tb.tb_uart.read_char_chk(uart_write_data[j]);
+         end
+      end
+      join
+   
+      #100
+      tb_uart.report_status(uart_rx_nu, uart_tx_nu);
+   
+      test_fail = 0;
+
+      // Check 
+      // if all the 40 byte transmitted
+      // if all the 40 byte received
+      // if no error 
+      if(uart_tx_nu != 40) test_fail = 1;
+      if(uart_rx_nu != 40) test_fail = 1;
+      if(tb_uart.err_cnt != 0) test_fail = 1;
+
+      $display("###################################################");
+      if(test_fail == 0) begin
+         `ifdef GL
+             $display("Monitor: Standalone User UART Test (GL) Passed");
+         `else
+             $display("Monitor: Standalone User UART Test (RTL) Passed");
+         `endif
+      end else begin
+          `ifdef GL
+              $display("Monitor: Standalone User UART Test (GL) Failed");
+          `else
+              $display("Monitor: Standalone User UART Test (RTL) Failed");
+          `endif
+       end
+      $display("###################################################");
+      #100
+      $finish;
+end
+
+
+wire USER_VDD1V8 = 1'b1;
+wire VSS = 1'b0;
+
+
+user_project_wrapper u_top(
+`ifdef USE_POWER_PINS
+    .vccd1(USER_VDD1V8),	// User area 1 1.8V supply
+    .vssd1(VSS),	// User area 1 digital ground
+`endif
+    .wb_clk_i        (clock),  // System clock
+    .user_clock2     (1'b1),  // Real-time clock
+    .wb_rst_i        (wb_rst_i),  // Regular Reset signal
+
+    .wbs_cyc_i   (wbd_ext_cyc_i),  // strobe/request
+    .wbs_stb_i   (wbd_ext_stb_i),  // strobe/request
+    .wbs_adr_i   (wbd_ext_adr_i),  // address
+    .wbs_we_i    (wbd_ext_we_i),  // write
+    .wbs_dat_i   (wbd_ext_dat_i),  // data output
+    .wbs_sel_i   (wbd_ext_sel_i),  // byte enable
+
+    .wbs_dat_o   (wbd_ext_dat_o),  // data input
+    .wbs_ack_o   (wbd_ext_ack_o),  // acknowlegement
+
+ 
+    // Logic Analyzer Signals
+    .la_data_in      ('1) ,
+    .la_data_out     (),
+    .la_oenb         ('0),
+ 
+
+    // IOs
+    .io_in          (io_in)  ,
+    .io_out         (io_out) ,
+    .io_oeb         (io_oeb) ,
+
+    .user_irq       () 
+
+);
+
+`ifndef GL // Drive Power for Hold Fix Buf
+    // All standard cell need power hook-up for functionality work
+    initial begin
+    end
+`endif    
+
+
+//------------------------------------------------------
+//  Integrate the Serial flash with qurd support to
+//  user core using the gpio pads
+//  ----------------------------------------------------
+
+   wire flash_clk = io_out[24];
+   wire flash_csb = io_out[28];
+   // Creating Pad Delay
+   wire #1 io_oeb_29 = io_oeb[29];
+   wire #1 io_oeb_30 = io_oeb[30];
+   wire #1 io_oeb_31 = io_oeb[31];
+   wire #1 io_oeb_32 = io_oeb[32];
+   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[29] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[30] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[31] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[32] : 1'bz;
+
+   assign io_in[29] = flash_io0;
+   assign io_in[30] = flash_io1;
+   assign io_in[31] = flash_io2;
+   assign io_in[32] = flash_io3;
+
+
+   // Quard flash
+     s25fl256s #(.mem_file_name("user_uart.hex"),
+	         .otp_file_name("none"), 
+                 .TimingModel("S25FL512SAGMFI010_F_30pF")) 
+		 u_spi_flash_256mb
+       (
+           // Data Inputs/Outputs
+       .SI      (flash_io0),
+       .SO      (flash_io1),
+       // Controls
+       .SCK     (flash_clk),
+       .CSNeg   (flash_csb),
+       .WPNeg   (flash_io2),
+       .HOLDNeg (flash_io3),
+       .RSTNeg  (!wb_rst_i)
+
+       );
+
+
+//---------------------------
+//  UART Agent integration
+// --------------------------
+wire uart_txd,uart_rxd;
+
+assign uart_txd   = io_out[2];
+assign io_in[1]  = uart_rxd ;
+ 
+uart_agent tb_uart(
+	.mclk                (clock              ),
+	.txd                 (uart_rxd           ),
+	.rxd                 (uart_txd           )
+	);
+
+
+task wb_user_core_write;
+input [31:0] address;
+input [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h1;  // write
+  wbd_ext_dat_i =data;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("DEBUG WB USER ACCESS WRITE Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read;
+input [31:0] address;
+output [31:0] data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("DEBUG WB USER ACCESS READ Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+`ifdef GL
+
+wire        wbd_spi_stb_i   = u_top.u_spi_master.wbd_stb_i;
+wire        wbd_spi_ack_o   = u_top.u_spi_master.wbd_ack_o;
+wire        wbd_spi_we_i    = u_top.u_spi_master.wbd_we_i;
+wire [31:0] wbd_spi_adr_i   = u_top.u_spi_master.wbd_adr_i;
+wire [31:0] wbd_spi_dat_i   = u_top.u_spi_master.wbd_dat_i;
+wire [31:0] wbd_spi_dat_o   = u_top.u_spi_master.wbd_dat_o;
+wire [3:0]  wbd_spi_sel_i   = u_top.u_spi_master.wbd_sel_i;
+
+wire        wbd_sdram_stb_i = u_top.u_sdram_ctrl.wb_stb_i;
+wire        wbd_sdram_ack_o = u_top.u_sdram_ctrl.wb_ack_o;
+wire        wbd_sdram_we_i  = u_top.u_sdram_ctrl.wb_we_i;
+wire [31:0] wbd_sdram_adr_i = u_top.u_sdram_ctrl.wb_addr_i;
+wire [31:0] wbd_sdram_dat_i = u_top.u_sdram_ctrl.wb_dat_i;
+wire [31:0] wbd_sdram_dat_o = u_top.u_sdram_ctrl.wb_dat_o;
+wire [3:0]  wbd_sdram_sel_i = u_top.u_sdram_ctrl.wb_sel_i;
+
+wire        wbd_uart_stb_i  = u_top.u_uart_i2c_usb.reg_cs;
+wire        wbd_uart_ack_o  = u_top.u_uart_i2c_usb.reg_ack;
+wire        wbd_uart_we_i   = u_top.u_uart_i2c_usb.reg_wr;
+wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_i2c_usb.reg_addr;
+wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_i2c_usb.reg_wdata;
+wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_i2c_usb.reg_rdata;
+wire        wbd_uart_sel_i  = u_top.u_uart_i2c_usb.reg_be;
+
+`endif
+
+/**
+`ifdef GL
+//-----------------------------------------------------------------------------
+// RISC IMEM amd DMEM Monitoring TASK
+//-----------------------------------------------------------------------------
+
+`define RISC_CORE  user_uart_tb.u_top.u_core.u_riscv_top
+
+always@(posedge `RISC_CORE.wb_clk) begin
+    if(`RISC_CORE.wbd_imem_ack_i)
+          $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x", `RISC_CORE.wbd_imem_adr_o,`RISC_CORE.wbd_imem_dat_i);
+    if(`RISC_CORE.wbd_dmem_ack_i && `RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_o);
+    if(`RISC_CORE.wbd_dmem_ack_i && !`RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_i);
+end
+
+`endif
+**/
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/user_uart_master/Makefile b/verilog/dv/user_uart_master/Makefile
new file mode 100644
index 0000000..b52caef
--- /dev/null
+++ b/verilog/dv/user_uart_master/Makefile
@@ -0,0 +1,92 @@
+# 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_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_BEHAVIOURAL_AGENTS = ../agents
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/yifive/ycr1c/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include
+
+## YIFIVE FIRMWARE
+YIFIVE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/dv/firmware
+
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+DUMP?=OFF
+
+.SUFFIXES:
+
+PATTERN = user_uart_master
+
+all:  ${PATTERN:=.vcd}
+
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+    else  
+	iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+   endif
+else  
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_GL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	$< -o $@ 
+endif
+
+%.vcd: %.vvp
+	vvp $<
+
+
+
+# ---- Clean ----
+
+clean:
+	rm -f *.vvp *.vcd *.log 
+
+.PHONY: clean all
diff --git a/verilog/dv/user_uart_master/run_iverilog b/verilog/dv/user_uart_master/run_iverilog
new file mode 100755
index 0000000..e461fd1
--- /dev/null
+++ b/verilog/dv/user_uart_master/run_iverilog
@@ -0,0 +1,42 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# // 
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# //      http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+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_uart.c -o user_uart.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_uart.elf -T ../../rtl/syntacore/scr1/sim/tests/common/link_tcm.ld user_uart.o crt_tcm.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32
+
+riscv64-unknown-elf-objcopy -O verilog user_uart.elf user_uart.hex
+
+riscv64-unknown-elf-objdump -D user_uart.elf > user_uart.dump
+
+rm crt_tcm.o user_uart.o
+
+#iverilog with waveform dump
+iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $PDK_PATH -I  ../../../caravel/verilog/rtl  -I ../ -I ../../../verilog/rtl -I ../ -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I ../../../verilog/rtl/i2cm/src/includes -I ../../../verilog/rtl/usb1_host/src/includes -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp
+
+
+#iverilog -g2005-sv -I $PDK_PATH -DFUNCTIONAL -DSIM -I  ../../../caravel/verilog/rtl -I ../ -I ../../../verilog/rtl -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp
+
+# GLS 
+#iverilog -g2005-sv -D GL -D FUNCTIONAL -I $PDK_PATH -I  ../../../caravel/verilog/rtl  -I ../ -I ../../../verilog/gl -I ../../../verilog -I /home/dinesha/workarea/pdk/sky130A -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp
+#
+
+vvp user_uart_tb.vvp | tee test.log
+
+\rm -rf user_uart_tb.vvp
diff --git a/verilog/dv/user_uart_master/user_uart.c b/verilog/dv/user_uart_master/user_uart.c
new file mode 100644
index 0000000..99e0204
--- /dev/null
+++ b/verilog/dv/user_uart_master/user_uart.c
@@ -0,0 +1,43 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+// //////////////////////////////////////////////////////////////////////////
+#define SC_SIM_OUTPORT (0xf0000000)
+#define uint32_t  long
+
+
+#define reg_mprj_uart_reg0 (*(volatile uint32_t*)0x10010000)
+#define reg_mprj_uart_reg1 (*(volatile uint32_t*)0x10010004)
+#define reg_mprj_uart_reg2 (*(volatile uint32_t*)0x10010008)
+#define reg_mprj_uart_reg3 (*(volatile uint32_t*)0x1001000C)
+#define reg_mprj_uart_reg4 (*(volatile uint32_t*)0x10010010)
+#define reg_mprj_uart_reg5 (*(volatile uint32_t*)0x10010014)
+#define reg_mprj_uart_reg6 (*(volatile uint32_t*)0x10010018)
+#define reg_mprj_uart_reg7 (*(volatile uint32_t*)0x1001001C)
+#define reg_mprj_uart_reg8 (*(volatile uint32_t*)0x10010020)
+
+int main()
+{
+
+    while(1) {
+       // Check UART RX fifo has data, if available loop back the data
+       if(reg_mprj_uart_reg8 != 0) { 
+	   reg_mprj_uart_reg5 = reg_mprj_uart_reg6;
+       }
+    }
+
+    return 0;
+}
diff --git a/verilog/dv/user_uart_master/user_uart_master_tb.v b/verilog/dv/user_uart_master/user_uart_master_tb.v
new file mode 100644
index 0000000..d41ff59
--- /dev/null
+++ b/verilog/dv/user_uart_master/user_uart_master_tb.v
@@ -0,0 +1,303 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  Standalone User validation Test bench                       ////
+////                                                              ////
+////  This file is part of the YIFive cores project               ////
+////  https://github.com/dineshannayya/yifive_r0.git              ////
+////  http://www.opencores.org/cores/yifive/                      ////
+////                                                              ////
+////  Description                                                 ////
+////   This is a standalone test bench to validate the            ////
+////   Digital core using uart master i/f.                        ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      - Dinesh Annayya, dinesha@opencores.org                 ////
+////                                                              ////
+////  Revision :                                                  ////
+////    0.1 - 16th Feb 2021, Dinesh A                             ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+`default_nettype wire
+
+`timescale 1 ns / 1 ns
+
+`include "uprj_netlists.v"
+`include "uart_agent.v"
+
+
+`define ADDR_SPACE_UART    32'h3001_0000
+`define ADDR_SPACE_PINMUX  32'h3002_0000
+
+
+module user_uart_master_tb;
+
+reg            clock         ;
+reg            wb_rst_i      ;
+reg            power1, power2;
+reg            power3, power4;
+
+reg            wbd_ext_cyc_i;  // strobe/request
+reg            wbd_ext_stb_i;  // strobe/request
+reg [31:0]     wbd_ext_adr_i;  // address
+reg            wbd_ext_we_i;  // write
+reg [31:0]     wbd_ext_dat_i;  // data output
+reg [3:0]      wbd_ext_sel_i;  // byte enable
+
+wire [31:0]    wbd_ext_dat_o;  // data input
+wire           wbd_ext_ack_o;  // acknowlegement
+wire           wbd_ext_err_o;  // error
+
+// User I/O
+wire [37:0]    io_oeb        ;
+wire [37:0]    io_out        ;
+wire [37:0]    io_in         ;
+
+wire [37:0]    mprj_io       ;
+wire [7:0]     mprj_io_0     ;
+reg            test_fail     ;
+reg [31:0]     read_data     ;
+//----------------------------------
+// Uart Configuration
+// ---------------------------------
+reg [1:0]      uart_data_bit        ;
+reg	       uart_stop_bits       ; // 0: 1 stop bit; 1: 2 stop bit;
+reg	       uart_stick_parity    ; // 1: force even parity
+reg	       uart_parity_en       ; // parity enable
+reg	       uart_even_odd_parity ; // 0: odd parity; 1: even parity
+
+reg [7:0]      uart_data            ;
+reg [15:0]     uart_divisor         ;	// divided by n * 16
+reg [15:0]     uart_timeout         ;// wait time limit
+
+reg [15:0]     uart_rx_nu           ;
+reg [15:0]     uart_tx_nu           ;
+reg [7:0]      uart_write_data [0:39];
+reg 	       uart_fifo_enable     ;	// fifo mode disable
+
+reg  [127:0]   la_data_in;
+reg       flag;
+
+
+integer i,j;
+
+	// 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;
+		la_data_in = 1;
+	end
+
+	`ifdef WFDUMP
+	   initial begin
+	   	$dumpfile("risc_boot.vcd");
+	   	$dumpvars(0, user_uart_master_tb);
+	   end
+       `endif
+
+	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
+initial
+begin
+   wb_rst_i <= 1'b1;
+   uart_data_bit           = 2'b11;
+   uart_stop_bits          = 1; // 0: 1 stop bit; 1: 2 stop bit;
+   uart_stick_parity       = 0; // 1: force even parity
+   uart_parity_en          = 0; // parity enable
+   uart_even_odd_parity    = 1; // 0: odd parity; 1: even parity
+   uart_divisor            = 15;// divided by n * 16
+   uart_timeout            = 600;// wait time limit
+   uart_fifo_enable        = 0;	// fifo mode disable
+
+   // UPDATE the RTL UART MASTER
+   la_data_in[1] = 1; //  Enable Transmit Path
+   la_data_in[2] = 1; //  Enable Received Path
+   la_data_in[3] = 1; //  Enable Received Path
+   la_data_in[15:4] = ((uart_divisor+1)/16)-1; //  Divisor value
+   la_data_in[17:16] = 2'b00; //  priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+
+   #100;
+   wb_rst_i <= 1'b0;	    	// Release reset
+
+   $display("Monitor: Standalone User Uart master Test Started");
+
+   tb_master_uart.debug_mode = 0; // disable debug display
+   tb_master_uart.uart_init;
+   tb_master_uart.control_setup (uart_data_bit, uart_stop_bits, uart_parity_en, uart_even_odd_parity, 
+	                          uart_stick_parity, uart_timeout, uart_divisor);
+
+   //$write ("\n(%t)Response:\n",$time);
+   flag = 0;
+   while(flag == 0)
+   begin
+        tb_master_uart.read_char(read_data,flag);
+        $write ("%c",read_data);
+   end
+
+
+
+   // Remove Wb Reset
+   uartm_reg_write('h3080_0000,'h1);
+
+   repeat (2) @(posedge clock);
+   #1;
+
+   $display("Monitor: Writing  expected value");
+   
+   test_fail = 0;
+   uartm_reg_write(32'h30020058,32'h11223344);
+   uartm_reg_write(32'h3002005C,32'h22334455);
+   uartm_reg_write(32'h30020060,32'h33445566);
+   uartm_reg_write(32'h30020064,32'h44556677);
+   uartm_reg_write(32'h30020068,32'h55667788);
+   uartm_reg_write(32'h3002006C,32'h66778899);
+
+   uartm_reg_read_check(32'h30020058,32'h11223344);
+   uartm_reg_read_check(32'h3002005C,32'h22334455);
+   uartm_reg_read_check(32'h30020060,32'h33445566);
+   uartm_reg_read_check(32'h30020064,32'h44556677);
+   uartm_reg_read_check(32'h30020068,32'h55667788);
+   uartm_reg_read_check(32'h3002006C,32'h66778899);
+   
+   
+   
+   $display("###################################################");
+   if(test_fail == 0) begin
+      `ifdef GL
+          $display("Monitor: Standalone User UART Master (GL) Passed");
+      `else
+          $display("Monitor: Standalone User Uart Master (RTL) Passed");
+      `endif
+   end else begin
+       `ifdef GL
+           $display("Monitor: Standalone User Uart Master (GL) Failed");
+       `else
+           $display("Monitor: Standalone User Uart Master (RTL) Failed");
+       `endif
+    end
+   $display("###################################################");
+   #100
+   $finish;
+end
+
+
+wire USER_VDD1V8 = 1'b1;
+wire VSS = 1'b0;
+
+
+user_project_wrapper u_top(
+`ifdef USE_POWER_PINS
+    .vccd1(USER_VDD1V8),	// User area 1 1.8V supply
+    .vssd1(VSS),	// User area 1 digital ground
+`endif
+    .wb_clk_i        (clock),  // System clock
+    .user_clock2     (1'b1),  // Real-time clock
+    .wb_rst_i        (wb_rst_i),  // Regular Reset signal
+
+    .wbs_cyc_i   (wbd_ext_cyc_i),  // strobe/request
+    .wbs_stb_i   (wbd_ext_stb_i),  // strobe/request
+    .wbs_adr_i   (wbd_ext_adr_i),  // address
+    .wbs_we_i    (wbd_ext_we_i),  // write
+    .wbs_dat_i   (wbd_ext_dat_i),  // data output
+    .wbs_sel_i   (wbd_ext_sel_i),  // byte enable
+
+    .wbs_dat_o   (wbd_ext_dat_o),  // data input
+    .wbs_ack_o   (wbd_ext_ack_o),  // acknowlegement
+
+ 
+    // Logic Analyzer Signals
+    .la_data_in      (la_data_in) ,
+    .la_data_out     (),
+    .la_oenb         ('0),
+ 
+
+    // IOs
+    .io_in          (io_in)  ,
+    .io_out         (io_out) ,
+    .io_oeb         (io_oeb) ,
+
+    .user_irq       () 
+
+);
+
+`ifndef GL // Drive Power for Hold Fix Buf
+    // All standard cell need power hook-up for functionality work
+    initial begin
+    end
+`endif    
+
+
+//---------------------------
+//  UART Agent integration
+// --------------------------
+wire uart_txd,uart_rxd;
+
+assign uart_txd   = io_out[35];
+assign io_in[34]  = uart_rxd ;
+ 
+uart_agent tb_master_uart(
+	.mclk                (clock              ),
+	.txd                 (uart_rxd           ),
+	.rxd                 (uart_txd           )
+	);
+
+
+
+`include "uart_master_tasks.sv"
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/vpi/system/system.c b/verilog/dv/vpi/system/system.c
new file mode 100644
index 0000000..1501a09
--- /dev/null
+++ b/verilog/dv/vpi/system/system.c
@@ -0,0 +1,52 @@
+# include  <vpi_user.h>
+
+static int system_compiletf(char*user_data)
+{
+      return 0;
+}
+
+static int system_calltf(char*name)
+{
+      vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
+      vpiHandle argv  = vpi_iterate(vpiArgument, callh);
+      vpiHandle arg_handle;
+      s_vpi_value value_s;
+
+
+      	/* Check that there are arguments. */
+      if (argv == 0) {
+	    vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
+	               (int)vpi_get(vpiLineNo, callh));
+	    vpi_printf("%s requires two arguments.\n", name);
+	    vpip_set_return_value(1);
+	    vpi_control(vpiFinish, 1);
+	    return 0;
+      }
+
+      /* Check that the first argument is a string. */
+      arg_handle = vpi_scan(argv);
+      vpi_free_object(argv); /* not calling scan until returns null */
+      value_s.format = vpiStringVal; /* read as a string */
+      vpi_get_value(arg_handle,  &value_s);
+      vpi_printf("System Cmd: %s\n",value_s.value.str);
+      system(value_s.value.str);
+      return 0;
+}
+
+void system_register()
+{
+      s_vpi_systf_data tf_data;
+
+      tf_data.type      = vpiSysTask;
+      tf_data.tfname    = "$system";
+      tf_data.calltf    = system_calltf;
+      tf_data.compiletf = system_compiletf;
+      tf_data.sizetf    = 0;
+      tf_data.user_data = "$system";
+      vpi_register_systf(&tf_data);
+}
+
+void (*vlog_startup_routines[])() = {
+    system_register,
+    0
+};
diff --git a/verilog/dv/wb_port/Makefile b/verilog/dv/wb_port/Makefile
new file mode 100644
index 0000000..a19be6a
--- /dev/null
+++ b/verilog/dv/wb_port/Makefile
@@ -0,0 +1,116 @@
+# 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
+
+## PDK 
+PDK_PATH = $(PDK_ROOT)/sky130A
+
+## 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_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = ../
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/yifive/ycr1c/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
+UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include
+## RISCV GCC 
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+GCC64_PREFIX?=riscv64-unknown-elf
+
+## Simulation mode: RTL/GL
+SIM_DEFINES = -DFUNCTIONAL -DSIM
+SIM?=RTL
+DUMP?=OFF
+
+.SUFFIXES:
+
+PATTERN = wb_port
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v %.hex
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2005-sv $(SIM_DEFINES) -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+    else  
+	iverilog -g2005-sv -DWFDUMP $(SIM_DEFINES) -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	-I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \
+	$< -o $@ 
+   endif
+else  
+	iverilog $(SIM_DEFINES) -DGL -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS) -I$(UPRJ_GL_PATH)  -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 check-env
+	${GCC64_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
+	${GCC64_PREFIX}-objcopy -O verilog $< $@ 
+	# to fix flash base address
+	sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+	${GCC64_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+check-env:
+ifndef PDK_ROOT
+	$(error PDK_ROOT is undefined, please export it before running make)
+endif
+ifeq (,$(wildcard $(PDK_ROOT)/sky130A))
+	$(error $(PDK_ROOT)/sky130A not found, please install pdk before running make)
+endif
+#ifeq (,$(wildcard $(GCC64_PREFIX)-gcc ))
+#	$(error $(GCC64_PREFIX)-gcc is not found, please export GCC_PATH and GCC_PREFIX before running make)
+#endif
+# check for efabless style installation
+ifeq (,$(wildcard $(PDK_ROOT)/sky130A/libs.ref/*/verilog))
+SIM_DEFINES := ${SIM_DEFINES} -DEF_STYLE
+endif
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
diff --git a/verilog/dv/wb_port/run_verilog b/verilog/dv/wb_port/run_verilog
new file mode 100644
index 0000000..5ffed3c
--- /dev/null
+++ b/verilog/dv/wb_port/run_verilog
@@ -0,0 +1,20 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# // 
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# //      http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+
+#iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I /home/dinesha/workarea/pdk/sky130A -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog/dv/caravel -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog/rtl -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog -I ../ -I../../../verilog/rtl -I../../../verilog/gl  -I ../../../verilog wb_port_tb.v -o wb_port.vvp
+iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -DGL -I /home/dinesha/workarea/pdk/sky130A -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog/dv/caravel -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog/rtl -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog -I ../ -I../../../verilog/rtl -I../../../verilog/gl  -I ../../../verilog wb_port_tb.v -o wb_port.vvp
diff --git a/verilog/dv/wb_port/wb_port.c b/verilog/dv/wb_port/wb_port.c
new file mode 100644
index 0000000..2649c67
--- /dev/null
+++ b/verilog/dv/wb_port/wb_port.c
@@ -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
+ */
+
+// 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_wbhost_reg0 (*(volatile uint32_t*)0x30800000)
+#define reg_mprj_globl_reg0  (*(volatile uint32_t*)0x30020000)
+#define reg_mprj_globl_reg1  (*(volatile uint32_t*)0x30020004)
+#define reg_mprj_globl_reg2  (*(volatile uint32_t*)0x30020008)
+#define reg_mprj_globl_reg3  (*(volatile uint32_t*)0x3002000C)
+#define reg_mprj_globl_reg4  (*(volatile uint32_t*)0x30020010)
+#define reg_mprj_globl_reg5  (*(volatile uint32_t*)0x30020014)
+#define reg_mprj_globl_reg6  (*(volatile uint32_t*)0x30020018)
+#define reg_mprj_globl_reg7  (*(volatile uint32_t*)0x3002001C)
+#define reg_mprj_globl_reg8  (*(volatile uint32_t*)0x30020020)
+#define reg_mprj_globl_reg9  (*(volatile uint32_t*)0x30020024)
+#define reg_mprj_globl_reg10 (*(volatile uint32_t*)0x30020028)
+#define reg_mprj_globl_reg11 (*(volatile uint32_t*)0x3002002C)
+#define reg_mprj_globl_reg12 (*(volatile uint32_t*)0x30020030)
+#define reg_mprj_globl_reg13 (*(volatile uint32_t*)0x30020034)
+#define reg_mprj_globl_reg14 (*(volatile uint32_t*)0x30020038)
+#define reg_mprj_globl_reg15 (*(volatile uint32_t*)0x3002003C)
+#define reg_mprj_globl_reg16 (*(volatile uint32_t*)0x30020040)
+#define reg_mprj_globl_reg17 (*(volatile uint32_t*)0x30020044)
+#define reg_mprj_globl_reg18 (*(volatile uint32_t*)0x30020048)
+#define reg_mprj_globl_reg19 (*(volatile uint32_t*)0x3002004C)
+#define reg_mprj_globl_reg20 (*(volatile uint32_t*)0x30020050)
+#define reg_mprj_globl_reg21 (*(volatile uint32_t*)0x30020054)
+#define reg_mprj_globl_reg22 (*(volatile uint32_t*)0x30020058)
+#define reg_mprj_globl_reg23 (*(volatile uint32_t*)0x3002005C)
+#define reg_mprj_globl_reg24 (*(volatile uint32_t*)0x30020060)
+#define reg_mprj_globl_reg25 (*(volatile uint32_t*)0x30020064)
+#define reg_mprj_globl_reg26 (*(volatile uint32_t*)0x30020068)
+#define reg_mprj_globl_reg27 (*(volatile uint32_t*)0x3002006C)
+
+
+/*
+	Wishbone Test:
+		- Configures MPRJ lower 8-IO pins as outputs
+		- Checks counter value through the wishbone port
+*/
+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       |
+	*/
+
+	/* 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]
+    reg_la0_data = 0x000;
+    reg_la0_data = 0x001; // Remove Soft Reset
+
+    // Flag start of the test
+	reg_mprj_datal = 0xAB600000;
+
+    // Remove Wishbone Reset
+    reg_mprj_wbhost_reg0 = 0x1;
+
+    if (reg_mprj_globl_reg0 != 0x89490201) bFail = 1;
+    if (reg_mprj_globl_reg1 != 0xA55AA55A) bFail = 1;
+
+    // Write software Write & Read Register
+    reg_mprj_globl_reg22  = 0x11223344; 
+    reg_mprj_globl_reg23  = 0x22334455; 
+    reg_mprj_globl_reg24  = 0x33445566; 
+    reg_mprj_globl_reg25  = 0x44556677; 
+    reg_mprj_globl_reg26  = 0x55667788; 
+    reg_mprj_globl_reg27  = 0x66778899; 
+
+
+    if (reg_mprj_globl_reg22  != 0x11223344) bFail = 1;
+    if (bFail == 1) reg_mprj_datal = 0xAB610000;
+    if (reg_mprj_globl_reg23  != 0x22334455) bFail = 1;
+    if (bFail == 1) reg_mprj_datal = 0xAB620000;
+    if (reg_mprj_globl_reg24  != 0x33445566) bFail = 1;
+    if (bFail == 1) reg_mprj_datal = 0xAB630000;
+    if (reg_mprj_globl_reg25  != 0x44556677) bFail = 1;
+    if (bFail == 1) reg_mprj_datal = 0xAB640000;
+    if (reg_mprj_globl_reg26 != 0x55667788) bFail = 1;
+    if (bFail == 1) reg_mprj_datal = 0xAB650000;
+    if (reg_mprj_globl_reg27 != 0x66778899) bFail = 1;
+    if (bFail == 1) reg_mprj_datal = 0xAB660000;
+
+    if(bFail == 0) {
+        reg_mprj_datal = 0xAB6A0000;
+    } 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
new file mode 100644
index 0000000..88e8bee
--- /dev/null
+++ b/verilog/dv/wb_port/wb_port_tb.v
@@ -0,0 +1,175 @@
+// 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
+
+`timescale 1 ns / 1 ps
+
+`include "uprj_netlists.v"
+`include "caravel_netlists.v"
+`include "spiflash.v"
+
+module wb_port_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("wb_port.vcd");
+		$dumpvars(1, wb_port_tb);
+		$dumpvars(2, wb_port_tb.uut);
+		//$dumpvars(1, wb_port_tb.uut.mprj);
+		$dumpvars(1, wb_port_tb.uut.mprj.u_wb_host);
+		$dumpvars(2, wb_port_tb.uut.mprj.u_pinmux);
+	end
+       `endif
+
+	initial begin
+
+		// Repeat cycles of 1000 clock edges as needed to complete testbench
+		repeat (30) begin
+			repeat (1000) @(posedge clock);
+			// $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
+
+	initial begin
+	   wait(checkbits == 16'h AB60);
+		$display("Monitor: MPRJ-Logic WB Started");
+		wait(checkbits == 16'h AB6A);
+		$display ("##########################################################");
+		`ifdef GL
+	    	$display("Monitor: Mega-Project WB (GL) Passed");
+		`else
+		    $display("Monitor: Mega-Project WB (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("wb_port.hex")
+	) spiflash (
+		.csb(flash_csb),
+		.clk(flash_clk),
+		.io0(flash_io0),
+		.io1(flash_io1),
+		.io2(),			// not used
+		.io3()			// not used
+	);
+
+`ifndef GL // Drive Power for Hold Fix Buf
+    // All standard cell need power hook-up for functionality work
+    initial begin
+    end
+`endif    
+endmodule
+`default_nettype wire