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
diff --git a/verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv b/verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv
new file mode 100644
index 0000000..7fd1a62
--- /dev/null
+++ b/verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv
@@ -0,0 +1,205 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// clock skew adjust ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block is useful for global clock skew adjustment ////
+//// logic implementation: ////
+//// clk_out = (sel=0) ? clk_in : ////
+//// (sel=1) ? clk_d1 : ////
+//// (sel=1) ? clk_d2 : ////
+//// ..... ////
+//// (sel=15)? clk_d15 :clk_in ////
+//// ////
+//// Note: each d* indicate clk buf delay ////
+//// ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 29th Feb 2021, Dinesh A ////
+//// Initial version ////
+///
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+// Clock-in is east pad direction
+// clock out give in other three direction for better placement
+/////////////////////////////////////////////////////////////////////
+module clk_skew_adjust(
+`ifdef USE_POWER_PINS
+ vccd1,// User area 1 1.8V supply
+ vssd1,// User area 1 digital ground
+`endif
+clk_in, sel, clk_out);
+
+
+`ifdef USE_POWER_PINS
+ input vccd1;// User area 1 1.8V supply
+ input vssd1;// User area 1 digital ground
+`endif
+ input clk_in;
+ output clk_out;
+ input [3:0] sel;
+ wire in0;
+ wire in1;
+ wire in2;
+ wire in3;
+ wire in4;
+ wire in5;
+ wire in6;
+ wire in7;
+ wire in8;
+ wire in9;
+ wire in10;
+ wire in11;
+ wire in12;
+ wire in13;
+ wire in14;
+ wire in15;
+
+ wire clk_d1;
+ wire clk_d2;
+ wire clk_d3;
+ wire clk_d4;
+ wire clk_d5;
+ wire clk_d6;
+ wire clk_d7;
+ wire clk_d8;
+ wire clk_d9;
+ wire clk_d10;
+ wire clk_d11;
+ wire clk_d12;
+ wire clk_d13;
+ wire clk_d14;
+ wire clk_d15;
+
+ wire d00;
+ wire d01;
+ wire d02;
+ wire d03;
+ wire d04;
+ wire d05;
+ wire d06;
+ wire d07;
+ wire d10;
+ wire d11;
+ wire d12;
+ wire d13;
+ wire d20;
+ wire d21;
+ wire d30;
+
+
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_1 (.A(clk_in), .X(clk_d1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_2 (.A(clk_d1), .X(clk_d2));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_3 (.A(clk_d2), .X(clk_d3));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_4 (.A(clk_d3), .X(clk_d4));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_5 (.A(clk_d4), .X(clk_d5));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_6 (.A(clk_d5), .X(clk_d6));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_7 (.A(clk_d6), .X(clk_d7));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_8 (.A(clk_d7), .X(clk_d8));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_9 (.A(clk_d8), .X(clk_d9));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_10 (.A(clk_d9), .X(clk_d10));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_11 (.A(clk_d10), .X(clk_d11));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_12 (.A(clk_d11), .X(clk_d12));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_13 (.A(clk_d12), .X(clk_d13));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_14 (.A(clk_d13), .X(clk_d14));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_15 (.A(clk_d14), .X(clk_d15));
+
+
+ // Tap point selection
+ assign in0 = clk_in;
+ assign in1 = clk_d1;
+ assign in2 = clk_d2;
+ assign in3 = clk_d3;
+ assign in4 = clk_d4;
+ assign in5 = clk_d5;
+ assign in6 = clk_d6;
+ assign in7 = clk_d7;
+ assign in8 = clk_d8;
+ assign in9 = clk_d9;
+ assign in10 = clk_d10;
+ assign in11 = clk_d11;
+ assign in12 = clk_d12;
+ assign in13 = clk_d13;
+ assign in14 = clk_d14;
+ assign in15 = clk_d15;
+
+
+ // first level mux - 8
+ sky130_fd_sc_hd__mux2_1 u_mux_level_00 ( .X (d00) , .A0 (in0), .A1(in1), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_01 ( .X (d01) , .A0 (in2), .A1(in3), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_02 ( .X (d02) , .A0 (in4), .A1(in5), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_03 ( .X (d03) , .A0 (in6), .A1(in7), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_04 ( .X (d04) , .A0 (in8), .A1(in9), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_05 ( .X (d05) , .A0 (in10), .A1(in11), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_06 ( .X (d06) , .A0 (in12), .A1(in13), .S(sel[0]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_07 ( .X (d07) , .A0 (in14), .A1(in15), .S(sel[0]));
+
+ // second level mux - 4
+ sky130_fd_sc_hd__mux2_1 u_mux_level_10 ( .X (d10) , .A0 (d00), .A1(d01), .S(sel[1]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_11 ( .X (d11) , .A0 (d02), .A1(d03), .S(sel[1]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_12 ( .X (d12) , .A0 (d04), .A1(d05), .S(sel[1]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_13 ( .X (d13) , .A0 (d06), .A1(d07), .S(sel[1]));
+
+ // third level mux - 2
+ sky130_fd_sc_hd__mux2_1 u_mux_level_20 ( .X (d20) , .A0 (d10), .A1(d11), .S(sel[2]));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_21 ( .X (d21) , .A0 (d12), .A1(d13), .S(sel[2]));
+
+ // fourth level mux - 1
+ sky130_fd_sc_hd__mux2_4 u_mux_level_30 ( .X (d30) , .A0 (d20), .A1(d21), .S(sel[3]));
+
+
+ assign clk_out = d30;
+
+endmodule
diff --git a/verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.v b/verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.v
new file mode 100644
index 0000000..a961a50
--- /dev/null
+++ b/verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.v
@@ -0,0 +1,2898 @@
+module clk_skew_adjust (clk_in,
+ clk_out,
+ vccd1,
+ vssd1,
+ sel);
+ input clk_in;
+ output clk_out;
+ input vccd1;
+ input vssd1;
+ input [3:0] sel;
+
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_1 (.A(clk_in),
+ .X(clk_d1),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_10 (.A(clk_d9),
+ .X(clk_d10),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_11 (.A(clk_d10),
+ .X(clk_d11),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_12 (.A(clk_d11),
+ .X(clk_d12),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_13 (.A(clk_d12),
+ .X(clk_d13),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_14 (.A(clk_d13),
+ .X(clk_d14),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_15 (.A(clk_d14),
+ .X(clk_d15),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_2 (.A(clk_d1),
+ .X(clk_d2),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_3 (.A(clk_d2),
+ .X(clk_d3),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_4 (.A(clk_d3),
+ .X(clk_d4),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_5 (.A(clk_d4),
+ .X(clk_d5),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_6 (.A(clk_d5),
+ .X(clk_d6),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_7 (.A(clk_d6),
+ .X(clk_d7),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_8 (.A(clk_d7),
+ .X(clk_d8),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__clkdlybuf4s15_2 clkbuf_9 (.A(clk_d8),
+ .X(clk_d9),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_00 (.A0(clk_in),
+ .A1(clk_d1),
+ .S(sel[0]),
+ .X(d00),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_01 (.A0(clk_d2),
+ .A1(clk_d3),
+ .S(sel[0]),
+ .X(d01),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_02 (.A0(clk_d4),
+ .A1(clk_d5),
+ .S(sel[0]),
+ .X(d02),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_03 (.A0(clk_d6),
+ .A1(clk_d7),
+ .S(sel[0]),
+ .X(d03),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_04 (.A0(clk_d8),
+ .A1(clk_d9),
+ .S(sel[0]),
+ .X(d04),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_05 (.A0(clk_d10),
+ .A1(clk_d11),
+ .S(sel[0]),
+ .X(d05),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_06 (.A0(clk_d12),
+ .A1(clk_d13),
+ .S(sel[0]),
+ .X(d06),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_07 (.A0(clk_d14),
+ .A1(clk_d15),
+ .S(sel[0]),
+ .X(d07),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_10 (.A0(d00),
+ .A1(d01),
+ .S(sel[1]),
+ .X(d10),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_11 (.A0(d02),
+ .A1(d03),
+ .S(sel[1]),
+ .X(d11),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_12 (.A0(d04),
+ .A1(d05),
+ .S(sel[1]),
+ .X(d12),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_13 (.A0(d06),
+ .A1(d07),
+ .S(sel[1]),
+ .X(d13),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_20 (.A0(d10),
+ .A1(d11),
+ .S(sel[2]),
+ .X(d20),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_1 u_mux_level_21 (.A0(d12),
+ .A1(d13),
+ .S(sel[2]),
+ .X(d21),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__mux2_4 u_mux_level_30 (.A0(d20),
+ .A1(d21),
+ .S(sel[3]),
+ .X(clk_out),
+ .VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_0 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_1 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_2 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_4 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_5 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_6 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_7 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_8 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_9 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_10 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_11 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_12 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_13 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_14 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_16 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_17 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_18 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_19 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_20 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_21 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_22 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_23 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_24 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_25 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_26 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_28 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_29 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_30 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_31 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_33 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_34 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_35 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_36 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_37 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_38 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_40 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_41 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_42 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_43 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_45 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_46 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_47 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_48 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_49 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_50 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_52 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_53 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_54 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_55 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_57 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_58 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_60 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_61 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 PHY_63 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_64 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_65 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_66 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_67 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_68 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_69 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_70 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_71 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_72 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_73 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_74 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_75 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_76 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_77 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_78 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_79 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_80 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_81 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_82 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_83 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_84 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_85 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_86 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_87 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_88 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_89 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_90 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_91 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_92 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_93 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_94 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_95 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_96 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_97 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_98 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_99 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_100 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_101 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_102 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_103 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_104 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_105 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_106 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_107 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_108 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_109 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_110 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_111 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_112 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_113 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_114 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_115 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_116 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_117 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_118 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_119 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_120 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_121 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_122 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_123 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_124 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_125 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_126 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_127 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_128 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_129 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_130 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_131 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_132 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_133 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_134 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_135 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_136 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_137 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_138 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_139 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_140 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_141 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_142 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_143 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_144 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_145 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_146 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_147 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_148 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_149 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_150 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_151 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_152 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_153 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_154 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_155 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_156 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_157 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_158 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_159 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_160 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_161 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_162 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_163 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_164 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__tapvpwrvgnd_1 PHY_165 (.VGND(vssd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_0_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_0_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_63 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_75 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_0_87 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_94 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_106 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_0_118 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_125 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_137 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_0_149 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_156 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_0_168 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_0_180 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_0_187 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_1_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_1_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_2_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_2_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_2_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_2_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_3_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_3_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_4_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_4_23 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_35 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_47 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_4_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_4_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_4_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_5_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_114 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_5_126 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_5_134 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_5_146 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_5_152 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_5_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_6_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_6_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_6_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_6_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_7_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_102 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_114 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_126 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_138 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_7_150 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_7_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_8_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_8_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_8_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_8_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_9_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_9_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_9_64 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_76 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_9_88 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_9_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_9_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_9_183 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_9_189 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_10_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_10_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_10_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_10_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_11_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_11_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_11_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_11_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_11_174 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_11_186 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_12_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_12_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_12_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_12_106 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_12_118 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_12_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_12_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_13_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_13_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_14_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_14_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_14_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_14_146 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_14_158 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_14_164 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_14_174 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_14_182 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_14_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_15_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_15_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_16_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_16_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_16_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_16_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_17_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_17_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_17_60 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_73 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_17_85 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_17_91 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_17_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_17_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_17_174 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_17_186 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_18_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_40 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_18_52 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_18_60 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_18_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_18_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_19_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_19_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_20_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_20_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_20_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_20_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_12 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_21_24 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_21_30 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_21_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_21_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_21_179 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_21_187 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_22_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_22_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_71 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_83 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_95 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_107 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_22_119 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_132 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_144 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_156 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_22_168 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_22_180 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_22_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_23_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_23_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_23_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_133 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_23_145 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_23_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_23_167 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_23_179 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_23_187 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_24_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_24_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_24_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_24_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_12 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_25_24 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_25_30 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_25_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_25_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_25_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_25_174 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_25_186 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_26_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_26_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_26_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_26_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_26_167 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_26_179 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_26_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_27_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_80 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_27_178 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_28_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_28_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_110 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_159 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_28_171 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_28_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_29_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_29_68 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_29_76 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_29_88 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_93 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_105 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_129 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_141 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_29_154 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_29_166 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_29_181 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_29_189 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_39 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_30_51 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_30_59 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_62 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_74 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_86 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_30_98 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_2 FILLER_30_106 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_30_117 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_30_121 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_123 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_30_135 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_30_139 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_30_149 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_30_161 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_30_169 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_30_179 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_30_184 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_3 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_15 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_4 FILLER_31_27 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_32 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_44 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_31_56 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_63 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_75 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_31_87 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_94 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_106 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_31_118 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_125 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__fill_1 FILLER_31_137 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_8 FILLER_31_147 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_156 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_12 FILLER_31_168 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_6 FILLER_31_180 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+ sky130_fd_sc_hd__decap_3 FILLER_31_187 (.VGND(vssd1),
+ .VNB(vssd1),
+ .VPB(vccd1),
+ .VPWR(vccd1));
+endmodule
diff --git a/verilog/rtl/clk_skew_adjust/synth/Makefile b/verilog/rtl/clk_skew_adjust/synth/Makefile
new file mode 100644
index 0000000..f6ae1df
--- /dev/null
+++ b/verilog/rtl/clk_skew_adjust/synth/Makefile
@@ -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>
+# // //////////////////////////////////////////////////////////////////////////
+#------------------------------------------------------------------------------
+# Makefile for Synthesis
+#------------------------------------------------------------------------------
+
+# Paths
+export ROOT_DIR := $(shell pwd)
+export REPORT_DIR := $(ROOT_DIR)/reports
+export NETLIST_DIR := $(ROOT_DIR)/netlist
+export TMP_DIR := $(ROOT_DIR)/tmp
+
+
+# Targets
+.PHONY: clean create synth
+
+default: clean create synth
+
+synth: clean create
+ yosys -g -c synth.tcl -l synth.log
+
+create:
+ mkdir -p ./tmp/synthesis;
+ mkdir -p ./reports;
+ mkdir -p ./netlist;
+ $(OPENLANE_ROOT)/scripts/libtrim.pl $(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib $(PDK_ROOT)/sky130A/libs.tech/openlane/sky130_fd_sc_hd/no_synth.cells > ./tmp/trimmed.lib
+
+
+
+clean:
+ $(RM) -R synth.log
+ $(RM) -R $(REPORT_DIR)
+ $(RM) -R $(NETLIST_DIR)
+ $(RM) -R $(TMP_DIR)
diff --git a/verilog/rtl/clk_skew_adjust/synth/synth.tcl b/verilog/rtl/clk_skew_adjust/synth/synth.tcl
new file mode 100755
index 0000000..b7adea6
--- /dev/null
+++ b/verilog/rtl/clk_skew_adjust/synth/synth.tcl
@@ -0,0 +1,385 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // 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>
+# // //////////////////////////////////////////////////////////////////////////
+# inputs expected as env vars
+#set opt $::env(SYNTH_OPT)
+########### config.tcl ##################
+# User config
+
+# User config
+set ::env(DESIGN_DIR) ../
+
+set ::env(PROJ_DIR) ../../../../
+
+# User config
+set ::env(DESIGN_NAME) clk_mux
+
+# Change if needed
+set ::env(VERILOG_FILES) [glob \
+ ../src/clk_mux.v ]
+
+
+set ::env(SYNTH_DEFINES) [list YOSYS ]
+
+
+set ::env(LIB_SYNTH) ./tmp/trimmed.lib
+
+
+# Fill this
+set ::env(CLOCK_PERIOD) "10"
+#set ::env(CLOCK_PORT) "mclk"
+set ::env(CLOCK_TREE_SYNTH) 0
+
+set ::env(RUN_SIMPLE_CTS) 0
+set ::env(SYNTH_BUFFERING) 0
+set ::env(SYNTH_SIZING) 0
+
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8"
+set ::env(SYNTH_CAP_LOAD) "17.65"
+set ::env(SYNTH_MAX_TRAN) "[expr {0.1*10.0}]"
+
+set ::env(SYNTH_MAX_FANOUT) 6
+set ::env(FP_CORE_UTIL) 50
+set ::env(PL_TARGET_DENSITY) [ expr ($::env(FP_CORE_UTIL)+5) / 100.0 ]
+set ::env(CELL_PAD) 4
+
+set ::env(SYNTH_NO_FLAT) "0"
+
+
+set ::env(SYNTH_STRATEGY) "AREA 0"
+set ::env(SYNTH_TIELO_PORT) "sky130_fd_sc_hd__conb_1 LO"
+set ::env(SYNTH_TIEHI_PORT) "sky130_fd_sc_hd__conb_1 HI"
+set ::env(SYNTH_MIN_BUF_PORT) "sky130_fd_sc_hd__buf_2 A X"
+
+
+#set ::env(CLOCK_NET) $::env(CLOCK_PORT)
+
+
+
+set ::env(yosys_tmp_file_tag) "./tmp/"
+set ::env(TMP_DIR) "./tmp/"
+set ::env(yosys_netlist_dir) "./netlist"
+set ::env(yosys_report_file_tag) "./reports/yosys"
+set ::env(yosys_result_file_tag) "./reports/yosys.synthesis"
+
+set ::env(SAVE_NETLIST) $::env(yosys_netlist_dir)/$::env(DESIGN_NAME).gv
+
+
+
+########### End of config.tcl
+set buffering $::env(SYNTH_BUFFERING)
+set sizing $::env(SYNTH_SIZING)
+
+yosys -import
+
+set vtop $::env(DESIGN_NAME)
+#set sdc_file $::env(SDC_FILE)
+set sclib $::env(LIB_SYNTH)
+
+if { [info exists ::env(SYNTH_DEFINES) ] } {
+ foreach define $::env(SYNTH_DEFINES) {
+ log "Defining $define"
+ verilog_defines -D$define
+ }
+}
+
+set vIdirsArgs ""
+if {[info exist ::env(VERILOG_INCLUDE_DIRS)]} {
+ foreach dir $::env(VERILOG_INCLUDE_DIRS) {
+ log "Adding include file -I$dir "
+ lappend vIdirsArgs "-I$dir"
+ }
+ set vIdirsArgs [join $vIdirsArgs]
+}
+
+
+
+if { [info exists ::env(EXTRA_LIBS) ] } {
+ foreach lib $::env(EXTRA_LIBS) {
+ read_liberty {*}$vIdirsArgs -lib -ignore_miss_dir -setattr blackbox $lib
+ }
+}
+
+
+
+# ns expected (in sdc as well)
+set clock_period [expr {$::env(CLOCK_PERIOD)*1000}]
+
+set driver $::env(SYNTH_DRIVING_CELL)
+set cload $::env(SYNTH_CAP_LOAD)
+# input pin cap of IN_3VX8
+set max_FO $::env(SYNTH_MAX_FANOUT)
+if {![info exist ::env(SYNTH_MAX_TRAN)]} {
+ set ::env(SYNTH_MAX_TRAN) [expr {0.1*$clock_period}]
+} else {
+ set ::env(SYNTH_MAX_TRAN) [expr {$::env(SYNTH_MAX_TRAN) * 1000}]
+}
+set max_Tran $::env(SYNTH_MAX_TRAN)
+
+
+# Mapping parameters
+set A_factor 0.00
+set B_factor 0.88
+set F_factor 0.00
+
+# Don't change these unless you know what you are doing
+set stat_ext ".stat.rpt"
+set chk_ext ".chk.rpt"
+set gl_ext ".gl.v"
+set constr_ext ".$clock_period.constr"
+set timing_ext ".timing.txt"
+set abc_ext ".abc"
+
+
+# get old sdc, add library specific stuff for abc scripts
+set sdc_file $::env(yosys_tmp_file_tag).sdc
+set outfile [open ${sdc_file} w]
+#puts $outfile $sdc_data
+puts $outfile "set_driving_cell ${driver}"
+puts $outfile "set_load ${cload}"
+close $outfile
+
+
+# ABC Scrips
+set abc_rs_K "resub,-K,"
+set abc_rs "resub"
+set abc_rsz "resub,-z"
+set abc_rw_K "rewrite,-K,"
+set abc_rw "rewrite"
+set abc_rwz "rewrite,-z"
+set abc_rf "refactor"
+set abc_rfz "refactor,-z"
+set abc_b "balance"
+
+set abc_resyn2 "${abc_b}; ${abc_rw}; ${abc_rf}; ${abc_b}; ${abc_rw}; ${abc_rwz}; ${abc_b}; ${abc_rfz}; ${abc_rwz}; ${abc_b}"
+set abc_share "strash; multi,-m; ${abc_resyn2}"
+set abc_resyn2a "${abc_b};${abc_rw};${abc_b};${abc_rw};${abc_rwz};${abc_b};${abc_rwz};${abc_b}"
+set abc_resyn3 "balance;resub;resub,-K,6;balance;resub,-z;resub,-z,-K,6;balance;resub,-z,-K,5;balance"
+set abc_resyn2rs "${abc_b};${abc_rs_K},6;${abc_rw};${abc_rs_K},6,-N,2;${abc_rf};${abc_rs_K},8;${abc_rw};${abc_rs_K},10;${abc_rwz};${abc_rs_K},10,-N,2;${abc_b},${abc_rs_K},12;${abc_rfz};${abc_rs_K},12,-N,2;${abc_rwz};${abc_b}"
+
+set abc_choice "fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore"
+set abc_choice2 "fraig_store; balance; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; ${abc_resyn2}; fraig_store; fraig_restore"
+
+set abc_map_old_cnt "map,-p,-a,-B,0.2,-A,0.9,-M,0"
+set abc_map_old_dly "map,-p,-B,0.2,-A,0.9,-M,0"
+set abc_retime_area "retime,-D,{D},-M,5"
+set abc_retime_dly "retime,-D,{D},-M,6"
+set abc_map_new_area "amap,-m,-Q,0.1,-F,20,-A,20,-C,5000"
+
+set abc_area_recovery_1 "${abc_choice}; map;"
+set abc_area_recovery_2 "${abc_choice2}; map;"
+
+set map_old_cnt "map,-p,-a,-B,0.2,-A,0.9,-M,0"
+set map_old_dly "map,-p,-B,0.2,-A,0.9,-M,0"
+set abc_retime_area "retime,-D,{D},-M,5"
+set abc_retime_dly "retime,-D,{D},-M,6"
+set abc_map_new_area "amap,-m,-Q,0.1,-F,20,-A,20,-C,5000"
+
+if {$buffering==1} {
+ set abc_fine_tune "buffer,-N,${max_FO},-S,${max_Tran};upsize,{D};dnsize,{D}"
+} elseif {$sizing} {
+ set abc_fine_tune "upsize,{D};dnsize,{D}"
+} else {
+ set abc_fine_tune ""
+}
+
+
+set delay_scripts [list \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_map_old_dly};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice2};${abc_map_old_dly};${abc_area_recovery_2}; retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_dly}; scleanup;${abc_choice};${abc_map_old_dly};${abc_area_recovery_1}; retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_old_dly};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ ]
+
+set area_scripts [list \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_resyn2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ \
+ "+read_constr,${sdc_file};fx;mfs;strash;refactor;${abc_choice2};${abc_retime_area};scleanup;${abc_choice2};${abc_map_new_area};${abc_choice2};${abc_map_new_area};retime,-D,{D};${abc_fine_tune};stime,-p;print_stats -m" \
+ ]
+
+set all_scripts [list {*}$delay_scripts {*}$area_scripts]
+
+set strategy_parts [split $::env(SYNTH_STRATEGY)]
+
+proc synth_strategy_format_err { } {
+ upvar area_scripts area_scripts
+ upvar delay_scripts delay_scripts
+ log -stderr "\[ERROR] Misformatted SYNTH_STRATEGY (\"$::env(SYNTH_STRATEGY)\")."
+ log -stderr "\[ERROR] Correct format is \"DELAY|AREA 0-[expr [llength $delay_scripts]-1]|0-[expr [llength $area_scripts]-1]\"."
+ exit 1
+}
+
+if { [llength $strategy_parts] != 2 } {
+ synth_strategy_format_err
+}
+
+set strategy_type [lindex $strategy_parts 0]
+set strategy_type_idx [lindex $strategy_parts 1]
+
+if { $strategy_type != "AREA" && $strategy_type != "DELAY" } {
+ log -stderr "\[ERROR] AREA|DELAY tokens not found. ($strategy_type)"
+ synth_strategy_format_err
+}
+
+if { $strategy_type == "DELAY" && $strategy_type_idx >= [llength $delay_scripts] } {
+ log -stderr "\[ERROR] strategy index ($strategy_type_idx) is too high."
+ synth_strategy_format_err
+}
+
+if { $strategy_type == "AREA" && $strategy_type_idx >= [llength $area_scripts] } {
+ log -stderr "\[ERROR] strategy index ($strategy_type_idx) is too high."
+ synth_strategy_format_err
+}
+
+if { $strategy_type == "DELAY" } {
+ set strategy $strategy_type_idx
+} else {
+ set strategy [expr {[llength $delay_scripts]+$strategy_type_idx}]
+}
+
+
+for { set i 0 } { $i < [llength $::env(VERILOG_FILES)] } { incr i } {
+ read_verilog -sv {*}$vIdirsArgs [lindex $::env(VERILOG_FILES) $i]
+}
+
+if { [info exists ::env(VERILOG_FILES_BLACKBOX)] } {
+ foreach verilog_file $::env(VERILOG_FILES_BLACKBOX) {
+ read_verilog -sv {*}$vIdirsArgs -lib $verilog_file
+ }
+}
+select -module $vtop
+show -format dot -prefix $::env(TMP_DIR)/synthesis/hierarchy
+select -clear
+
+hierarchy -check -top $vtop
+
+# Infer tri-state buffers.
+set tbuf_map false
+if { [info exists ::env(TRISTATE_BUFFER_MAP)] } {
+ if { [file exists $::env(TRISTATE_BUFFER_MAP)] } {
+ set tbuf_map true
+ tribuf
+ } else {
+ log "WARNING: TRISTATE_BUFFER_MAP is defined but could not be found: $::env(TRISTATE_BUFFER_MAP)"
+ }
+}
+
+if { $::env(SYNTH_NO_FLAT) } {
+ synth -top $vtop
+} else {
+ synth -top $vtop -flatten
+}
+
+share -aggressive
+opt
+opt_clean -purge
+
+tee -o "$::env(yosys_report_file_tag)_pre.stat" stat
+
+# Map tri-state buffers.
+if { $tbuf_map } {
+ log {mapping tbuf}
+ techmap -map $::env(TRISTATE_BUFFER_MAP)
+ simplemap
+}
+
+# handle technology mapping of 4-MUX, and tell Yosys to infer 4-muxes
+if { [info exists ::env(SYNTH_MUX4_MAP)] && [file exists $::env(SYNTH_MUX4_MAP)] } {
+ muxcover -mux4
+ techmap -map $::env(SYNTH_MUX4_MAP)
+ simplemap
+}
+
+# handle technology mapping of 2-MUX
+if { [info exists ::env(SYNTH_MUX_MAP)] && [file exists $::env(SYNTH_MUX_MAP)] } {
+ techmap -map $::env(SYNTH_MUX_MAP)
+ simplemap
+}
+
+# handle technology mapping of latches
+if { [info exists ::env(SYNTH_LATCH_MAP)] && [file exists $::env(SYNTH_LATCH_MAP)] } {
+ techmap -map $::env(SYNTH_LATCH_MAP)
+ simplemap
+}
+
+dfflibmap -liberty $sclib
+tee -o "$::env(yosys_report_file_tag)_dff.stat" stat
+
+if { [info exists ::env(SYNTH_EXPLORE)] && $::env(SYNTH_EXPLORE) } {
+ design -save myDesign
+
+ for { set index 0 } { $index < [llength $all_scripts] } { incr index } {
+ log "\[INFO\]: ABC: WireLoad : S_$index"
+ design -load myDesign
+
+ abc -D $clock_period \
+ -constr "$sdc_file" \
+ -liberty $sclib \
+ -script [lindex $all_scripts $index]
+
+ setundef -zero
+
+ hilomap -hicell {*}$::env(SYNTH_TIEHI_PORT) -locell {*}$::env(SYNTH_TIELO_PORT)
+
+ # get rid of the assignments that make verilog2def fail
+ splitnets
+ opt_clean -purge
+ insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT)
+
+ tee -o "$::env(yosys_report_file_tag)_$index$chk_ext" check
+ write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(yosys_result_file_tag)_$index.v"
+ design -reset
+ }
+} else {
+
+ log "\[INFO\]: ABC: WireLoad : S_$strategy"
+
+ abc -D $clock_period \
+ -constr "$sdc_file" \
+ -liberty $sclib \
+ -script [lindex $all_scripts $strategy] \
+ -showtmp;
+
+ setundef -zero
+
+ hilomap -hicell {*}$::env(SYNTH_TIEHI_PORT) -locell {*}$::env(SYNTH_TIELO_PORT)
+
+ # get rid of the assignments that make verilog2def fail
+ splitnets
+ opt_clean -purge
+ insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT)
+
+ tee -o "$::env(yosys_report_file_tag)_$strategy$chk_ext" check
+ write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(SAVE_NETLIST)"
+}
+
+if { $::env(SYNTH_NO_FLAT) } {
+ design -reset
+ file copy -force $::env(SAVE_NETLIST) $::env(yosys_tmp_file_tag)_unflat.v
+ read_verilog -sv $::env(SAVE_NETLIST)
+ synth -top $vtop -flatten
+ splitnets
+ opt_clean -purge
+ insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT)
+ write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(SAVE_NETLIST)"
+ tee -o "$::env(yosys_report_file_tag)_$strategy$chk_ext" check
+}
diff --git a/verilog/rtl/digital_core/filelist_rtl.f b/verilog/rtl/digital_core/filelist_rtl.f
new file mode 100755
index 0000000..3bb3d95
--- /dev/null
+++ b/verilog/rtl/digital_core/filelist_rtl.f
@@ -0,0 +1,75 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+// //////////////////////////////////////////////////////////////////////////
++incdir+../sdram_ctrl/src/defs
++incdir+../syntacore/scr1/src/includes
+
+../spi_master/src/spim_top.sv
+../spi_master/src/spim_regs.sv
+../spi_master/src/spim_clkgen.sv
+../spi_master/src/spim_ctrl.sv
+../spi_master/src/spim_rx.sv
+../spi_master/src/spim_tx.sv
+
+../sdram_ctrl/src/top/sdrc_top.v
+../sdram_ctrl/src/wb2sdrc/wb2sdrc.v
+../lib/async_fifo.sv
+../sdram_ctrl/src/core/sdrc_core.v
+../sdram_ctrl/src/core/sdrc_bank_ctl.v
+../sdram_ctrl/src/core/sdrc_bank_fsm.v
+../sdram_ctrl/src/core/sdrc_bs_convert.v
+../sdram_ctrl/src/core/sdrc_req_gen.v
+../sdram_ctrl/src/core/sdrc_xfr_ctl.v
+
+../lib/wb_crossbar.v
+../lib/registers.v
+../lib/clk_ctl.v
+./src/glbl_cfg.sv
+./src/digital_core.sv
+
+
+../syntacore/scr1/src/core/pipeline/scr1_pipe_hdu.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_tdu.sv
+../syntacore/scr1/src/core/pipeline/scr1_ipic.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_csr.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_exu.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_ialu.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_idu.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_ifu.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_lsu.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_mprf.sv
+../syntacore/scr1/src/core/pipeline/scr1_pipe_top.sv
+../syntacore/scr1/src/core/primitives/scr1_reset_cells.sv
+../syntacore/scr1/src/core/primitives/scr1_cg.sv
+../syntacore/scr1/src/core/scr1_clk_ctrl.sv
+../syntacore/scr1/src/core/scr1_tapc_shift_reg.sv
+../syntacore/scr1/src/core/scr1_tapc.sv
+../syntacore/scr1/src/core/scr1_tapc_synchronizer.sv
+../syntacore/scr1/src/core/scr1_core_top.sv
+../syntacore/scr1/src/core/scr1_dm.sv
+../syntacore/scr1/src/core/scr1_dmi.sv
+../syntacore/scr1/src/core/scr1_scu.sv
+
+../syntacore/scr1/src/top/scr1_dmem_router.sv
+../syntacore/scr1/src/top/scr1_dp_memory.sv
+../syntacore/scr1/src/top/scr1_tcm.sv
+../syntacore/scr1/src/top/scr1_timer.sv
+../syntacore/scr1/src/top/scr1_dmem_wb.sv
+../syntacore/scr1/src/top/scr1_imem_wb.sv
+../syntacore/scr1/src/top/scr1_top_wb.sv
+../lib/sync_fifo.sv
+
diff --git a/verilog/rtl/digital_core/run_modelsim b/verilog/rtl/digital_core/run_modelsim
new file mode 100755
index 0000000..2b56b12
--- /dev/null
+++ b/verilog/rtl/digital_core/run_modelsim
@@ -0,0 +1,21 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // 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>
+# // //////////////////////////////////////////////////////////////////////////
+
+vlib work
+vlog -f filelist_rtl.f
+vsim -c digital_core -suppress vsim-3999 -do "exit"
diff --git a/verilog/rtl/digital_core/src/digital_core.sv b/verilog/rtl/digital_core/src/digital_core.sv
new file mode 100644
index 0000000..2eb4b27
--- /dev/null
+++ b/verilog/rtl/digital_core/src/digital_core.sv
@@ -0,0 +1,805 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Digital core ////
+//// ////
+//// 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 digital core and integrate all the main block ////
+//// here. Following block are integrated here ////
+//// 1. Risc V Core ////
+//// 2. SPI Master ////
+//// 3. Wishbone Cross Bar ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 16th Feb 2021, Dinesh A ////
+//// Initial integration with Risc-V core + ////
+//// Wishbone Cross Bar + SPI Master ////
+//// 0.2 - 17th June 2021, Dinesh A ////
+//// 1. In risc core, wishbone and core domain is ////
+//// created ////
+//// 2. cpu and rtc clock are generated in glbl reg block ////
+//// 3. in wishbone interconnect:- Stagging flop are added ////
+//// at interface to break wishbone timing path ////
+//// 4. buswidth warning are fixed inside spi_master ////
+//// modified rtl files are ////
+//// verilog/rtl/digital_core/src/digital_core.sv ////
+//// verilog/rtl/digital_core/src/glbl_cfg.sv ////
+//// verilog/rtl/lib/wb_stagging.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_dmem_wb.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_imem_wb.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_top_wb.sv ////
+//// verilog/rtl/user_project_wrapper.v ////
+//// verilog/rtl/wb_interconnect/src/wb_interconnect.sv ////
+//// verilog/rtl/spi_master/src/spim_clkgen.sv ////
+//// verilog/rtl/spi_master/src/spim_ctrl.sv ////
+//// 0.3 - 20th June 2021, Dinesh A ////
+//// 1. uart core is integrated ////
+//// 2. 3rd Slave ported added to wishbone interconnect ////
+//// 0.4 - 25th June 2021, Dinesh A ////
+//// Moved the pad logic inside sdram,spi,uart block to ////
+//// avoid logic at digital core level ////
+//// 0.5 - 25th June 2021, Dinesh A ////
+//// Since carvel gives only 16MB address space for user ////
+//// space, we have implemented indirect address select ////
+//// with 8 bit bank select given inside wb_host ////
+//// core Address = {Bank_Sel[7:0], Wb_Address[23:0] ////
+//// caravel user address space is ////
+//// 0x3000_0000 to 0x30FF_FFFF ////
+//// 0.6 - 27th June 2021, Dinesh A ////
+//// Digital core level tie are moved inside IP to avoid ////
+//// power hook up at core level ////
+//// u_risc_top - test_mode & test_rst_n ////
+//// u_intercon - s*_wbd_err_i ////
+//// unused wb_cti_i is removed from u_sdram_ctrl ////
+//// 0.7 - 28th June 2021, Dinesh A ////
+//// wb_interconnect master port are interchanged for ////
+//// better physical placement. ////
+//// m0 - External HOST ////
+//// m1 - RISC IMEM ////
+//// m2 - RISC DMEM ////
+//// 0.8 - 6th July 2021, Dinesh A ////
+//// For Better SDRAM Interface timing we have taping ////
+//// sdram_clock goint to io_out[29] directly from ////
+//// global register block, this help in better SDRAM ////
+//// interface timing control ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module digital_core (
+`ifdef USE_POWER_PINS
+ inout vdda1, // User area 1 3.3V supply
+ inout vdda2, // User area 2 3.3V supply
+ inout vssa1, // User area 1 analog ground
+ inout vssa2, // User area 2 analog ground
+ inout vccd1, // User area 1 1.8V supply
+ inout vccd2, // User area 2 1.8v supply
+ inout vssd1, // User area 1 digital ground
+ inout vssd2, // User area 2 digital ground
+`endif
+ input wire wb_clk_i , // System clock
+ input wire user_clock2 , // user Clock
+ input wire wb_rst_i , // Regular Reset signal
+
+ input wire wbs_cyc_i , // strobe/request
+ input wire wbs_stb_i , // strobe/request
+ input wire [WB_WIDTH-1:0] wbs_adr_i , // address
+ input wire wbs_we_i , // write
+ input wire [WB_WIDTH-1:0] wbs_dat_i , // data output
+ input wire [3:0] wbs_sel_i , // byte enable
+ output wire [WB_WIDTH-1:0] wbs_dat_o , // data input
+ output wire wbs_ack_o , // acknowlegement
+
+ // Analog (direct connection to GPIO pad---use with caution)
+ // Note that analog I/O is not available on the 7 lowest-numbered
+ // GPIO pads, and so the analog_io indexing is offset from the
+ // GPIO indexing by 7 (also upper 2 GPIOs do not have analog_io).
+ inout [`MPRJ_IO_PADS-10:0] analog_io,
+
+ // Logic Analyzer Signals
+ input wire [127:0] la_data_in ,
+ output wire [127:0] la_data_out ,
+ input wire [127:0] la_oenb ,
+
+
+ // IOs
+ input wire [37:0] io_in ,
+ output wire [37:0] io_out ,
+ output wire [37:0] io_oeb ,
+
+ output wire [2:0] user_irq
+
+);
+
+//---------------------------------------------------
+// Local Parameter Declaration
+// --------------------------------------------------
+
+parameter SDR_DW = 8; // SDR Data Width
+parameter SDR_BW = 1; // SDR Byte Width
+parameter WB_WIDTH = 32; // WB ADDRESS/DARA WIDTH
+
+//---------------------------------------------------------------------
+// Wishbone Risc V Instruction Memory Interface
+//---------------------------------------------------------------------
+wire wbd_riscv_imem_stb_i; // strobe/request
+wire [WB_WIDTH-1:0] wbd_riscv_imem_adr_i; // address
+wire wbd_riscv_imem_we_i; // write
+wire [WB_WIDTH-1:0] wbd_riscv_imem_dat_i; // data output
+wire [3:0] wbd_riscv_imem_sel_i; // byte enable
+wire [WB_WIDTH-1:0] wbd_riscv_imem_dat_o; // data input
+wire wbd_riscv_imem_ack_o; // acknowlegement
+wire wbd_riscv_imem_err_o; // error
+
+//---------------------------------------------------------------------
+// RISC V Wishbone Data Memory Interface
+//---------------------------------------------------------------------
+wire wbd_riscv_dmem_stb_i; // strobe/request
+wire [WB_WIDTH-1:0] wbd_riscv_dmem_adr_i; // address
+wire wbd_riscv_dmem_we_i; // write
+wire [WB_WIDTH-1:0] wbd_riscv_dmem_dat_i; // data output
+wire [3:0] wbd_riscv_dmem_sel_i; // byte enable
+wire [WB_WIDTH-1:0] wbd_riscv_dmem_dat_o; // data input
+wire wbd_riscv_dmem_ack_o; // acknowlegement
+wire wbd_riscv_dmem_err_o; // error
+
+//---------------------------------------------------------------------
+// WB HOST Interface
+//---------------------------------------------------------------------
+wire wbd_int_cyc_i; // strobe/request
+wire wbd_int_stb_i; // strobe/request
+wire [WB_WIDTH-1:0] wbd_int_adr_i; // address
+wire wbd_int_we_i; // write
+wire [WB_WIDTH-1:0] wbd_int_dat_i; // data output
+wire [3:0] wbd_int_sel_i; // byte enable
+wire [WB_WIDTH-1:0] wbd_int_dat_o; // data input
+wire wbd_int_ack_o; // acknowlegement
+wire wbd_int_err_o; // error
+//---------------------------------------------------------------------
+// SPI Master Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_spim_stb_o; // strobe/request
+wire [WB_WIDTH-1:0] wbd_spim_adr_o; // address
+wire wbd_spim_we_o; // write
+wire [WB_WIDTH-1:0] wbd_spim_dat_o; // data output
+wire [3:0] wbd_spim_sel_o; // byte enable
+wire wbd_spim_cyc_o ;
+wire [WB_WIDTH-1:0] wbd_spim_dat_i; // data input
+wire wbd_spim_ack_i; // acknowlegement
+wire wbd_spim_err_i; // error
+
+//---------------------------------------------------------------------
+// SPI Master Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_sdram_stb_o ;
+wire [WB_WIDTH-1:0] wbd_sdram_adr_o ;
+wire wbd_sdram_we_o ; // 1 - Write, 0 - Read
+wire [WB_WIDTH-1:0] wbd_sdram_dat_o ;
+wire [WB_WIDTH/8-1:0] wbd_sdram_sel_o ; // Byte enable
+wire wbd_sdram_cyc_o ;
+wire [2:0] wbd_sdram_cti_o ;
+wire [WB_WIDTH-1:0] wbd_sdram_dat_i ;
+wire wbd_sdram_ack_i ;
+
+//---------------------------------------------------------------------
+// Global Register Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_glbl_stb_o; // strobe/request
+wire [7:0] wbd_glbl_adr_o; // address
+wire wbd_glbl_we_o; // write
+wire [WB_WIDTH-1:0] wbd_glbl_dat_o; // data output
+wire [3:0] wbd_glbl_sel_o; // byte enable
+wire wbd_glbl_cyc_o ;
+wire [WB_WIDTH-1:0] wbd_glbl_dat_i; // data input
+wire wbd_glbl_ack_i; // acknowlegement
+wire wbd_glbl_err_i; // error
+
+//---------------------------------------------------------------------
+// Global Register Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_uart_stb_o; // strobe/request
+wire [7:0] wbd_uart_adr_o; // address
+wire wbd_uart_we_o; // write
+wire [7:0] wbd_uart_dat_o; // data output
+wire wbd_uart_sel_o; // byte enable
+wire wbd_uart_cyc_o ;
+wire [7:0] wbd_uart_dat_i; // data input
+wire wbd_uart_ack_i; // acknowlegement
+wire wbd_uart_err_i; // error
+
+//----------------------------------------------------
+// CPU Configuration
+//----------------------------------------------------
+wire cpu_rst_n ;
+wire spi_rst_n ;
+wire sdram_rst_n ;
+wire sdram_clk ;
+wire cpu_clk ;
+wire rtc_clk ;
+wire wbd_clk_int ;
+wire wbd_int_rst_n ;
+
+wire [31:0] fuse_mhartid ;
+wire [15:0] irq_lines ;
+wire soft_irq ;
+
+wire [7:0] cfg_glb_ctrl ;
+wire [31:0] cfg_clk_ctrl1 ;
+wire [31:0] cfg_clk_ctrl2 ;
+wire [3:0] cfg_cska_wi ; // clock skew adjust for wishbone interconnect
+wire [3:0] cfg_cska_riscv; // clock skew adjust for riscv
+wire [3:0] cfg_cska_uart ; // clock skew adjust for uart
+wire [3:0] cfg_cska_spi ; // clock skew adjust for spi
+wire [3:0] cfg_cska_sdram; // clock skew adjust for sdram
+wire [3:0] cfg_cska_glbl ; // clock skew adjust for global reg
+wire [3:0] cfg_cska_wh ; // clock skew adjust for web host
+
+
+wire wbd_clk_wi ; // clock for wishbone interconnect
+wire wbd_clk_riscv ; // clock for riscv
+wire wbd_clk_uart ; // clock for uart
+wire wbd_clk_spi ; // clock for spi
+wire wbd_clk_sdram ; // clock for sdram
+wire wbd_clk_glbl ; // clock for global reg
+wire wbd_clk_wh ; // clock for global reg
+
+wire [3:0] cfg_cska_sd_co; // clock skew adjust for sdram clock out
+wire [3:0] cfg_cska_sd_ci; // clock skew adjust for sdram clock input
+wire [3:0] cfg_cska_sp_co; // clock skew adjust for SPI clock out
+
+wire io_out_29_ ; // Internally tapped SDRAM clock
+wire io_in_29_ ; // Clock Skewed Pad SDRAM clock
+wire io_in_30_ ; // SPI clock out
+
+//------------------------------------------------
+// Configuration Parameter
+//------------------------------------------------
+wire [1:0] cfg_sdr_width ; // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit
+wire [1:0] cfg_colbits ; // 2'b00 - 8 Bit column address,
+wire sdr_init_done ; // Indicate SDRAM Initialisation Done
+wire [3:0] cfg_sdr_tras_d ; // Active to precharge delay
+wire [3:0] cfg_sdr_trp_d ; // Precharge to active delay
+wire [3:0] cfg_sdr_trcd_d ; // Active to R/W delay
+wire cfg_sdr_en ; // Enable SDRAM controller
+wire [1:0] cfg_req_depth ; // Maximum Request accepted by SDRAM controller
+wire [12:0] cfg_sdr_mode_reg ;
+wire [2:0] cfg_sdr_cas ; // SDRAM CAS Latency
+wire [3:0] cfg_sdr_trcar_d ; // Auto-refresh period
+wire [3:0] cfg_sdr_twr_d ; // Write recovery delay
+wire [11: 0] cfg_sdr_rfsh ;
+wire [2 : 0] cfg_sdr_rfmax ;
+
+
+
+
+
+/////////////////////////////////////////////////////////
+// Generating acive low wishbone reset
+// //////////////////////////////////////////////////////
+assign wbd_int_rst_n = cfg_glb_ctrl[0];
+assign cpu_rst_n = cfg_glb_ctrl[1];
+assign spi_rst_n = cfg_glb_ctrl[2];
+assign sdram_rst_n = cfg_glb_ctrl[3];
+
+assign cfg_cska_wi = cfg_clk_ctrl1[3:0];
+assign cfg_cska_riscv = cfg_clk_ctrl1[7:4];
+assign cfg_cska_uart = cfg_clk_ctrl1[11:8];
+assign cfg_cska_spi = cfg_clk_ctrl1[15:12];
+assign cfg_cska_sdram = cfg_clk_ctrl1[19:16];
+assign cfg_cska_glbl = cfg_clk_ctrl1[23:20];
+assign cfg_cska_wh = cfg_clk_ctrl1[27:24];
+
+assign cfg_cska_sd_co = cfg_clk_ctrl2[3:0]; // SDRAM clock out control
+assign cfg_cska_sd_ci = cfg_clk_ctrl2[7:4]; // SDRAM clock in control
+assign cfg_cska_sp_co = cfg_clk_ctrl2[11:8];// SPI clock out control
+
+
+wb_host u_wb_host(
+
+ // Master Port
+ .wbm_rst_i (wb_rst_i ),
+ .wbm_clk_i (wb_clk_i ),
+ .wbm_cyc_i (wbs_cyc_i ),
+ .wbm_stb_i (wbs_stb_i ),
+ .wbm_adr_i (wbs_adr_i ),
+ .wbm_we_i (wbs_we_i ),
+ .wbm_dat_i (wbs_dat_i ),
+ .wbm_sel_i (wbs_sel_i ),
+ .wbm_dat_o (wbs_dat_o ),
+ .wbm_ack_o (wbs_ack_o ),
+ .wbm_err_o ( ),
+
+ // Slave Port
+ .wbs_clk_out (wbd_clk_int ),
+ .wbs_clk_i (wbd_clk_wh ),
+ .wbs_cyc_o (wbd_int_cyc_i ),
+ .wbs_stb_o (wbd_int_stb_i ),
+ .wbs_adr_o (wbd_int_adr_i ),
+ .wbs_we_o (wbd_int_we_i ),
+ .wbs_dat_o (wbd_int_dat_i ),
+ .wbs_sel_o (wbd_int_sel_i ),
+ .wbs_dat_i (wbd_int_dat_o ),
+ .wbs_ack_i (wbd_int_ack_o ),
+ .wbs_err_i (wbd_int_err_o ),
+
+ .cfg_glb_ctrl (cfg_glb_ctrl ),
+ .cfg_clk_ctrl1 (cfg_clk_ctrl1 ),
+ .cfg_clk_ctrl2 (cfg_clk_ctrl2 ),
+
+ // Logic Analyzer Signals
+ .la_data_in (la_data_in ),
+ .la_data_out (la_data_out ),
+ .la_oenb (la_oenb )
+ );
+
+
+
+
+//------------------------------------------------------------------------------
+// RISC V Core instance
+//------------------------------------------------------------------------------
+scr1_top_wb u_riscv_top (
+ // Reset
+ .pwrup_rst_n (wbd_int_rst_n ),
+ .rst_n (wbd_int_rst_n ),
+ .cpu_rst_n (cpu_rst_n ),
+
+ // Clock
+ .core_clk (cpu_clk ),
+ .rtc_clk (rtc_clk ),
+
+ // Fuses
+ .fuse_mhartid (fuse_mhartid ),
+
+ // IRQ
+ .irq_lines (irq_lines ),
+ .soft_irq (soft_irq ), // TODO - Interrupts
+
+ // DFT
+ // .test_mode (1'b0 ), // Moved inside IP
+ // .test_rst_n (1'b1 ), // Moved inside IP
+
+
+ .wb_rst_n (wbd_int_rst_n ),
+ .wb_clk (wbd_clk_riscv ),
+ // Instruction memory interface
+ .wbd_imem_stb_o (wbd_riscv_imem_stb_i ),
+ .wbd_imem_adr_o (wbd_riscv_imem_adr_i ),
+ .wbd_imem_we_o (wbd_riscv_imem_we_i ),
+ .wbd_imem_dat_o (wbd_riscv_imem_dat_i ),
+ .wbd_imem_sel_o (wbd_riscv_imem_sel_i ),
+ .wbd_imem_dat_i (wbd_riscv_imem_dat_o ),
+ .wbd_imem_ack_i (wbd_riscv_imem_ack_o ),
+ .wbd_imem_err_i (wbd_riscv_imem_err_o ),
+
+ // Data memory interface
+ .wbd_dmem_stb_o (wbd_riscv_dmem_stb_i ),
+ .wbd_dmem_adr_o (wbd_riscv_dmem_adr_i ),
+ .wbd_dmem_we_o (wbd_riscv_dmem_we_i ),
+ .wbd_dmem_dat_o (wbd_riscv_dmem_dat_i ),
+ .wbd_dmem_sel_o (wbd_riscv_dmem_sel_i ),
+ .wbd_dmem_dat_i (wbd_riscv_dmem_dat_o ),
+ .wbd_dmem_ack_i (wbd_riscv_dmem_ack_o ),
+ .wbd_dmem_err_i (wbd_riscv_dmem_err_o )
+);
+
+/*********************************************************
+* SPI Master
+* This is an implementation of an SPI master that is controlled via an AXI bus.
+* It has FIFOs for transmitting and receiving data.
+* It supports both the normal SPI mode and QPI mode with 4 data lines.
+* *******************************************************/
+
+spim_top
+#(
+`ifndef SYNTHESIS
+ .WB_WIDTH (WB_WIDTH)
+`endif
+) u_spi_master
+(
+ .mclk (wbd_clk_spi ),
+ .rst_n (spi_rst_n ),
+
+ .wbd_stb_i (wbd_spim_stb_o ),
+ .wbd_adr_i (wbd_spim_adr_o ),
+ .wbd_we_i (wbd_spim_we_o ),
+ .wbd_dat_i (wbd_spim_dat_o ),
+ .wbd_sel_i (wbd_spim_sel_o ),
+ .wbd_dat_o (wbd_spim_dat_i ),
+ .wbd_ack_o (wbd_spim_ack_i ),
+ .wbd_err_o (wbd_spim_err_i ),
+
+ .spi_debug (spi_debug ),
+
+ // Pad Interface
+ .io_in (io_in[35:30] ),
+ .io_out ({io_out[35:31],io_in_30_} ),
+ .io_oeb (io_oeb[35:30] )
+
+);
+
+
+sdrc_top
+ `ifndef SYNTHESIS
+ #(.APP_AW(WB_WIDTH),
+ .APP_DW(WB_WIDTH),
+ .APP_BW(4),
+ .SDR_DW(8),
+ .SDR_BW(1))
+ `endif
+ u_sdram_ctrl (
+ .cfg_sdr_width (cfg_sdr_width ),
+ .cfg_colbits (cfg_colbits ),
+
+ // WB bus
+ .wb_rst_n (wbd_int_rst_n ),
+ .wb_clk_i (wbd_clk_sdram ),
+
+ .wb_stb_i (wbd_sdram_stb_o ),
+ .wb_addr_i (wbd_sdram_adr_o ),
+ .wb_we_i (wbd_sdram_we_o ),
+ .wb_dat_i (wbd_sdram_dat_o ),
+ .wb_sel_i (wbd_sdram_sel_o ),
+ .wb_cyc_i (wbd_sdram_cyc_o ),
+ .wb_ack_o (wbd_sdram_ack_i ),
+ .wb_dat_o (wbd_sdram_dat_i ),
+
+
+ /* Interface to SDRAMs */
+ .sdram_clk (sdram_clk ),
+ .sdram_resetn (sdram_rst_n ),
+
+ /** Pad Interface **/
+ .io_in ({io_in_29_,io_in[28:0]} ),
+ .io_oeb (io_oeb[29:0] ),
+ .io_out ({io_out_29_,io_out[28:0]} ),
+
+ /* Parameters */
+ .sdr_init_done (sdr_init_done ),
+ .cfg_req_depth (cfg_req_depth ), //how many req. buffer should hold
+ .cfg_sdr_en (cfg_sdr_en ),
+ .cfg_sdr_mode_reg (cfg_sdr_mode_reg ),
+ .cfg_sdr_tras_d (cfg_sdr_tras_d ),
+ .cfg_sdr_trp_d (cfg_sdr_trp_d ),
+ .cfg_sdr_trcd_d (cfg_sdr_trcd_d ),
+ .cfg_sdr_cas (cfg_sdr_cas ),
+ .cfg_sdr_trcar_d (cfg_sdr_trcar_d ),
+ .cfg_sdr_twr_d (cfg_sdr_twr_d ),
+ .cfg_sdr_rfsh (cfg_sdr_rfsh ),
+ .cfg_sdr_rfmax (cfg_sdr_rfmax )
+ );
+
+
+wb_interconnect u_intercon (
+ .clk_i (wbd_clk_wi ),
+ .rst_n (wbd_int_rst_n ),
+
+ // Master 0 Interface
+ .m0_wbd_dat_i (wbd_int_dat_i ),
+ .m0_wbd_adr_i (wbd_int_adr_i ),
+ .m0_wbd_sel_i (wbd_int_sel_i ),
+ .m0_wbd_we_i (wbd_int_we_i ),
+ .m0_wbd_cyc_i (wbd_int_cyc_i ),
+ .m0_wbd_stb_i (wbd_int_stb_i ),
+ .m0_wbd_dat_o (wbd_int_dat_o ),
+ .m0_wbd_ack_o (wbd_int_ack_o ),
+ .m0_wbd_err_o (wbd_int_err_o ),
+
+ // Master 0 Interface
+ .m1_wbd_dat_i (wbd_riscv_imem_dat_i ),
+ .m1_wbd_adr_i (wbd_riscv_imem_adr_i ),
+ .m1_wbd_sel_i (wbd_riscv_imem_sel_i ),
+ .m1_wbd_we_i (wbd_riscv_imem_we_i ),
+ .m1_wbd_cyc_i (wbd_riscv_imem_stb_i ),
+ .m1_wbd_stb_i (wbd_riscv_imem_stb_i ),
+ .m1_wbd_dat_o (wbd_riscv_imem_dat_o ),
+ .m1_wbd_ack_o (wbd_riscv_imem_ack_o ),
+ .m1_wbd_err_o (wbd_riscv_imem_err_o ),
+
+ // Master 1 Interface
+ .m2_wbd_dat_i (wbd_riscv_dmem_dat_i ),
+ .m2_wbd_adr_i (wbd_riscv_dmem_adr_i ),
+ .m2_wbd_sel_i (wbd_riscv_dmem_sel_i ),
+ .m2_wbd_we_i (wbd_riscv_dmem_we_i ),
+ .m2_wbd_cyc_i (wbd_riscv_dmem_stb_i ),
+ .m2_wbd_stb_i (wbd_riscv_dmem_stb_i ),
+ .m2_wbd_dat_o (wbd_riscv_dmem_dat_o ),
+ .m2_wbd_ack_o (wbd_riscv_dmem_ack_o ),
+ .m2_wbd_err_o (wbd_riscv_dmem_err_o ),
+
+
+ // Slave 0 Interface
+ // .s0_wbd_err_i (1'b0 ), - Moved inside IP
+ .s0_wbd_dat_i (wbd_spim_dat_i ),
+ .s0_wbd_ack_i (wbd_spim_ack_i ),
+ .s0_wbd_dat_o (wbd_spim_dat_o ),
+ .s0_wbd_adr_o (wbd_spim_adr_o ),
+ .s0_wbd_sel_o (wbd_spim_sel_o ),
+ .s0_wbd_we_o (wbd_spim_we_o ),
+ .s0_wbd_cyc_o (wbd_spim_cyc_o ),
+ .s0_wbd_stb_o (wbd_spim_stb_o ),
+
+ // Slave 1 Interface
+ // .s1_wbd_err_i (1'b0 ), - Moved inside IP
+ .s1_wbd_dat_i (wbd_sdram_dat_i ),
+ .s1_wbd_ack_i (wbd_sdram_ack_i ),
+ .s1_wbd_dat_o (wbd_sdram_dat_o ),
+ .s1_wbd_adr_o (wbd_sdram_adr_o ),
+ .s1_wbd_sel_o (wbd_sdram_sel_o ),
+ .s1_wbd_we_o (wbd_sdram_we_o ),
+ .s1_wbd_cyc_o (wbd_sdram_cyc_o ),
+ .s1_wbd_stb_o (wbd_sdram_stb_o ),
+
+ // Slave 2 Interface
+ // .s2_wbd_err_i (1'b0 ), - Moved inside IP
+ .s2_wbd_dat_i (wbd_glbl_dat_i ),
+ .s2_wbd_ack_i (wbd_glbl_ack_i ),
+ .s2_wbd_dat_o (wbd_glbl_dat_o ),
+ .s2_wbd_adr_o (wbd_glbl_adr_o ),
+ .s2_wbd_sel_o (wbd_glbl_sel_o ),
+ .s2_wbd_we_o (wbd_glbl_we_o ),
+ .s2_wbd_cyc_o (wbd_glbl_cyc_o ),
+ .s2_wbd_stb_o (wbd_glbl_stb_o ),
+
+ // Slave 3 Interface
+ // .s3_wbd_err_i (1'b0 ), - Moved inside IP
+ .s3_wbd_dat_i (wbd_uart_dat_i ),
+ .s3_wbd_ack_i (wbd_uart_ack_i ),
+ .s3_wbd_dat_o (wbd_uart_dat_o ),
+ .s3_wbd_adr_o (wbd_uart_adr_o ),
+ .s3_wbd_sel_o (wbd_uart_sel_o ),
+ .s3_wbd_we_o (wbd_uart_we_o ),
+ .s3_wbd_cyc_o (wbd_uart_cyc_o ),
+ .s3_wbd_stb_o (wbd_uart_stb_o )
+ );
+
+glbl_cfg u_glbl_cfg (
+
+ .mclk (wbd_clk_glbl ),
+ .reset_n (wbd_int_rst_n ),
+ .user_clock1 (wb_clk_i ),
+ .user_clock2 (user_clock2 ),
+ .device_idcode ( ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (wbd_glbl_stb_o ),
+ .reg_wr (wbd_glbl_we_o ),
+ .reg_addr (wbd_glbl_adr_o ),
+ .reg_wdata (wbd_glbl_dat_o ),
+ .reg_be (wbd_glbl_sel_o ),
+
+ // Outputs
+ .reg_rdata (wbd_glbl_dat_i ),
+ .reg_ack (wbd_glbl_ack_i ),
+
+ // SDRAM Clock
+
+ .sdram_clk (sdram_clk ),
+ .cpu_clk (cpu_clk ),
+ .rtc_clk (rtc_clk ),
+
+ // Risc configuration
+ .fuse_mhartid (fuse_mhartid ),
+ .irq_lines (irq_lines ),
+ .soft_irq (soft_irq ),
+ .user_irq (user_irq ),
+
+ // SDRAM Config
+ .cfg_sdr_width (cfg_sdr_width ),
+ .cfg_colbits (cfg_colbits ),
+
+ /* Parameters */
+ .sdr_init_done (sdr_init_done ),
+ .cfg_req_depth (cfg_req_depth ), //how many req. buffer should hold
+ .cfg_sdr_en (cfg_sdr_en ),
+ .cfg_sdr_mode_reg (cfg_sdr_mode_reg ),
+ .cfg_sdr_tras_d (cfg_sdr_tras_d ),
+ .cfg_sdr_trp_d (cfg_sdr_trp_d ),
+ .cfg_sdr_trcd_d (cfg_sdr_trcd_d ),
+ .cfg_sdr_cas (cfg_sdr_cas ),
+ .cfg_sdr_trcar_d (cfg_sdr_trcar_d ),
+ .cfg_sdr_twr_d (cfg_sdr_twr_d ),
+ .cfg_sdr_rfsh (cfg_sdr_rfsh ),
+ .cfg_sdr_rfmax (cfg_sdr_rfmax )
+
+
+ );
+
+uart_core u_uart_core (
+ .arst_n (wbd_int_rst_n ), // async reset
+ .app_clk (wbd_clk_uart ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (wbd_uart_stb_o ),
+ .reg_wr (wbd_uart_we_o ),
+ .reg_addr (wbd_uart_adr_o[5:2] ),
+ .reg_wdata (wbd_uart_dat_o[7:0] ),
+ .reg_be (wbd_uart_sel_o ),
+
+ // Outputs
+ .reg_rdata (wbd_uart_dat_i[7:0] ),
+ .reg_ack (wbd_uart_ack_i ),
+
+ // Pad interface
+ .io_in (io_in [37:36] ),
+ .io_oeb (io_oeb[37:36] ),
+ .io_out (io_out[37:36] )
+
+ );
+
+////////////////////////////////////////////////////////////////
+// Clock Skew adjust module
+// ///////////////////////////////////////////////////////////
+
+// Wishbone interconnect clock skew control
+clk_skew_adjust u_skew_wi
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_wi ),
+ .clk_out (wbd_clk_wi )
+ );
+
+// riscv clock skew control
+clk_skew_adjust u_skew_riscv
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_riscv ),
+ .clk_out (wbd_clk_riscv )
+ );
+
+// uart clock skew control
+clk_skew_adjust u_skew_uart
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_uart ),
+ .clk_out (wbd_clk_uart )
+ );
+
+// spi clock skew control
+clk_skew_adjust u_skew_spi
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_spi ),
+ .clk_out (wbd_clk_spi )
+ );
+
+// sdram clock skew control
+clk_skew_adjust u_skew_sdram
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_sdram ),
+ .clk_out (wbd_clk_sdram )
+ );
+
+// global clock skew control
+clk_skew_adjust u_skew_glbl
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_glbl ),
+ .clk_out (wbd_clk_glbl )
+ );
+
+// wb_host clock skew control
+clk_skew_adjust u_skew_wh
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_wh ),
+ .clk_out (wbd_clk_wh )
+ );
+
+// SDRAM clock out clock skew control
+clk_skew_adjust u_skew_sd_co
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (io_out_29_ ),
+ .sel (cfg_cska_sd_co ),
+ .clk_out (io_out[29] )
+ );
+
+// Clock Skey for PAD SDRAM clock
+clk_skew_adjust u_skew_sd_ci
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (sdram_clk ),
+ .sel (cfg_cska_sd_ci ),
+ .clk_out (io_in_29_ )
+ );
+
+// Clock Skey for SPI clock out
+clk_skew_adjust u_skew_sp_co
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (io_in_30_ ),
+ .sel (cfg_cska_sp_co ),
+ .clk_out (io_out[30] )
+ );
+
+endmodule : digital_core
diff --git a/verilog/rtl/digital_core/src/glbl_cfg.sv b/verilog/rtl/digital_core/src/glbl_cfg.sv
new file mode 100644
index 0000000..c852e19
--- /dev/null
+++ b/verilog/rtl/digital_core/src/glbl_cfg.sv
@@ -0,0 +1,1041 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Global confg register ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block generate all the global config and status ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 08 June 2021 Dinesh A ////
+//// Initial version ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module glbl_cfg (
+
+ input logic mclk,
+ input logic reset_n,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [7:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ // Risc configuration
+ output logic [31:0] fuse_mhartid,
+ output logic [15:0] irq_lines,
+ output logic soft_irq,
+ output logic [2:0] user_irq,
+
+ // SDRAM Config
+ input logic sdr_init_done , // Indicate SDRAM Initialisation Done
+ output logic [1:0] cfg_sdr_width , // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit
+ output logic [1:0] cfg_colbits , // 2'b00 - 8 Bit column address,
+ output logic [3:0] cfg_sdr_tras_d , // Active to precharge delay
+ output logic [3:0] cfg_sdr_trp_d , // Precharge to active delay
+ output logic [3:0] cfg_sdr_trcd_d , // Active to R/W delay
+ output logic cfg_sdr_en , // Enable SDRAM controller
+ output logic [1:0] cfg_req_depth , // Maximum Request accepted by SDRAM controller
+ output logic [12:0] cfg_sdr_mode_reg ,
+ output logic [2:0] cfg_sdr_cas , // SDRAM CAS Latency
+ output logic [3:0] cfg_sdr_trcar_d , // Auto-refresh period
+ output logic [3:0] cfg_sdr_twr_d , // Write recovery delay
+ output logic [11:0] cfg_sdr_rfsh ,
+ output logic [2:0] cfg_sdr_rfmax
+
+
+ );
+
+
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+logic sw_rd_en;
+logic sw_wr_en;
+logic [3:0] sw_addr ; // addressing 16 registers
+logic [3:0] wr_be ;
+logic [31:0] sw_reg_wdata;
+
+logic reg_cs_l ;
+logic reg_cs_2l ;
+
+
+logic [31:0] reg_0; // Software_Reg_0
+logic [31:0] reg_1; // Risc Fuse ID
+logic [31:0] reg_2; // Software-Reg_2
+logic [31:0] reg_3; // Interrup Control
+logic [31:0] reg_4; // SDRAM_CTRL1
+logic [31:0] reg_5; // SDRAM_CTRL2
+logic [31:0] reg_6; // Software-Reg_6
+logic [31:0] reg_7; // Software-Reg_7
+logic [31:0] reg_8; // Software-Reg_8
+logic [31:0] reg_9; // Software-Reg_9
+logic [31:0] reg_10; // Software-Reg_10
+logic [31:0] reg_11; // Software-Reg_11
+logic [31:0] reg_12; // Software-Reg_12
+logic [31:0] reg_13; // Software-Reg_13
+logic [31:0] reg_14; // Software-Reg_14
+logic [31:0] reg_15; // Software-Reg_15
+logic [31:0] reg_out;
+
+//-----------------------------------------------------------------------
+// Main code starts here
+//-----------------------------------------------------------------------
+
+//-----------------------------------------------------------------------
+// To avoid interface timing, all the content are registered
+//-----------------------------------------------------------------------
+always @ (posedge mclk or negedge reset_n)
+begin
+ if (reset_n == 1'b0)
+ begin
+ sw_addr <= '0;
+ sw_rd_en <= '0;
+ sw_wr_en <= '0;
+ sw_reg_wdata <= '0;
+ wr_be <= '0;
+ reg_cs_l <= '0;
+ reg_cs_2l <= '0;
+ end else begin
+ sw_addr <= reg_addr [5:2];
+ sw_rd_en <= reg_cs & !reg_wr;
+ sw_wr_en <= reg_cs & reg_wr;
+ sw_reg_wdata <= reg_wdata;
+ wr_be <= reg_be;
+ reg_cs_l <= reg_cs;
+ reg_cs_2l <= reg_cs_l;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// Read path mux
+//-----------------------------------------------------------------------
+
+always @ (posedge mclk or negedge reset_n)
+begin : preg_out_Seq
+ if (reset_n == 1'b0) begin
+ reg_rdata [31:0] <= 32'h0000_0000;
+ reg_ack <= 1'b0;
+ end else if (sw_rd_en && !reg_ack && !reg_cs_2l) begin
+ reg_rdata [31:0] <= reg_out [31:0];
+ reg_ack <= 1'b1;
+ end else if (sw_wr_en && !reg_ack && !reg_cs_2l) begin
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 4'h0);
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 4'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 4'h1);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 4'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 4'h2);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 4'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 4'h3);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 4'h3);
+wire sw_wr_en_4 = sw_wr_en & (sw_addr == 4'h4);
+wire sw_rd_en_4 = sw_rd_en & (sw_addr == 4'h4);
+wire sw_wr_en_5 = sw_wr_en & (sw_addr == 4'h5);
+wire sw_rd_en_5 = sw_rd_en & (sw_addr == 4'h5);
+wire sw_wr_en_6 = sw_wr_en & (sw_addr == 4'h6);
+wire sw_rd_en_6 = sw_rd_en & (sw_addr == 4'h6);
+wire sw_wr_en_7 = sw_wr_en & (sw_addr == 4'h7);
+wire sw_rd_en_7 = sw_rd_en & (sw_addr == 4'h7);
+wire sw_wr_en_8 = sw_wr_en & (sw_addr == 4'h8);
+wire sw_rd_en_8 = sw_rd_en & (sw_addr == 4'h8);
+wire sw_wr_en_9 = sw_wr_en & (sw_addr == 4'h9);
+wire sw_rd_en_9 = sw_rd_en & (sw_addr == 4'h9);
+wire sw_wr_en_10 = sw_wr_en & (sw_addr == 4'hA);
+wire sw_rd_en_10 = sw_rd_en & (sw_addr == 4'hA);
+wire sw_wr_en_11 = sw_wr_en & (sw_addr == 4'hB);
+wire sw_rd_en_11 = sw_rd_en & (sw_addr == 4'hB);
+wire sw_wr_en_12 = sw_wr_en & (sw_addr == 4'hC);
+wire sw_rd_en_12 = sw_rd_en & (sw_addr == 4'hC);
+wire sw_wr_en_13 = sw_wr_en & (sw_addr == 4'hD);
+wire sw_rd_en_13 = sw_rd_en & (sw_addr == 4'hD);
+wire sw_wr_en_14 = sw_wr_en & (sw_addr == 4'hE);
+wire sw_rd_en_14 = sw_rd_en & (sw_addr == 4'hE);
+wire sw_wr_en_15 = sw_wr_en & (sw_addr == 4'hF);
+wire sw_rd_en_15 = sw_rd_en & (sw_addr == 4'hF);
+
+
+always @( *)
+begin : preg_sel_Com
+
+ reg_out [31:0] = 32'd0;
+
+ case (sw_addr [3:0])
+ 4'b0000 : reg_out [31:0] = reg_0 [31:0];
+ 4'b0001 : reg_out [31:0] = reg_1 [31:0];
+ 4'b0010 : reg_out [31:0] = reg_2 [31:0];
+ 4'b0011 : reg_out [31:0] = reg_3 [31:0];
+ 4'b0100 : reg_out [31:0] = reg_4 [31:0];
+ 4'b0101 : reg_out [31:0] = reg_5 [31:0];
+ 4'b0110 : reg_out [31:0] = reg_6 [31:0];
+ 4'b0111 : reg_out [31:0] = reg_7 [31:0];
+ 4'b1000 : reg_out [31:0] = reg_8 [31:0];
+ 4'b1001 : reg_out [31:0] = reg_9 [31:0];
+ 4'b1010 : reg_out [31:0] = reg_10 [31:0];
+ 4'b1011 : reg_out [31:0] = reg_11 [31:0];
+ 4'b1100 : reg_out [31:0] = reg_12 [31:0];
+ 4'b1101 : reg_out [31:0] = reg_13 [31:0];
+ 4'b1110 : reg_out [31:0] = reg_14 [31:0];
+ 4'b1111 : reg_out [31:0] = reg_15 [31:0];
+ endcase
+end
+
+
+
+//-----------------------------------------------------------------------
+// Individual register assignments
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+// reg-0
+// -----------------------------------------------------------------
+
+
+
+generic_register #(8,8'hAA ) u_reg0_be0 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[7:0] )
+ );
+
+generic_register #(8,8'hBB ) u_reg0_be1 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[15:8] )
+ );
+generic_register #(8,8'hCC ) u_reg0_be2 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[23:16] )
+ );
+
+generic_register #(8,8'hDD ) u_reg0_be3 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[31:24] )
+ );
+
+
+
+//-----------------------------------------------------------------------
+// reg-1, reset value = 32'hA55A_A55A
+// -----------------------------------------------------------------
+
+assign fuse_mhartid = reg_1[31:0];
+generic_register #(.WD(8),.RESET_DEFAULT(8'h5A)) u_reg1_be0 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[7:0] )
+ );
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hA5) ) u_reg1_be1 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[15:8] )
+ );
+generic_register #(.WD(8),.RESET_DEFAULT(8'h5A) ) u_reg1_be2 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[23:16] )
+ );
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hA5) ) u_reg1_be3 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[31:24] )
+ );
+
+//-----------------------------------------------------------------------
+// reg-2, reset value = 32'hAABBCCDD
+//-----------------------------------------------------------------
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hDD) ) u_reg2_be0 (
+ .we ({8{sw_wr_en_2 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[7:0] )
+ );
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hCC) ) u_reg2_be1 (
+ .we ({8{sw_wr_en_2 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[15:8] )
+ );
+generic_register #(.WD(8),.RESET_DEFAULT(8'hBB) ) u_reg2_be2 (
+ .we ({8{sw_wr_en_2 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[23:16] )
+ );
+
+generic_register #(.WD(8),.RESET_DEFAULT(8'hAA) ) u_reg2_be3 (
+ .we ({8{sw_wr_en_2 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[31:24] )
+ );
+
+//-----------------------------------------------------------------------
+// reg-3
+//-----------------------------------------------------------------
+assign irq_lines = reg_3[15:0];
+assign soft_irq = reg_3[16];
+assign user_irq = reg_3[19:17];
+
+generic_register #(8,0 ) u_reg3_be0 (
+ .we ({8{sw_wr_en_3 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_3[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg3_be1 (
+ .we ({8{sw_wr_en_3 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_3[15:8] )
+ );
+generic_register #(4,0 ) u_reg3_be2 (
+ .we ({4{sw_wr_en_3 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[19:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_3[19:16] )
+ );
+
+assign reg_3[31:20] = '0;
+
+
+//-----------------------------------------------------------------------
+// reg-4
+// recommended Default value:
+// 1'b1,3'h3,2'h3,4'h1,4'h7',4'h2,4'h2,4'h6,2'b01,2'b10 = 32'h2F17_2266
+//-----------------------------------------------------------------
+assign cfg_sdr_width = reg_4[1:0] ; // 2'b10 // 2'b00 - 32 Bit SDR, 2'b01 - 16 Bit SDR, 2'b1x - 8 Bit
+assign cfg_colbits = reg_4[3:2] ; // 2'b00 8 Bit column address, 2'b01 - 9 Bit column address,
+assign cfg_sdr_tras_d = reg_4[7:4] ; // 4'h4 // Active to precharge delay
+assign cfg_sdr_trp_d = reg_4[11:8]; // 4'h2 // Precharge to active delay
+assign cfg_sdr_trcd_d = reg_4[15:12]; // 4'h2 // Active to R/W delay
+assign cfg_sdr_trcar_d = reg_4[19:16]; // 4'h7 // Auto-refresh period
+assign cfg_sdr_twr_d = reg_4[23:20]; // 4'h1 // Write recovery delay
+assign cfg_req_depth = reg_4[25:24]; // 2'h3 // Maximum Request accepted by SDRAM controller
+assign cfg_sdr_cas = reg_4[28:26]; // 3'h3 // SDRAM CAS Latency
+assign cfg_sdr_en = reg_4[29] ; // 1'b1 // Enable SDRAM controller
+assign reg_4[30] = sdr_init_done ; // Indicate SDRAM Initialisation Done
+assign reg_4[31] = 1'b0;
+
+
+generic_register #(8,0 ) u_reg4_be0 (
+ .we ({8{sw_wr_en_4 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg4_be1 (
+ .we ({8{sw_wr_en_4 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[15:8] )
+ );
+generic_register #(8,0 ) u_reg4_be2 (
+ .we ({8{sw_wr_en_4 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[23:16] )
+ );
+
+generic_register #(6,0 ) u_reg4_be3 (
+ .we ({6{sw_wr_en_4 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[29:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[29:24] )
+ );
+//-----------------------------------------------------------------------
+// reg-5, recomended default value {12'h100,13'h33,3'h6} = 32'h100_019E
+//-----------------------------------------------------------------
+assign cfg_sdr_rfmax = reg_5[2:0] ; // 3'h6
+assign cfg_sdr_mode_reg = reg_5[15:3] ; // 13'h033
+assign cfg_sdr_rfsh = reg_5[27:16]; // 12'h100
+
+generic_register #(8,0 ) u_reg5_be0 (
+ .we ({8{sw_wr_en_5 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_5[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg5_be1 (
+ .we ({8{sw_wr_en_5 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_5[15:8] )
+ );
+generic_register #(8,0 ) u_reg5_be2 (
+ .we ({8{sw_wr_en_5 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_5[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg5_be3 (
+ .we ({8{sw_wr_en_5 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_5[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 6
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg6_be0 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg6_be1 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[15:8] )
+ );
+generic_register #(8,0 ) u_reg6_be2 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg6_be3 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 7
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg7_be0 (
+ .we ({8{sw_wr_en_7 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_7[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg7_be1 (
+ .we ({8{sw_wr_en_7 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_7[15:8] )
+ );
+generic_register #(8,0 ) u_reg7_be2 (
+ .we ({8{sw_wr_en_7 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_7[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg7_be3 (
+ .we ({8{sw_wr_en_7 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_7[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 8
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg8_be0 (
+ .we ({8{sw_wr_en_8 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_8[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg8_be1 (
+ .we ({8{sw_wr_en_8 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_8[15:8] )
+ );
+generic_register #(8,0 ) u_reg8_be2 (
+ .we ({8{sw_wr_en_8 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_8[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg8_be3 (
+ .we ({8{sw_wr_en_8 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_8[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 9
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg9_be0 (
+ .we ({8{sw_wr_en_9 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_9[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg9_be1 (
+ .we ({8{sw_wr_en_9 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_9[15:8] )
+ );
+generic_register #(8,0 ) u_reg9_be2 (
+ .we ({8{sw_wr_en_9 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_9[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg9_be3 (
+ .we ({8{sw_wr_en_9 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_9[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 10
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg10_be0 (
+ .we ({8{sw_wr_en_10 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_10[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg10_be1 (
+ .we ({8{sw_wr_en_10 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_10[15:8] )
+ );
+generic_register #(8,0 ) u_reg10_be2 (
+ .we ({8{sw_wr_en_10 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_10[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg10_be3 (
+ .we ({8{sw_wr_en_10 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_10[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 11
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg11_be0 (
+ .we ({8{sw_wr_en_11 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_11[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg11_be1 (
+ .we ({8{sw_wr_en_11 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_11[15:8] )
+ );
+generic_register #(8,0 ) u_reg11_be2 (
+ .we ({8{sw_wr_en_11 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_11[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg11_be3 (
+ .we ({8{sw_wr_en_11 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_11[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 12
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg12_be0 (
+ .we ({8{sw_wr_en_12 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_12[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg12_be1 (
+ .we ({8{sw_wr_en_12 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_12[15:8] )
+ );
+generic_register #(8,0 ) u_reg12_be2 (
+ .we ({8{sw_wr_en_12 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_12[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg12_be3 (
+ .we ({8{sw_wr_en_12 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_12[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 13
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg13_be0 (
+ .we ({8{sw_wr_en_13 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_13[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg13_be1 (
+ .we ({8{sw_wr_en_13 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_13[15:8] )
+ );
+generic_register #(8,0 ) u_reg13_be2 (
+ .we ({8{sw_wr_en_13 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_13[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg13_be3 (
+ .we ({8{sw_wr_en_13 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_13[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 14
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg14_be0 (
+ .we ({8{sw_wr_en_14 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_14[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg14_be1 (
+ .we ({8{sw_wr_en_14 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_14[15:8] )
+ );
+generic_register #(8,0 ) u_reg14_be2 (
+ .we ({8{sw_wr_en_14 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_14[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg14_be3 (
+ .we ({8{sw_wr_en_14 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_14[31:24] )
+ );
+
+
+//-----------------------------------------------------------------
+// reg- 15
+//-----------------------------------------------------------------
+
+generic_register #(8,0 ) u_reg15_be0 (
+ .we ({8{sw_wr_en_15 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_15[7:0] )
+ );
+
+generic_register #(8,0 ) u_reg15_be1 (
+ .we ({8{sw_wr_en_15 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_15[15:8] )
+ );
+generic_register #(8,0 ) u_reg15_be2 (
+ .we ({8{sw_wr_en_15 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_15[23:16] )
+ );
+
+generic_register #(8,0 ) u_reg15_be3 (
+ .we ({8{sw_wr_en_15 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_15[31:24] )
+ );
+
+
+
+
+
+endmodule
diff --git a/verilog/rtl/i2cm/src/core/i2cm_bit_ctrl.v b/verilog/rtl/i2cm/src/core/i2cm_bit_ctrl.v
new file mode 100755
index 0000000..35c2146
--- /dev/null
+++ b/verilog/rtl/i2cm/src/core/i2cm_bit_ctrl.v
@@ -0,0 +1,545 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// OMS8051 I2C Master bit-controller Module ////
+//// WISHBONE rev.B2 compliant I2C Master bit-controller ////
+//// ////
+//// This file is part of the OMS 8051 cores project ////
+//// http://www.opencores.org/cores/oms8051mini/ ////
+//// ////
+//// Description ////
+//// OMS 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// -Richard Herveille , richard@asics.ws, www.asics.ws ////
+//// -Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Jan 6, 2017 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+// v0.0 - Dinesh A, 6th Jan 2017
+// 1. Initail version picked from
+// http://www.opencores.org/projects/i2c/
+// v0.1 - Dinesh A, 19th Jan 2017
+// 1. Lint warning clean up
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+/////////////////////////////////////
+// Bit controller section
+/////////////////////////////////////
+//
+// Translate simple commands into SCL/SDA transitions
+// Each command has 5 states, A/B/C/D/idle
+//
+// start: SCL ~~~~~~~~~~\____
+// SDA ~~~~~~~~\______
+// x | A | B | C | D | i
+//
+// repstart SCL ____/~~~~\___
+// SDA __/~~~\______
+// x | A | B | C | D | i
+//
+// stop SCL ____/~~~~~~~~
+// SDA ==\____/~~~~~
+// x | A | B | C | D | i
+//
+//- write SCL ____/~~~~\____
+// SDA ==X=========X=
+// x | A | B | C | D | i
+//
+//- read SCL ____/~~~~\____
+// SDA XXXX=====XXXX
+// x | A | B | C | D | i
+//
+
+// Timing: Normal mode Fast mode
+///////////////////////////////////////////////////////////////////////
+// Fscl 100KHz 400KHz
+// Th_scl 4.0us 0.6us High period of SCL
+// Tl_scl 4.7us 1.3us Low period of SCL
+// Tsu:sta 4.7us 0.6us setup time for a repeated start condition
+// Tsu:sto 4.0us 0.6us setup time for a stop conditon
+// Tbuf 4.7us 1.3us Bus free time between a stop and start condition
+//
+
+
+`include "i2cm_defines.v"
+
+module i2cm_bit_ctrl (
+ input clk, // system clock
+ input sresetn, // synchronous active low reset
+ input aresetn, // asynchronous active low reset
+ input ena, // core enable signal
+
+ input [15:0] clk_cnt, // clock prescale value
+
+ input [ 3:0] cmd, // command (from byte controller)
+ output reg cmd_ack, // command complete acknowledge
+ output reg busy, // i2c bus busy
+ output reg al, // i2c bus arbitration lost
+
+ input din,
+ output reg dout,
+
+ input scl_i, // i2c clock line input
+ output scl_o, // i2c clock line output
+ output reg scl_oen, // i2c clock line output enable (active low)
+ input sda_i, // i2c data line input
+ output sda_o, // i2c data line output
+ output reg sda_oen // i2c data line output enable (active low)
+);
+
+
+ //
+ // variable declarations
+ //
+
+ reg [ 1:0] cSCL, cSDA; // capture SCL and SDA
+ reg [ 2:0] fSCL, fSDA; // SCL and SDA filter inputs
+ reg sSCL, sSDA; // filtered and synchronized SCL and SDA inputs
+ reg dSCL, dSDA; // delayed versions of sSCL and sSDA
+ reg dscl_oen; // delayed scl_oen
+ reg sda_chk; // check SDA output (Multi-master arbitration)
+ reg clk_en; // clock generation signals
+ reg slave_wait; // slave inserts wait states
+ reg [15:0] cnt; // clock divider counter (synthesis)
+ reg [13:0] filter_cnt; // clock divider for filter
+
+
+ // state machine variable
+ reg [17:0] c_state; // synopsys enum_state
+
+ //
+ // module body
+ //
+
+ // whenever the slave is not ready it can delay the cycle by pulling SCL low
+ // delay scl_oen
+ always @(posedge clk)
+ dscl_oen <= scl_oen;
+
+ // slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
+ // slave_wait remains asserted until the slave releases SCL
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn) slave_wait <= 1'b0;
+ else slave_wait <= (scl_oen & ~dscl_oen & ~sSCL) | (slave_wait & ~sSCL);
+
+ // master drives SCL high, but another master pulls it low
+ // master start counting down its low cycle now (clock synchronization)
+ wire scl_sync = dSCL & ~sSCL & scl_oen;
+
+
+ // generate clk enable signal
+ always @(posedge clk or negedge aresetn)
+ if (~aresetn)
+ begin
+ cnt <= 16'h0;
+ clk_en <= 1'b1;
+ end
+ else if (!sresetn || ~|cnt || !ena || scl_sync)
+ begin
+ cnt <= clk_cnt;
+ clk_en <= 1'b1;
+ end
+ else if (slave_wait)
+ begin
+ cnt <= cnt;
+ clk_en <= 1'b0;
+ end
+ else
+ begin
+ cnt <= cnt - 16'h1;
+ clk_en <= 1'b0;
+ end
+
+
+ // generate bus status controller
+
+ // capture SDA and SCL
+ // reduce metastability risk
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn)
+ begin
+ cSCL <= 2'b00;
+ cSDA <= 2'b00;
+ end
+ else if (!sresetn)
+ begin
+ cSCL <= 2'b00;
+ cSDA <= 2'b00;
+ end
+ else
+ begin
+ cSCL <= {cSCL[0],scl_i};
+ cSDA <= {cSDA[0],sda_i};
+ end
+
+
+ // filter SCL and SDA signals; (attempt to) remove glitches
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn ) filter_cnt <= 14'h0;
+ else if (!sresetn || !ena ) filter_cnt <= 14'h0;
+ else if (~|filter_cnt) filter_cnt <= clk_cnt >> 2; //16x I2C bus frequency
+ else filter_cnt <= filter_cnt -1;
+
+
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn)
+ begin
+ fSCL <= 3'b111;
+ fSDA <= 3'b111;
+ end
+ else if (!sresetn)
+ begin
+ fSCL <= 3'b111;
+ fSDA <= 3'b111;
+ end
+ else if (~|filter_cnt)
+ begin
+ fSCL <= {fSCL[1:0],cSCL[1]};
+ fSDA <= {fSDA[1:0],cSDA[1]};
+ end
+
+
+ // generate filtered SCL and SDA signals
+ always @(posedge clk or negedge aresetn)
+ if (~aresetn)
+ begin
+ sSCL <= 1'b1;
+ sSDA <= 1'b1;
+
+ dSCL <= 1'b1;
+ dSDA <= 1'b1;
+ end
+ else if (!sresetn)
+ begin
+ sSCL <= 1'b1;
+ sSDA <= 1'b1;
+
+ dSCL <= 1'b1;
+ dSDA <= 1'b1;
+ end
+ else
+ begin
+ sSCL <= &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]);
+ sSDA <= &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]);
+
+ dSCL <= sSCL;
+ dSDA <= sSDA;
+ end
+
+ // detect start condition => detect falling edge on SDA while SCL is high
+ // detect stop condition => detect rising edge on SDA while SCL is high
+ reg sta_condition;
+ reg sto_condition;
+ always @(posedge clk or negedge aresetn)
+ if (~aresetn)
+ begin
+ sta_condition <= 1'b0;
+ sto_condition <= 1'b0;
+ end
+ else if (!sresetn)
+ begin
+ sta_condition <= 1'b0;
+ sto_condition <= 1'b0;
+ end
+ else
+ begin
+ sta_condition <= ~sSDA & dSDA & sSCL;
+ sto_condition <= sSDA & ~dSDA & sSCL;
+ end
+
+
+ // generate i2c bus busy signal
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn) busy <= 1'b0;
+ else if (!sresetn ) busy <= 1'b0;
+ else busy <= (sta_condition | busy) & ~sto_condition;
+
+
+ // generate arbitration lost signal
+ // aribitration lost when:
+ // 1) master drives SDA high, but the i2c bus is low
+ // 2) stop detected while not requested
+ reg cmd_stop;
+ always @(posedge clk or negedge aresetn)
+ if (~aresetn)
+ cmd_stop <= 1'b0;
+ else if (!sresetn)
+ cmd_stop <= 1'b0;
+ else if (clk_en)
+ cmd_stop <= cmd == `I2C_CMD_STOP;
+
+ always @(posedge clk or negedge aresetn)
+ if (~aresetn)
+ al <= 1'b0;
+ else if (!sresetn)
+ al <= 1'b0;
+ else
+ al <= (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
+
+
+ // generate dout signal (store SDA on rising edge of SCL)
+ always @(posedge clk)
+ if (sSCL & ~dSCL) dout <= sSDA;
+
+
+ // generate statemachine
+
+ // nxt_state decoder
+ parameter [17:0] idle = 18'b0_0000_0000_0000_0000;
+ parameter [17:0] start_a = 18'b0_0000_0000_0000_0001;
+ parameter [17:0] start_b = 18'b0_0000_0000_0000_0010;
+ parameter [17:0] start_c = 18'b0_0000_0000_0000_0100;
+ parameter [17:0] start_d = 18'b0_0000_0000_0000_1000;
+ parameter [17:0] start_e = 18'b0_0000_0000_0001_0000;
+ parameter [17:0] stop_a = 18'b0_0000_0000_0010_0000;
+ parameter [17:0] stop_b = 18'b0_0000_0000_0100_0000;
+ parameter [17:0] stop_c = 18'b0_0000_0000_1000_0000;
+ parameter [17:0] stop_d = 18'b0_0000_0001_0000_0000;
+ parameter [17:0] rd_a = 18'b0_0000_0010_0000_0000;
+ parameter [17:0] rd_b = 18'b0_0000_0100_0000_0000;
+ parameter [17:0] rd_c = 18'b0_0000_1000_0000_0000;
+ parameter [17:0] rd_d = 18'b0_0001_0000_0000_0000;
+ parameter [17:0] wr_a = 18'b0_0010_0000_0000_0000;
+ parameter [17:0] wr_b = 18'b0_0100_0000_0000_0000;
+ parameter [17:0] wr_c = 18'b0_1000_0000_0000_0000;
+ parameter [17:0] wr_d = 18'b1_0000_0000_0000_0000;
+
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn)
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b0;
+ scl_oen <= 1'b1;
+ sda_oen <= 1'b1;
+ sda_chk <= 1'b0;
+ end
+ else if (!sresetn | al)
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b0;
+ scl_oen <= 1'b1;
+ sda_oen <= 1'b1;
+ sda_chk <= 1'b0;
+ end
+ else
+ begin
+ cmd_ack <= 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
+
+ if (clk_en)
+ case (c_state) // synopsys full_case parallel_case
+ // idle state
+ idle:
+ begin
+ case (cmd) // synopsys full_case parallel_case
+ `I2C_CMD_START: c_state <= start_a;
+ `I2C_CMD_STOP: c_state <= stop_a;
+ `I2C_CMD_WRITE: c_state <= wr_a;
+ `I2C_CMD_READ: c_state <= rd_a;
+ default: c_state <= idle;
+ endcase
+
+ scl_oen <= scl_oen; // keep SCL in same state
+ sda_oen <= sda_oen; // keep SDA in same state
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ // start
+ start_a:
+ begin
+ c_state <= start_b;
+ scl_oen <= scl_oen; // keep SCL in same state
+ sda_oen <= 1'b1; // set SDA high
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ start_b:
+ begin
+ c_state <= start_c;
+ scl_oen <= 1'b1; // set SCL high
+ sda_oen <= 1'b1; // keep SDA high
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ start_c:
+ begin
+ c_state <= start_d;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b0; // set SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ start_d:
+ begin
+ c_state <= start_e;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b0; // keep SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ start_e:
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b1;
+ scl_oen <= 1'b0; // set SCL low
+ sda_oen <= 1'b0; // keep SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ // stop
+ stop_a:
+ begin
+ c_state <= stop_b;
+ scl_oen <= 1'b0; // keep SCL low
+ sda_oen <= 1'b0; // set SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ stop_b:
+ begin
+ c_state <= stop_c;
+ scl_oen <= 1'b1; // set SCL high
+ sda_oen <= 1'b0; // keep SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ stop_c:
+ begin
+ c_state <= stop_d;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b0; // keep SDA low
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ stop_d:
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b1;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b1; // set SDA high
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ // read
+ rd_a:
+ begin
+ c_state <= rd_b;
+ scl_oen <= 1'b0; // keep SCL low
+ sda_oen <= 1'b1; // tri-state SDA
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ rd_b:
+ begin
+ c_state <= rd_c;
+ scl_oen <= 1'b1; // set SCL high
+ sda_oen <= 1'b1; // keep SDA tri-stated
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ rd_c:
+ begin
+ c_state <= rd_d;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= 1'b1; // keep SDA tri-stated
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ rd_d:
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b1;
+ scl_oen <= 1'b0; // set SCL low
+ sda_oen <= 1'b1; // keep SDA tri-stated
+ sda_chk <= 1'b0; // don't check SDA output
+ end
+
+ // write
+ wr_a:
+ begin
+ c_state <= wr_b;
+ scl_oen <= 1'b0; // keep SCL low
+ sda_oen <= din; // set SDA
+ sda_chk <= 1'b0; // don't check SDA output (SCL low)
+ end
+
+ wr_b:
+ begin
+ c_state <= wr_c;
+ scl_oen <= 1'b1; // set SCL high
+ sda_oen <= din; // keep SDA
+ sda_chk <= 1'b0; // don't check SDA output yet
+ // allow some time for SDA and SCL to settle
+ end
+
+ wr_c:
+ begin
+ c_state <= wr_d;
+ scl_oen <= 1'b1; // keep SCL high
+ sda_oen <= din;
+ sda_chk <= 1'b1; // check SDA output
+ end
+
+ wr_d:
+ begin
+ c_state <= idle;
+ cmd_ack <= 1'b1;
+ scl_oen <= 1'b0; // set SCL low
+ sda_oen <= din;
+ sda_chk <= 1'b0; // don't check SDA output (SCL low)
+ end
+
+ endcase
+ end
+
+
+ // assign scl and sda output (always gnd)
+ assign scl_o = 1'b0;
+ assign sda_o = 1'b0;
+
+endmodule
diff --git a/verilog/rtl/i2cm/src/core/i2cm_byte_ctrl.v b/verilog/rtl/i2cm/src/core/i2cm_byte_ctrl.v
new file mode 100755
index 0000000..002b51e
--- /dev/null
+++ b/verilog/rtl/i2cm/src/core/i2cm_byte_ctrl.v
@@ -0,0 +1,343 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// OMS8051 I2C Master byte-controller Module ////
+//// WISHBONE rev.B2 compliant I2C Master byte-controller ////
+//// ////
+//// This file is part of the OMS 8051 cores project ////
+//// http://www.opencores.org/cores/oms8051mini/ ////
+//// ////
+//// Description ////
+//// OMS 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// -Richard Herveille , richard@asics.ws, www.asics.ws ////
+//// -Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Jan 6, 2017 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// v0.0 - Dinesh A, 6th Jan 2017
+//// 1. Initail version picked from
+//// http://www.opencores.org/projects/i2c/
+//// 2. renaming of reset signal to aresetn and sresetn
+//// v0.1 - Dinesh.A, 19th Jan 2017
+//// 1. Lint Error fixes
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "i2cm_defines.v"
+
+module i2cm_byte_ctrl (
+ //
+ // inputs & outputs
+ //
+ input clk, // master clock
+ input sresetn, // synchronous active high reset
+ input aresetn, // asynchronous active low reset
+ input ena, // core enable signal
+
+ input [15:0] clk_cnt, // 4x SCL
+
+ // control inputs
+ input start,
+ input stop,
+ input read,
+ input write,
+ input ack_in,
+ input [7:0] din,
+
+ // status outputs
+ output reg cmd_ack,
+ output reg ack_out,
+ output i2c_busy,
+ output i2c_al,
+ output [7:0] dout,
+
+ // I2C signals
+ input scl_i,
+ output scl_o,
+ output scl_oen,
+ input sda_i,
+ output sda_o,
+ output sda_oen
+
+ );
+
+
+
+ //
+ // Variable declarations
+ //
+
+ // statemachine
+ parameter [4:0] ST_IDLE = 5'b0_0000;
+ parameter [4:0] ST_START = 5'b0_0001;
+ parameter [4:0] ST_READ = 5'b0_0010;
+ parameter [4:0] ST_WRITE = 5'b0_0100;
+ parameter [4:0] ST_ACK = 5'b0_1000;
+ parameter [4:0] ST_STOP = 5'b1_0000;
+
+ // signals for bit_controller
+ reg [3:0] core_cmd;
+ reg core_txd;
+ wire core_ack, core_rxd;
+
+ // signals for shift register
+ reg [7:0] sr; //8bit shift register
+ reg shift, ld;
+
+ // signals for state machine
+ wire go;
+ reg [2:0] dcnt;
+ wire cnt_done;
+
+ //
+ // Module body
+ //
+
+ // hookup bit_controller
+ i2cm_bit_ctrl u_bit_ctrl (
+ .clk ( clk ),
+ .sresetn ( sresetn ),
+ .aresetn ( aresetn ),
+ .ena ( ena ),
+ .clk_cnt ( clk_cnt ),
+ .cmd ( core_cmd ),
+ .cmd_ack ( core_ack ),
+ .busy ( i2c_busy ),
+ .al ( i2c_al ),
+ .din ( core_txd ),
+ .dout ( core_rxd ),
+ .scl_i ( scl_i ),
+ .scl_o ( scl_o ),
+ .scl_oen ( scl_oen ),
+ .sda_i ( sda_i ),
+ .sda_o ( sda_o ),
+ .sda_oen ( sda_oen )
+ );
+
+ // generate go-signal
+ assign go = (read | write | stop) & ~cmd_ack;
+
+ // assign dout output to shift-register
+ assign dout = sr;
+
+ // generate shift register
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn)
+ sr <= 8'h0;
+ else if (!sresetn)
+ sr <= 8'h0;
+ else if (ld)
+ sr <= din;
+ else if (shift)
+ sr <= {sr[6:0], core_rxd};
+
+ // generate counter
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn)
+ dcnt <= 3'h0;
+ else if (!sresetn)
+ dcnt <= 3'h0;
+ else if (ld)
+ dcnt <= 3'h7;
+ else if (shift)
+ dcnt <= dcnt - 3'h1;
+
+ assign cnt_done = ~(|dcnt);
+
+ //
+ // state machine
+ //
+ reg [4:0] c_state; // synopsys enum_state
+
+ always @(posedge clk or negedge aresetn)
+ if (!aresetn)
+ begin
+ core_cmd <= `I2C_CMD_NOP;
+ core_txd <= 1'b0;
+ shift <= 1'b0;
+ ld <= 1'b0;
+ cmd_ack <= 1'b0;
+ c_state <= ST_IDLE;
+ ack_out <= 1'b0;
+ end
+ else if (!sresetn | i2c_al)
+ begin
+ core_cmd <= `I2C_CMD_NOP;
+ core_txd <= 1'b0;
+ shift <= 1'b0;
+ ld <= 1'b0;
+ cmd_ack <= 1'b0;
+ c_state <= ST_IDLE;
+ ack_out <= 1'b0;
+ end
+ else
+ begin
+ // initially reset all signals
+ core_txd <= sr[7];
+ shift <= 1'b0;
+ ld <= 1'b0;
+ cmd_ack <= 1'b0;
+
+ case (c_state) // synopsys full_case parallel_case
+ ST_IDLE:
+ if (go)
+ begin
+ if (start)
+ begin
+ c_state <= ST_START;
+ core_cmd <= `I2C_CMD_START;
+ end
+ else if (read)
+ begin
+ c_state <= ST_READ;
+ core_cmd <= `I2C_CMD_READ;
+ end
+ else if (write)
+ begin
+ c_state <= ST_WRITE;
+ core_cmd <= `I2C_CMD_WRITE;
+ end
+ else // stop
+ begin
+ c_state <= ST_STOP;
+ core_cmd <= `I2C_CMD_STOP;
+ end
+
+ ld <= 1'b1;
+ end
+
+ ST_START:
+ if (core_ack)
+ begin
+ if (read)
+ begin
+ c_state <= ST_READ;
+ core_cmd <= `I2C_CMD_READ;
+ end
+ else
+ begin
+ c_state <= ST_WRITE;
+ core_cmd <= `I2C_CMD_WRITE;
+ end
+
+ ld <= 1'b1;
+ end
+
+ ST_WRITE:
+ if (core_ack)
+ if (cnt_done)
+ begin
+ c_state <= ST_ACK;
+ core_cmd <= `I2C_CMD_READ;
+ end
+ else
+ begin
+ c_state <= ST_WRITE; // stay in same state
+ core_cmd <= `I2C_CMD_WRITE; // write next bit
+ shift <= 1'b1;
+ end
+
+ ST_READ:
+ if (core_ack)
+ begin
+ if (cnt_done)
+ begin
+ c_state <= ST_ACK;
+ core_cmd <= `I2C_CMD_WRITE;
+ end
+ else
+ begin
+ c_state <= ST_READ; // stay in same state
+ core_cmd <= `I2C_CMD_READ; // read next bit
+ end
+
+ shift <= 1'b1;
+ core_txd <= ack_in;
+ end
+
+ ST_ACK:
+ if (core_ack)
+ begin
+ if (stop)
+ begin
+ c_state <= ST_STOP;
+ core_cmd <= `I2C_CMD_STOP;
+ end
+ else
+ begin
+ c_state <= ST_IDLE;
+ core_cmd <= `I2C_CMD_NOP;
+
+ // generate command acknowledge signal
+ cmd_ack <= 1'b1;
+ end
+
+ // assign ack_out output to bit_controller_rxd (contains last received bit)
+ ack_out <= core_rxd;
+
+ core_txd <= 1'b1;
+ end
+ else
+ core_txd <= ack_in;
+
+ ST_STOP:
+ if (core_ack)
+ begin
+ c_state <= ST_IDLE;
+ core_cmd <= `I2C_CMD_NOP;
+
+ // generate command acknowledge signal
+ cmd_ack <= 1'b1;
+ end
+ default: c_state <= ST_IDLE;
+
+ endcase
+ end
+endmodule
diff --git a/verilog/rtl/i2cm/src/core/i2cm_top.v b/verilog/rtl/i2cm/src/core/i2cm_top.v
new file mode 100755
index 0000000..3b32db9
--- /dev/null
+++ b/verilog/rtl/i2cm/src/core/i2cm_top.v
@@ -0,0 +1,280 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// OMS8051 I2C Master Core Module ////
+//// WISHBONE revB.2 compliant I2C Master controller Top-level ////
+//// ////
+//// This file is part of the OMS 8051 cores project ////
+//// http://www.opencores.org/cores/oms8051mini/ ////
+//// ////
+//// Description ////
+//// OMS 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// -Richard Herveille , richard@asics.ws, www.asics.ws ////
+//// -Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Jan 6, 2017 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+// v0.0 - Dinesh A, 6th Jan 2017
+// 1. Initail version picked from
+// http://www.opencores.org/projects/i2c/
+// 2. renaming of reset signal to aresetn and sresetn
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "i2cm_defines.v"
+
+module i2cm_top(
+ // wishbone signals
+ input wb_clk_i, // master clock input
+ input sresetn, // synchronous reset
+ input aresetn, // asynchronous reset
+ input [2:0] wb_adr_i, // lower address bits
+ input [7:0] wb_dat_i, // databus input
+ output reg [7:0] wb_dat_o, // databus output
+ input wb_we_i, // write enable input
+ input wb_stb_i, // stobe/core select signal
+ input wb_cyc_i, // valid bus cycle input
+ output reg wb_ack_o, // bus cycle acknowledge output
+ output reg wb_inta_o, // interrupt request signal output
+
+ // I2C signals
+ // i2c clock line
+ input scl_pad_i, // SCL-line input
+ output scl_pad_o, // SCL-line output (always 1'b0)
+ output scl_padoen_o, // SCL-line output enable (active low)
+
+ // i2c data line
+ input sda_pad_i, // SDA-line input
+ output sda_pad_o, // SDA-line output (always 1'b0)
+ output sda_padoen_o // SDA-line output enable (active low)
+
+ );
+
+
+ //
+ // variable declarations
+ //
+
+ // registers
+ reg [15:0] prer; // clock prescale register
+ reg [ 7:0] ctr; // control register
+ reg [ 7:0] txr; // transmit register
+ wire [ 7:0] rxr; // receive register
+ reg [ 7:0] cr; // command register
+ wire [ 7:0] sr; // status register
+
+ // done signal: command completed, clear command register
+ wire done;
+
+ // core enable signal
+ wire core_en;
+ wire ien;
+
+ // status register signals
+ wire irxack;
+ reg rxack; // received aknowledge from slave
+ reg tip; // transfer in progress
+ reg irq_flag; // interrupt pending flag
+ wire i2c_busy; // bus busy (start signal detected)
+ wire i2c_al; // i2c bus arbitration lost
+ reg al; // status register arbitration lost bit
+
+ //
+ // module body
+ //
+
+
+ // generate wishbone signals
+ wire wb_wacc = wb_we_i & wb_ack_o;
+
+ // generate acknowledge output signal
+ always @(posedge wb_clk_i)
+ wb_ack_o <= #1 wb_cyc_i & wb_stb_i & ~wb_ack_o; // because timing is always honored
+
+ // assign DAT_O
+ always @(posedge wb_clk_i)
+ begin
+ case (wb_adr_i) // synopsys parallel_case
+ 3'b000: wb_dat_o <= #1 prer[ 7:0];
+ 3'b001: wb_dat_o <= #1 prer[15:8];
+ 3'b010: wb_dat_o <= #1 ctr;
+ 3'b011: wb_dat_o <= #1 rxr; // write is transmit register (txr)
+ 3'b100: wb_dat_o <= #1 sr; // write is command register (cr)
+ 3'b101: wb_dat_o <= #1 txr;
+ 3'b110: wb_dat_o <= #1 cr;
+ 3'b111: wb_dat_o <= #1 0; // reserved
+ endcase
+ end
+
+ // generate registers
+ always @(posedge wb_clk_i or negedge aresetn)
+ if (!aresetn)
+ begin
+ prer <= #1 16'hffff;
+ ctr <= #1 8'h0;
+ txr <= #1 8'h0;
+ end
+ else if (!sresetn)
+ begin
+ prer <= #1 16'hffff;
+ ctr <= #1 8'h0;
+ txr <= #1 8'h0;
+ end
+ else
+ if (wb_wacc)
+ case (wb_adr_i) // synopsys parallel_case
+ 3'b000 : prer [ 7:0] <= #1 wb_dat_i;
+ 3'b001 : prer [15:8] <= #1 wb_dat_i;
+ 3'b010 : ctr <= #1 wb_dat_i;
+ 3'b011 : txr <= #1 wb_dat_i;
+ default: ;
+ endcase
+
+ // generate command register (special case)
+ always @(posedge wb_clk_i or negedge aresetn)
+ if (!aresetn)
+ cr <= #1 8'h0;
+ else if (!sresetn)
+ cr <= #1 8'h0;
+ else if (wb_wacc)
+ begin
+ if (core_en & (wb_adr_i == 3'b100) )
+ cr <= #1 wb_dat_i;
+ end
+ else
+ begin
+ if (done | i2c_al)
+ cr[7:4] <= #1 4'h0; // clear command bits when done
+ // or when aribitration lost
+ cr[2:1] <= #1 2'b0; // reserved bits
+ cr[0] <= #1 1'b0; // clear IRQ_ACK bit
+ end
+
+
+ // decode command register
+ wire sta = cr[7];
+ wire sto = cr[6];
+ wire rd = cr[5];
+ wire wr = cr[4];
+ wire ack = cr[3];
+ wire iack = cr[0];
+
+ // decode control register
+ assign core_en = ctr[7];
+ assign ien = ctr[6];
+
+ // hookup byte controller block
+ i2cm_byte_ctrl u_byte_ctrl (
+ .clk ( wb_clk_i ),
+ .sresetn ( sresetn ),
+ .aresetn ( aresetn ),
+ .ena ( core_en ),
+ .clk_cnt ( prer ),
+ .start ( sta ),
+ .stop ( sto ),
+ .read ( rd ),
+ .write ( wr ),
+ .ack_in ( ack ),
+ .din ( txr ),
+ .cmd_ack ( done ),
+ .ack_out ( irxack ),
+ .dout ( rxr ),
+ .i2c_busy ( i2c_busy ),
+ .i2c_al ( i2c_al ),
+ .scl_i ( scl_pad_i ),
+ .scl_o ( scl_pad_o ),
+ .scl_oen ( scl_padoen_o ),
+ .sda_i ( sda_pad_i ),
+ .sda_o ( sda_pad_o ),
+ .sda_oen ( sda_padoen_o )
+ );
+
+ // status register block + interrupt request signal
+ always @(posedge wb_clk_i or negedge aresetn)
+ if (!aresetn)
+ begin
+ al <= #1 1'b0;
+ rxack <= #1 1'b0;
+ tip <= #1 1'b0;
+ irq_flag <= #1 1'b0;
+ end
+ else if (!sresetn)
+ begin
+ al <= #1 1'b0;
+ rxack <= #1 1'b0;
+ tip <= #1 1'b0;
+ irq_flag <= #1 1'b0;
+ end
+ else
+ begin
+ al <= #1 i2c_al | (al & ~sta);
+ rxack <= #1 irxack;
+ tip <= #1 (rd | wr);
+ irq_flag <= #1 (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated
+ end
+
+ // generate interrupt request signals
+ always @(posedge wb_clk_i or negedge aresetn)
+ if (!aresetn)
+ wb_inta_o <= #1 1'b0;
+ else if (!sresetn)
+ wb_inta_o <= #1 1'b0;
+ else
+ wb_inta_o <= #1 irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set)
+
+ // assign status register bits
+ assign sr[7] = rxack;
+ assign sr[6] = i2c_busy;
+ assign sr[5] = al;
+ assign sr[4:2] = 3'h0; // reserved
+ assign sr[1] = tip;
+ assign sr[0] = irq_flag;
+
+endmodule
diff --git a/verilog/rtl/i2cm/src/includes/i2cm_defines.v b/verilog/rtl/i2cm/src/includes/i2cm_defines.v
new file mode 100755
index 0000000..ccfee25
--- /dev/null
+++ b/verilog/rtl/i2cm/src/includes/i2cm_defines.v
@@ -0,0 +1,25 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+// I2C registers wishbone addresses
+
+// bitcontroller states
+`define I2C_CMD_NOP 4'b0000
+`define I2C_CMD_START 4'b0001
+`define I2C_CMD_STOP 4'b0010
+`define I2C_CMD_WRITE 4'b0100
+`define I2C_CMD_READ 4'b1000
diff --git a/verilog/rtl/lib/async_fifo.sv b/verilog/rtl/lib/async_fifo.sv
new file mode 100755
index 0000000..fd59cfa
--- /dev/null
+++ b/verilog/rtl/lib/async_fifo.sv
@@ -0,0 +1,341 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+/*********************************************************************
+
+ ASYNC FIFO
+
+ This file is part of the sdram controller project
+ https://github.com/dineshannayya/yifive_r0.git
+ http://www.opencores.org/cores/sdr_ctrl/
+
+ Description: ASYNC FIFO
+
+ To Do:
+ nothing
+
+ Author(s): Dinesh Annayya, dinesha@opencores.org
+
+ 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
+
+*******************************************************************/
+
+//-------------------------------------------
+// async FIFO
+//-----------------------------------------------
+//`timescale 1ns/1ps
+
+module async_fifo (wr_clk,
+ wr_reset_n,
+ wr_en,
+ wr_data,
+ full, // sync'ed to wr_clk
+ afull, // sync'ed to wr_clk
+ rd_clk,
+ rd_reset_n,
+ rd_en,
+ empty, // sync'ed to rd_clk
+ aempty, // sync'ed to rd_clk
+ rd_data);
+
+ parameter W = 4'd8;
+ parameter DP = 3'd4;
+ parameter WR_FAST = 1'b1;
+ parameter RD_FAST = 1'b1;
+ parameter FULL_DP = DP;
+ parameter EMPTY_DP = 1'b0;
+
+ parameter AW = (DP == 2) ? 1 :
+ (DP == 4) ? 2 :
+ (DP == 8) ? 3 :
+ (DP == 16) ? 4 :
+ (DP == 32) ? 5 :
+ (DP == 64) ? 6 :
+ (DP == 128) ? 7 :
+ (DP == 256) ? 8 : 0;
+
+ output [W-1 : 0] rd_data;
+ input [W-1 : 0] wr_data;
+ input wr_clk, wr_reset_n, wr_en, rd_clk, rd_reset_n,
+ rd_en;
+ output full, empty;
+ output afull, aempty; // about full and about to empty
+
+
+ // synopsys translate_off
+
+ initial begin
+ if (AW == 0) begin
+ $display ("%m : ERROR!!! Fifo depth %d not in range 2 to 256", DP);
+ end // if (AW == 0)
+ end // initial begin
+
+ // synopsys translate_on
+
+ reg [W-1 : 0] mem[DP-1 : 0];
+
+ /*********************** write side ************************/
+ reg [AW:0] sync_rd_ptr_0, sync_rd_ptr_1;
+ wire [AW:0] sync_rd_ptr;
+ reg [AW:0] wr_ptr, grey_wr_ptr;
+ reg [AW:0] grey_rd_ptr;
+ reg full_q;
+ wire full_c;
+ wire afull_c;
+ wire [AW:0] wr_ptr_inc = wr_ptr + 1'b1;
+ wire [AW:0] wr_cnt = get_cnt(wr_ptr, sync_rd_ptr);
+
+ assign full_c = (wr_cnt == FULL_DP) ? 1'b1 : 1'b0;
+ assign afull_c = (wr_cnt == FULL_DP-1) ? 1'b1 : 1'b0;
+
+
+ always @(posedge wr_clk or negedge wr_reset_n) begin
+ if (!wr_reset_n) begin
+ wr_ptr <= 0;
+ grey_wr_ptr <= 0;
+ full_q <= 0;
+ end
+ else if (wr_en) begin
+ wr_ptr <= wr_ptr_inc;
+ grey_wr_ptr <= bin2grey(wr_ptr_inc);
+ if (wr_cnt == (FULL_DP-1)) begin
+ full_q <= 1'b1;
+ end
+ end
+ else begin
+ if (full_q && (wr_cnt<FULL_DP)) begin
+ full_q <= 1'b0;
+ end
+ end
+ end
+
+ assign full = (WR_FAST == 1) ? full_c : full_q;
+ assign afull = afull_c;
+
+ always @(posedge wr_clk) begin
+ if (wr_en) begin
+ mem[wr_ptr[AW-1:0]] <= wr_data;
+ end
+ end
+
+ wire [AW:0] grey_rd_ptr_dly ;
+ assign #1 grey_rd_ptr_dly = grey_rd_ptr;
+
+ // read pointer synchronizer
+ always @(posedge wr_clk or negedge wr_reset_n) begin
+ if (!wr_reset_n) begin
+ sync_rd_ptr_0 <= 0;
+ sync_rd_ptr_1 <= 0;
+ end
+ else begin
+ sync_rd_ptr_0 <= grey_rd_ptr_dly;
+ sync_rd_ptr_1 <= sync_rd_ptr_0;
+ end
+ end
+
+ assign sync_rd_ptr = grey2bin(sync_rd_ptr_1);
+
+ /************************ read side *****************************/
+ reg [AW:0] sync_wr_ptr_0, sync_wr_ptr_1;
+ wire [AW:0] sync_wr_ptr;
+ reg [AW:0] rd_ptr;
+ reg empty_q;
+ wire empty_c;
+ wire aempty_c;
+ wire [AW:0] rd_ptr_inc = rd_ptr + 1'b1;
+ wire [AW:0] sync_wr_ptr_dec = sync_wr_ptr - 1'b1;
+ wire [AW:0] rd_cnt = get_cnt(sync_wr_ptr, rd_ptr);
+
+ assign empty_c = (rd_cnt == 0) ? 1'b1 : 1'b0;
+ assign aempty_c = (rd_cnt == 1) ? 1'b1 : 1'b0;
+
+ always @(posedge rd_clk or negedge rd_reset_n) begin
+ if (!rd_reset_n) begin
+ rd_ptr <= 0;
+ grey_rd_ptr <= 0;
+ empty_q <= 1'b1;
+ end
+ else begin
+ if (rd_en) begin
+ rd_ptr <= rd_ptr_inc;
+ grey_rd_ptr <= bin2grey(rd_ptr_inc);
+ if (rd_cnt==(EMPTY_DP+1)) begin
+ empty_q <= 1'b1;
+ end
+ end
+ else begin
+ if (empty_q && (rd_cnt!=EMPTY_DP)) begin
+ empty_q <= 1'b0;
+ end
+ end
+ end
+ end
+
+ assign empty = (RD_FAST == 1) ? empty_c : empty_q;
+ assign aempty = aempty_c;
+
+ reg [W-1 : 0] rd_data_q;
+
+ wire [W-1 : 0] rd_data_c = mem[rd_ptr[AW-1:0]];
+ always @(posedge rd_clk) begin
+ rd_data_q <= rd_data_c;
+ end
+ assign rd_data = (RD_FAST == 1) ? rd_data_c : rd_data_q;
+
+ wire [AW:0] grey_wr_ptr_dly ;
+ assign #1 grey_wr_ptr_dly = grey_wr_ptr;
+
+ // write pointer synchronizer
+ always @(posedge rd_clk or negedge rd_reset_n) begin
+ if (!rd_reset_n) begin
+ sync_wr_ptr_0 <= 0;
+ sync_wr_ptr_1 <= 0;
+ end
+ else begin
+ sync_wr_ptr_0 <= grey_wr_ptr_dly;
+ sync_wr_ptr_1 <= sync_wr_ptr_0;
+ end
+ end
+ assign sync_wr_ptr = grey2bin(sync_wr_ptr_1);
+
+
+/************************ functions ******************************/
+function [AW:0] bin2grey;
+input [AW:0] bin;
+reg [8:0] bin_8;
+reg [8:0] grey_8;
+begin
+ bin_8 = bin;
+ grey_8[1:0] = do_grey(bin_8[2:0]);
+ grey_8[3:2] = do_grey(bin_8[4:2]);
+ grey_8[5:4] = do_grey(bin_8[6:4]);
+ grey_8[7:6] = do_grey(bin_8[8:6]);
+ grey_8[8] = bin_8[8];
+ bin2grey = grey_8;
+end
+endfunction
+
+function [AW:0] grey2bin;
+input [AW:0] grey;
+reg [8:0] grey_8;
+reg [8:0] bin_8;
+begin
+ grey_8 = grey;
+ bin_8[8] = grey_8[8];
+ bin_8[7:6] = do_bin({bin_8[8], grey_8[7:6]});
+ bin_8[5:4] = do_bin({bin_8[6], grey_8[5:4]});
+ bin_8[3:2] = do_bin({bin_8[4], grey_8[3:2]});
+ bin_8[1:0] = do_bin({bin_8[2], grey_8[1:0]});
+ grey2bin = bin_8;
+end
+endfunction
+
+
+function [1:0] do_grey;
+input [2:0] bin;
+begin
+ if (bin[2]) begin // do reverse grey
+ case (bin[1:0])
+ 2'b00: do_grey = 2'b10;
+ 2'b01: do_grey = 2'b11;
+ 2'b10: do_grey = 2'b01;
+ 2'b11: do_grey = 2'b00;
+ endcase
+ end
+ else begin
+ case (bin[1:0])
+ 2'b00: do_grey = 2'b00;
+ 2'b01: do_grey = 2'b01;
+ 2'b10: do_grey = 2'b11;
+ 2'b11: do_grey = 2'b10;
+ endcase
+ end
+end
+endfunction
+
+function [1:0] do_bin;
+input [2:0] grey;
+begin
+ if (grey[2]) begin // actually bin[2]
+ case (grey[1:0])
+ 2'b10: do_bin = 2'b00;
+ 2'b11: do_bin = 2'b01;
+ 2'b01: do_bin = 2'b10;
+ 2'b00: do_bin = 2'b11;
+ endcase
+ end
+ else begin
+ case (grey[1:0])
+ 2'b00: do_bin = 2'b00;
+ 2'b01: do_bin = 2'b01;
+ 2'b11: do_bin = 2'b10;
+ 2'b10: do_bin = 2'b11;
+ endcase
+ end
+end
+endfunction
+
+function [AW:0] get_cnt;
+input [AW:0] wr_ptr, rd_ptr;
+begin
+ if (wr_ptr >= rd_ptr) begin
+ get_cnt = (wr_ptr - rd_ptr);
+ end
+ else begin
+ get_cnt = DP*2 - (rd_ptr - wr_ptr);
+ end
+end
+endfunction
+
+// synopsys translate_off
+always @(posedge wr_clk) begin
+ if (wr_en && full) begin
+ $display($time, "%m Error! afifo overflow!");
+ $stop;
+ end
+end
+
+always @(posedge rd_clk) begin
+ if (rd_en && empty) begin
+ $display($time, "%m error! afifo underflow!");
+ $stop;
+ end
+end
+// synopsys translate_on
+
+endmodule
diff --git a/verilog/rtl/lib/async_fifo_th.sv b/verilog/rtl/lib/async_fifo_th.sv
new file mode 100755
index 0000000..05860f8
--- /dev/null
+++ b/verilog/rtl/lib/async_fifo_th.sv
@@ -0,0 +1,404 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// OMS 8051 cores common library Module ////
+//// ////
+//// This file is part of the OMS 8051 cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/oms8051mini/ ////
+//// ////
+//// Description ////
+//// Async Fifo with threshold tracking/status ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Nov 26, 2016 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+//-------------------------------------------
+// async_fifo:: async FIFO
+// Following two ports are newly added
+// 1. At write clock domain:
+// wr_total_free_space --> Indicate total free transfer available
+// 2. At read clock domain:
+// rd_total_aval --> Indicate total no of transfer available
+//-----------------------------------------------
+
+module async_fifo_th (
+ wr_clk,
+ wr_reset_n,
+ wr_en,
+ wr_data,
+ full, // sync'ed to wr_clk
+ afull, // sync'ed to wr_clk
+ wr_total_free_space,
+ rd_clk,
+ rd_reset_n,
+ rd_en,
+ empty, // sync'ed to rd_clk
+ aempty, // sync'ed to rd_clk
+ rd_total_aval,
+ rd_data);
+
+ parameter W = 4'd8;
+ parameter DP = 3'd4;
+ parameter WR_FAST = 1'b1;
+ parameter RD_FAST = 1'b1;
+ parameter FULL_DP = DP;
+ parameter EMPTY_DP = 1'b0;
+
+ parameter AW = (DP == 2) ? 1 :
+ (DP == 4) ? 2 :
+ (DP == 8) ? 3 :
+ (DP == 16) ? 4 :
+ (DP == 32) ? 5 :
+ (DP == 64) ? 6 :
+ (DP == 128) ? 7 :
+ (DP == 256) ? 8 : 0;
+
+ output [W-1 : 0] rd_data;
+ input [W-1 : 0] wr_data;
+ input wr_clk, wr_reset_n, wr_en, rd_clk, rd_reset_n,
+ rd_en;
+ output full, empty;
+ output afull, aempty; // about full and about to empty
+ output [AW:0] wr_total_free_space; // Total Number of free space aval
+ // w.r.t write clk
+ // note: Without accounting byte enables
+ output [AW:0] rd_total_aval; // Total Number of words avaialble
+ // w.r.t rd clock,
+ // note: Without accounting byte enables
+ // synopsys translate_off
+
+ initial begin
+ if (AW == 0) begin
+ $display ("%m : ERROR!!! Fifo depth %d not in range 2 to 256", DP);
+ end // if (AW == 0)
+ end // initial begin
+
+ // synopsys translate_on
+ reg [W-1 : 0] mem[DP-1 : 0];
+
+ /*********************** write side ************************/
+ reg [AW:0] sync_rd_ptr_0, sync_rd_ptr_1;
+ wire [AW:0] sync_rd_ptr;
+ reg [AW:0] wr_ptr, grey_wr_ptr;
+ reg [AW:0] grey_rd_ptr;
+ reg full_q;
+ wire full_c;
+ wire afull_c;
+ wire [AW:0] wr_ptr_inc = wr_ptr + 1'b1;
+ wire [AW:0] wr_cnt = get_cnt(wr_ptr, sync_rd_ptr);
+
+ assign full_c = (wr_cnt == FULL_DP) ? 1'b1 : 1'b0;
+ assign afull_c = (wr_cnt == FULL_DP-1) ? 1'b1 : 1'b0;
+
+ //--------------------------
+ // Shows total number of words
+ // of free space available w.r.t write clock
+ //---------------------------
+ assign wr_total_free_space = FULL_DP - wr_cnt;
+
+ always @(posedge wr_clk or negedge wr_reset_n) begin
+ if (!wr_reset_n) begin
+ wr_ptr <= 0;
+ grey_wr_ptr <= 0;
+ full_q <= 0;
+ end
+ else if (wr_en) begin
+ wr_ptr <= wr_ptr_inc;
+ grey_wr_ptr <= bin2grey(wr_ptr_inc);
+ if (wr_cnt == (FULL_DP-1)) begin
+ full_q <= 1'b1;
+ end
+ end
+ else begin
+ if (full_q && (wr_cnt<FULL_DP)) begin
+ full_q <= 1'b0;
+ end
+ end
+ end
+
+ assign full = (WR_FAST == 1) ? full_c : full_q;
+ assign afull = afull_c;
+
+ always @(posedge wr_clk) begin
+ if (wr_en) begin
+ mem[wr_ptr[AW-1:0]] <= wr_data;
+ end
+ end
+
+ wire [AW:0] grey_rd_ptr_dly ;
+ assign #1 grey_rd_ptr_dly = grey_rd_ptr;
+
+ // read pointer synchronizer
+ always @(posedge wr_clk or negedge wr_reset_n) begin
+ if (!wr_reset_n) begin
+ sync_rd_ptr_0 <= 0;
+ sync_rd_ptr_1 <= 0;
+ end
+ else begin
+ sync_rd_ptr_0 <= grey_rd_ptr_dly;
+ sync_rd_ptr_1 <= sync_rd_ptr_0;
+ end
+ end
+
+ assign sync_rd_ptr = grey2bin(sync_rd_ptr_1);
+
+ /************************ read side *****************************/
+ reg [AW:0] sync_wr_ptr_0, sync_wr_ptr_1;
+ wire [AW:0] sync_wr_ptr;
+ reg [AW:0] rd_ptr;
+ reg empty_q;
+ wire empty_c;
+ wire aempty_c;
+ wire [AW:0] rd_ptr_inc = rd_ptr + 1'b1;
+ wire [AW:0] sync_wr_ptr_dec = sync_wr_ptr - 1'b1;
+ wire [AW:0] rd_cnt = get_cnt(sync_wr_ptr, rd_ptr);
+
+ assign empty_c = (rd_cnt == 0) ? 1'b1 : 1'b0;
+ assign aempty_c = (rd_cnt == 1) ? 1'b1 : 1'b0;
+ //--------------------------
+ // Shows total number of words
+ // space available w.r.t write clock
+ //---------------------------
+ assign rd_total_aval = rd_cnt;
+
+ always @(posedge rd_clk or negedge rd_reset_n) begin
+ if (!rd_reset_n) begin
+ rd_ptr <= 0;
+ grey_rd_ptr <= 0;
+ empty_q <= 1'b1;
+ end
+ else begin
+ if (rd_en) begin
+ rd_ptr <= rd_ptr_inc;
+ grey_rd_ptr <= bin2grey(rd_ptr_inc);
+ if (rd_cnt==(EMPTY_DP+1)) begin
+ empty_q <= 1'b1;
+ end
+ end
+ else begin
+ if (empty_q && (rd_cnt!=EMPTY_DP)) begin
+ empty_q <= 1'b0;
+ end
+ end
+ end
+ end
+
+ assign empty = (RD_FAST == 1) ? empty_c : empty_q;
+ assign aempty = aempty_c;
+
+ assign rd_data = mem[rd_ptr[AW-1:0]];
+
+ wire [AW:0] grey_wr_ptr_dly ;
+ assign #1 grey_wr_ptr_dly = grey_wr_ptr;
+
+ // write pointer synchronizer
+ always @(posedge rd_clk or negedge rd_reset_n) begin
+ if (!rd_reset_n) begin
+ sync_wr_ptr_0 <= 0;
+ sync_wr_ptr_1 <= 0;
+ end
+ else begin
+ sync_wr_ptr_0 <= grey_wr_ptr_dly;
+ sync_wr_ptr_1 <= sync_wr_ptr_0;
+ end
+ end
+ assign sync_wr_ptr = grey2bin(sync_wr_ptr_1);
+
+
+/************************ functions ******************************/
+function [AW:0] bin2grey;
+input [AW:0] bin;
+reg [8:0] bin_8;
+reg [8:0] grey_8;
+begin
+ bin_8 = bin;
+ grey_8[1:0] = do_grey(bin_8[2:0]);
+ grey_8[3:2] = do_grey(bin_8[4:2]);
+ grey_8[5:4] = do_grey(bin_8[6:4]);
+ grey_8[7:6] = do_grey(bin_8[8:6]);
+ grey_8[8] = bin_8[8];
+ bin2grey = grey_8;
+end
+endfunction
+
+function [AW:0] grey2bin;
+input [AW:0] grey;
+reg [8:0] grey_8;
+reg [8:0] bin_8;
+begin
+ grey_8 = grey;
+ bin_8[8] = grey_8[8];
+ bin_8[7:6] = do_bin({bin_8[8], grey_8[7:6]});
+ bin_8[5:4] = do_bin({bin_8[6], grey_8[5:4]});
+ bin_8[3:2] = do_bin({bin_8[4], grey_8[3:2]});
+ bin_8[1:0] = do_bin({bin_8[2], grey_8[1:0]});
+ grey2bin = bin_8;
+end
+endfunction
+
+
+function [1:0] do_grey;
+input [2:0] bin;
+begin
+ if (bin[2]) begin // do reverse grey
+ case (bin[1:0])
+ 2'b00: do_grey = 2'b10;
+ 2'b01: do_grey = 2'b11;
+ 2'b10: do_grey = 2'b01;
+ 2'b11: do_grey = 2'b00;
+ endcase
+ end
+ else begin
+ case (bin[1:0])
+ 2'b00: do_grey = 2'b00;
+ 2'b01: do_grey = 2'b01;
+ 2'b10: do_grey = 2'b11;
+ 2'b11: do_grey = 2'b10;
+ endcase
+ end
+end
+endfunction
+
+function [1:0] do_bin;
+input [2:0] grey;
+begin
+ if (grey[2]) begin // actually bin[2]
+ case (grey[1:0])
+ 2'b10: do_bin = 2'b00;
+ 2'b11: do_bin = 2'b01;
+ 2'b01: do_bin = 2'b10;
+ 2'b00: do_bin = 2'b11;
+ endcase
+ end
+ else begin
+ case (grey[1:0])
+ 2'b00: do_bin = 2'b00;
+ 2'b01: do_bin = 2'b01;
+ 2'b11: do_bin = 2'b10;
+ 2'b10: do_bin = 2'b11;
+ endcase
+ end
+end
+endfunction
+
+function [AW:0] get_cnt;
+input [AW:0] wr_ptr, rd_ptr;
+begin
+ if (wr_ptr >= rd_ptr) begin
+ get_cnt = (wr_ptr - rd_ptr);
+ end
+ else begin
+ get_cnt = DP*2 - (rd_ptr - wr_ptr);
+ end
+end
+endfunction
+
+// synopsys translate_off
+always @(posedge wr_clk) begin
+ if (wr_en && full) begin
+ $display($time, "%m Error! afifo overflow!");
+ $stop;
+ end
+end
+
+always @(posedge rd_clk) begin
+ if (rd_en && empty) begin
+ $display($time, "%m error! afifo underflow!");
+ $stop;
+ end
+end
+
+// gray code monitor
+reg [AW:0] last_gwr_ptr;
+always @(posedge wr_clk or negedge wr_reset_n) begin
+ if (!wr_reset_n) begin
+ last_gwr_ptr <= #1 0;
+ end
+ else if (last_gwr_ptr !== grey_wr_ptr) begin
+ check_ptr_chg(last_gwr_ptr, grey_wr_ptr);
+ last_gwr_ptr <= #1 grey_wr_ptr;
+ end
+end
+
+reg [AW:0] last_grd_ptr;
+always @(posedge rd_clk or negedge rd_reset_n) begin
+ if (!rd_reset_n) begin
+ last_grd_ptr <= #1 0;
+ end
+ else if (last_grd_ptr !== grey_rd_ptr) begin
+ check_ptr_chg(last_grd_ptr, grey_rd_ptr);
+ last_grd_ptr <= #1 grey_rd_ptr;
+ end
+end
+
+task check_ptr_chg;
+input [AW:0] last_ptr;
+input [AW:0] cur_ptr;
+integer i;
+integer ptr_diff;
+begin
+ ptr_diff = 0;
+ for (i=0; i<= AW; i=i+ 1'b1) begin
+ if (last_ptr[i] != cur_ptr[i]) begin
+ ptr_diff = ptr_diff + 1'b1;
+ end
+ end
+ if (ptr_diff !== 1) begin
+ $display($time, "%m, ERROR! async fifo ptr has changed more than noe bit, last=%h, cur=%h",
+ last_ptr, cur_ptr);
+ $stop;
+ end
+end
+endtask
+ // synopsys translate_on
+
+endmodule
diff --git a/verilog/rtl/lib/async_reg_bus.sv b/verilog/rtl/lib/async_reg_bus.sv
new file mode 100644
index 0000000..2c02701
--- /dev/null
+++ b/verilog/rtl/lib/async_reg_bus.sv
@@ -0,0 +1,305 @@
+
+
+//----------------------------------------------------------------------------------------------
+// This block translate the Reg Bus transaction from in_clk clock domain to out_clk clock domain.
+// This block also generate and terminate the transfer if 512 cycle transaction is not completed
+// Assumption
+// 1. in_reg_cs will be asserted untill ack is received
+// 2. reg_addr/reg_wdata/reg_be will be available during reg_cs
+// 3. Ever after out_reg_ack de-asserted reg_rdata holds the old data
+//----------------------------------------------------------------------------------------------
+
+module async_reg_bus (
+ // Initiator declartion
+ in_clk ,
+ in_reset_n ,
+ // Reg Bus Master
+ // outputs
+ in_reg_rdata ,
+ in_reg_ack ,
+ in_reg_timeout ,
+
+ // Inputs
+ in_reg_cs ,
+ in_reg_addr ,
+ in_reg_wdata ,
+ in_reg_wr ,
+ in_reg_be ,
+
+ // Target Declaration
+ out_clk ,
+ out_reset_n ,
+ // Reg Bus Slave
+ // output
+ out_reg_cs ,
+ out_reg_addr ,
+ out_reg_wdata ,
+ out_reg_wr ,
+ out_reg_be ,
+
+ // Inputs
+ out_reg_rdata ,
+ out_reg_ack
+ );
+parameter AW = 26 ; // Address width
+parameter DW = 32 ; // DATA WIDTH
+parameter BEW = 4 ; // Byte enable width
+
+//----------------------------------------
+// Reg Bus reg inout declration
+//----------------------------------------
+input in_clk ; // Initiator domain clock
+input in_reset_n ; // Initiator domain reset
+
+input in_reg_cs ; // Initiator Chip Select
+input [AW-1:0] in_reg_addr ; // Address bus
+input [DW-1:0] in_reg_wdata ; // Write data
+input in_reg_wr ; // Read/write indication, 1-> write
+input [BEW-1:0] in_reg_be ; // Byte valid for write
+
+output [DW-1:0] in_reg_rdata ; // Read Data
+output in_reg_ack ; // Reg Access done
+output in_reg_timeout ; // Access error indication pulse
+ // Genererated if no target ack
+ // received
+ // within 512 cycle
+
+//---------------------------------------------
+// Reg Bus target inout declration
+//---------------------------------------------
+
+input out_clk ; // Target domain clock
+input out_reset_n ; // Traget domain reset
+
+input [DW-1:0] out_reg_rdata ; // Read data
+input out_reg_ack ; // target finish
+
+output out_reg_cs ; // Target Start indication
+output [AW-1:0] out_reg_addr ; // Target address
+output [DW-1:0] out_reg_wdata ; // Target write data
+output out_reg_wr ; // Target Read/write ind, 1-> Write
+output [BEW-1:0] out_reg_be ; // Target Byte enable
+
+//-----------------------------------
+// Initiator Local Declaration
+// ----------------------------------
+parameter INI_IDLE = 2'b00;
+parameter INI_WAIT_ACK = 2'b01;
+parameter INI_WAIT_TAR_DONE = 2'b10;
+
+reg [1:0] in_state ; // reg state
+reg [8:0] in_timer ; // reg timout monitor timer
+reg in_flag ; // reg handshake flag
+reg in_reg_ack ; // reg reg access finish ind
+reg [DW-1:0] in_reg_rdata ; // reg reg access read data
+reg in_reg_timeout ; // reg time out error pulse
+
+//-----------------------------------
+// Target Local Declaration
+// ----------------------------------
+parameter TAR_IDLE = 2'b00;
+parameter TAR_WAIT_ACK = 2'b01;
+parameter TAR_WAIT_INI_DONE = 2'b10;
+
+reg [1:0] out_state ; // target state machine
+reg out_flag ; // target handshake flag
+reg out_reg_cs ; // Target Start indication
+
+reg [8:0] inititaor_timer ; // timeout counter
+//-----------------------------------------------
+// Double sync local declaration
+// ----------------------------------------------
+
+reg in_flag_s ; // Initiator handshake flag sync
+ // with target clk
+reg in_flag_ss ; // Initiator handshake flag sync
+ // with target clk
+
+reg out_flag_s ; // target handshake flag sync
+ // with initiator clk
+reg out_flag_ss ; // target handshake flag sync
+ // with initiator clck
+
+
+
+
+assign out_reg_addr = in_reg_addr;
+assign out_reg_wdata = in_reg_wdata;
+assign out_reg_wr = in_reg_wr;
+assign out_reg_be = in_reg_be;
+//------------------------------------------------------
+// Initiator Domain logic
+//------------------------------------------------------
+
+always @(negedge in_reset_n or posedge in_clk)
+begin
+ if(in_reset_n == 1'b0)
+ begin
+ in_state <= INI_IDLE;
+ in_timer <= 9'h0;
+ in_flag <= 1'b0;
+ in_reg_ack <= 1'b0;
+ in_reg_rdata <= {DW {1'b0}};
+ in_reg_timeout<= 1'b0;
+ end
+ else
+ begin
+ case(in_state)
+ INI_IDLE :
+ begin
+ in_reg_ack <= 1'b0;
+ in_reg_timeout <= 1'b0;
+ in_timer <= 'h0;
+ // Wait for Initiator Start Indication
+ // Once the reg start is detected
+ // Set the reg flag and move to WAIT
+ // for ack from Target
+ if(in_reg_cs) begin
+ in_flag <= 1'b1;
+ in_state <= INI_WAIT_ACK;
+ end
+ end
+ INI_WAIT_ACK :
+ begin
+ //--------------------------------------------
+ // 1. Wait for Out Flag == 1
+ // 2. If the Out Flag =1 is not
+ // detected witin 512 cycle, exit with error indication
+ // 3. If Target flag detected, then de-assert
+ // reg_flag = 0 and move the tar_wait_done state
+ // ---------------------------------------------
+ if(out_flag_ss == 1'b1) begin
+ in_flag <= 1'b0;
+ in_reg_rdata <= out_reg_rdata;
+ in_reg_ack <= 1'b1;
+ in_state <= INI_WAIT_TAR_DONE;
+ end
+ else begin
+ if(in_timer == 9'h1FF) begin
+ in_flag <= 1'b0;
+ in_reg_ack <= 1'b1;
+ in_reg_rdata <= 32'h0;
+ in_reg_timeout <= 1'b1;
+ in_state <= INI_IDLE;
+ end
+ else begin
+ in_timer <= in_timer + 1;
+ end
+ end
+ end
+ INI_WAIT_TAR_DONE :
+ begin
+ in_reg_ack <= 1'b0;
+ //--------------------------------------------
+ // 1. Wait for Target Flag == 0
+ // 2. If Target flag = 0 detected, then remove
+ // move the idle state
+ // ---------------------------------------------
+ if(out_flag_ss == 1'b0) begin
+ in_state <= INI_IDLE;
+ end
+ end
+ default:
+ begin
+ in_state <= INI_IDLE;
+ in_timer <= 9'h0;
+ in_flag <= 1'b0;
+ in_reg_rdata <= {DW {1'b0}};
+ in_reg_timeout <= 1'b0;
+ end
+ endcase
+ end
+end
+
+
+//------------------------------------------------------
+// target Domain logic
+//------------------------------------------------------
+always @(negedge out_reset_n or posedge out_clk)
+begin
+ if(out_reset_n == 1'b0)
+ begin
+ out_state <= TAR_IDLE;
+ out_flag <= 1'b0;
+ out_reg_cs <= 1'b0;
+ end
+ else
+ begin
+ case(out_state)
+ TAR_IDLE :
+ begin
+ // 1. Wait for Initiator flag assertion
+ // 2. Once the reg flag = 1 is detected
+ // Set the target_flag and initiate the
+ // target reg bus access
+ out_flag <= 1'b0;
+ if(in_flag_ss) begin
+ out_reg_cs <= 1'b1;
+ out_state <= TAR_WAIT_ACK;
+ end
+ end
+ TAR_WAIT_ACK :
+ begin
+ //--------------------------------------------
+ // 1. Wait for reg Flag == 0
+ // 2. If reg flag = 0 detected, then
+ // move the idle state
+ // ---------------------------------------------
+ if(out_reg_ack == 1'b1)
+ begin
+ out_reg_cs <= 1'b0;
+ out_flag <= 1'b1;
+ out_state <= TAR_WAIT_INI_DONE;
+ end
+ end
+ TAR_WAIT_INI_DONE :
+ begin
+ if(in_flag_ss == 1'b0) begin
+ out_flag <= 1'b0;
+ out_state <= TAR_IDLE;
+ end
+ end
+ default:
+ begin
+ out_state <= TAR_IDLE;
+ out_reg_cs <= 1'b0;
+ out_flag <= 1'b0;
+ end
+ endcase
+ end
+end
+
+//-------------------------------------------------------
+// Double Sync Logic
+// ------------------------------------------------------
+always @(negedge in_reset_n or posedge in_clk)
+begin
+ if(in_reset_n == 1'b0)
+ begin
+ out_flag_s <= 1'b0;
+ out_flag_ss <= 1'b0;
+ end
+ else
+ begin
+ out_flag_s <= out_flag;
+ out_flag_ss <= out_flag_s;
+ end
+end
+
+
+always @(negedge out_reset_n or posedge out_clk)
+begin
+ if(out_reset_n == 1'b0)
+ begin
+ in_flag_s <= 1'b0;
+ in_flag_ss <= 1'b0;
+ end
+ else
+ begin
+ in_flag_s <= in_flag;
+ in_flag_ss <= in_flag_s;
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/lib/async_wb.sv b/verilog/rtl/lib/async_wb.sv
new file mode 100644
index 0000000..4e5d4a6
--- /dev/null
+++ b/verilog/rtl/lib/async_wb.sv
@@ -0,0 +1,234 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Async Wishbone Interface ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block does async Wishbone from one clock to other ////
+//// clock domain
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 25th Feb 2021, Dinesh A ////
+//// initial version ////
+//// 0.2 - 28th Feb 2021, Dinesh A ////
+//// reduced the response FIFO path depth to 2 as ////
+//// return path used by only read logic and read is ////
+//// blocking request and expect only one location will ////
+//// be used ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module async_wb
+ #(parameter AW = 32,
+ parameter BW = 4,
+ parameter DW = 32)
+ (
+
+ // Master Port
+ input logic wbm_rst_n , // Regular Reset signal
+ input logic wbm_clk_i , // System clock
+ input logic wbm_cyc_i , // strobe/request
+ input logic wbm_stb_i , // strobe/request
+ input logic [AW-1:0] wbm_adr_i , // address
+ input logic wbm_we_i , // write
+ input logic [DW-1:0] wbm_dat_i , // data output
+ input logic [BW-1:0] wbm_sel_i , // byte enable
+ output logic [DW-1:0] wbm_dat_o , // data input
+ output logic wbm_ack_o , // acknowlegement
+ output logic wbm_err_o , // error
+
+ // Slave Port
+ input logic wbs_rst_n , // Regular Reset signal
+ input logic wbs_clk_i , // System clock
+ output logic wbs_cyc_o , // strobe/request
+ output logic wbs_stb_o , // strobe/request
+ output logic [AW-1:0] wbs_adr_o , // address
+ output logic wbs_we_o , // write
+ output logic [DW-1:0] wbs_dat_o , // data output
+ output logic [BW-1:0] wbs_sel_o , // byte enable
+ input logic [DW-1:0] wbs_dat_i , // data input
+ input logic wbs_ack_i , // acknowlegement
+ input logic wbs_err_i // error
+
+ );
+
+
+
+parameter CFW = AW+DW+BW+1 ; // COMMAND FIFO WIDTH
+
+//-------------------------------------------------
+// Master Interface
+// -------------------------------------------------
+logic PendingRd ; // Pending Read Transaction
+logic m_cmd_wr_en ;
+logic [CFW-1:0] m_cmd_wr_data ;
+logic m_cmd_wr_full ;
+logic m_cmd_wr_afull ;
+
+logic m_resp_rd_empty ;
+logic m_resp_rd_aempty ;
+logic m_resp_rd_en ;
+logic [DW:0] m_resp_rd_data ;
+
+// Master Write Interface
+
+
+assign m_cmd_wr_en = (!PendingRd) && wbm_stb_i && !m_cmd_wr_full && !m_cmd_wr_afull;
+
+assign m_cmd_wr_data = {wbm_adr_i,wbm_we_i,wbm_dat_i,wbm_sel_i};
+
+always@(negedge wbm_rst_n or posedge wbm_clk_i)
+begin
+ if(wbm_rst_n == 0) begin
+ PendingRd <= 1'b0;
+ end else begin
+ if((!PendingRd) && wbm_stb_i && (!wbm_we_i) && m_cmd_wr_en) begin
+ PendingRd <= 1'b1;
+ end else if(PendingRd && wbm_stb_i && (!wbm_we_i) && wbm_ack_o) begin
+ PendingRd <= 1'b0;
+ end
+ end
+end
+
+
+// Master Read Interface
+// For Write is feed through, if there is space in fifo the ack
+// For Read, Wait for Response Path FIFO status
+assign wbm_ack_o = (wbm_stb_i && wbm_we_i) ? m_cmd_wr_en : // Write Logic
+ (wbm_stb_i && (!wbm_we_i)) ? !m_resp_rd_empty : 1'b0; // Read Logic
+
+assign m_resp_rd_en = !m_resp_rd_empty;
+assign wbm_dat_o = m_resp_rd_data[DW-1:0];
+assign wbm_err_o = m_resp_rd_data[DW];
+
+
+//------------------------------
+// Slave Interface
+//-------------------------------
+
+logic [CFW-1:0] s_cmd_rd_data ;
+logic s_cmd_rd_empty ;
+logic s_cmd_rd_aempty ;
+logic s_cmd_rd_en ;
+logic s_resp_wr_en ;
+logic [DW:0] s_resp_wr_data ;
+logic s_resp_wr_full ;
+logic s_resp_wr_afull ;
+logic wbs_ack_f ;
+
+
+always@(negedge wbs_rst_n or posedge wbs_clk_i)
+begin
+ if(wbs_rst_n == 0) begin
+ wbs_ack_f <= 1'b0;
+ end else begin
+ wbs_ack_f <= wbs_ack_i;
+ end
+end
+
+
+// Read Interface
+assign {wbs_adr_o,wbs_we_o,wbs_dat_o,wbs_sel_o} = (s_cmd_rd_empty) ? '0: s_cmd_rd_data;
+// All the downstream logic expect Stobe is getting de-asserted
+// atleast for 1 cycle after ack is generated
+assign wbs_stb_o = (wbs_ack_f) ? 1'b0 : (s_cmd_rd_empty) ? 1'b0: 1'b1;
+assign wbs_cyc_o = (wbs_ack_f) ? 1'b0 : (s_cmd_rd_empty) ? 1'b0: 1'b1;
+
+assign s_cmd_rd_en = wbs_ack_i;
+
+// Write Interface
+// response send only for read logic
+assign s_resp_wr_en = wbs_stb_o & (!wbs_we_o) & wbs_ack_i & !s_resp_wr_full;
+assign s_resp_wr_data = {wbs_err_i,wbs_dat_i};
+
+async_fifo #(.W(CFW), .DP(4), .WR_FAST(1), .RD_FAST(1)) u_cmd_if (
+ // Sync w.r.t WR clock
+ .wr_clk (wbm_clk_i ),
+ .wr_reset_n (wbm_rst_n ),
+ .wr_en (m_cmd_wr_en ),
+ .wr_data (m_cmd_wr_data ),
+ .full (m_cmd_wr_full ),
+ .afull (m_cmd_wr_afull ),
+
+ // Sync w.r.t RD Clock
+ .rd_clk (wbs_clk_i ),
+ .rd_reset_n (wbs_rst_n ),
+ .rd_en (s_cmd_rd_en ),
+ .empty (s_cmd_rd_empty ), // sync'ed to rd_clk
+ .aempty (s_cmd_rd_aempty ), // sync'ed to rd_clk
+ .rd_data (s_cmd_rd_data )
+ );
+
+
+// Response used only read path, read is blocking access, expect
+// only one location used in return path - reduced the depth to 2
+async_fifo #(.W(DW+1), .DP(2), .WR_FAST(1), .RD_FAST(1)) u_resp_if (
+ // Sync w.r.t WR clock
+ .wr_clk (wbs_clk_i ),
+ .wr_reset_n (wbs_rst_n ),
+ .wr_en (s_resp_wr_en ),
+ .wr_data (s_resp_wr_data ),
+ .full (s_resp_wr_full ),
+ .afull (s_resp_wr_afull ),
+
+ // Sync w.r.t RD Clock
+ .rd_clk (wbm_clk_i ),
+ .rd_reset_n (wbm_rst_n ),
+ .rd_en (m_resp_rd_en ),
+ .empty (m_resp_rd_empty ), // sync'ed to rd_clk
+ .aempty (m_resp_rd_aempty ), // sync'ed to rd_clk
+ .rd_data (m_resp_rd_data )
+ );
+
+
+
+endmodule
diff --git a/verilog/rtl/lib/clk_buf.v b/verilog/rtl/lib/clk_buf.v
new file mode 100644
index 0000000..dad8fc6
--- /dev/null
+++ b/verilog/rtl/lib/clk_buf.v
@@ -0,0 +1,85 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Clk Buf ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// Adding clock buf for manual clock tree at SOC level ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module clk_buf (
+ // Outputs
+ clk_o,
+ // Inputs
+ clk_i
+ );
+
+//---------------------------------------------
+// All the input to this block are declared here
+// --------------------------------------------
+ input clk_i ;//
+
+//---------------------------------------------
+// All the output to this block are declared here
+// --------------------------------------------
+ output clk_o ; // clock out
+
+
+
+sky130_fd_sc_hd__clkbuf_16 u_buf (.A(clk_i),.X(clk_o));
+
+endmodule
+
diff --git a/verilog/rtl/lib/clk_ctl.v b/verilog/rtl/lib/clk_ctl.v
new file mode 100644
index 0000000..7e4478b
--- /dev/null
+++ b/verilog/rtl/lib/clk_ctl.v
@@ -0,0 +1,147 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+////////////////////////////////////////////////////////////////////////
+//// ////
+//// Tubo 8051 cores common library Module ////
+//// ////
+//// This file is part of the Turbo 8051 cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//// Description ////
+//// Turbo 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 1.0 Mar 2, 2011,Dinesh.A ////
+//// Initial Version ////
+//// 1.1 Nov 15,2021,Dinesh A ////
+//// Bug fix in High and Low count width ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+// #################################################################
+// Module: clk_ctl
+//
+// Description: Generic clock control logic , clk-out = mclk/(2+clk_div_ratio)
+//
+//
+// #################################################################
+
+
+module clk_ctl (
+ // Outputs
+ clk_o,
+ // Inputs
+ mclk,
+ reset_n,
+ clk_div_ratio
+ );
+
+//---------------------------------
+// CLOCK Default Divider value.
+// This value will be change from outside
+//---------------------------------
+parameter WD = 'h1;
+
+//---------------------------------------------
+// All the input to this block are declared here
+// --------------------------------------------
+ input mclk ;//
+ input reset_n ;// primary reset signal
+ input [WD:0] clk_div_ratio ;// primary clock divide ratio
+ // output clock = selected clock / (div_ratio+1)
+
+//---------------------------------------------
+// All the output to this block are declared here
+// --------------------------------------------
+ output clk_o ; // clock out
+
+
+
+//------------------------------------
+// Clock Divide func is done here
+//------------------------------------
+reg [WD:0] high_count ; // high level counter
+reg [WD:0] low_count ; // low level counter
+reg mclk_div ; // divided clock
+
+
+assign clk_o = mclk_div;
+
+always @ (posedge mclk or negedge reset_n)
+begin // {
+ if(reset_n == 1'b0)
+ begin
+ high_count <= 'h0;
+ low_count <= 'h0;
+ mclk_div <= 'b0;
+ end
+ else
+ begin
+ if(high_count != 0)
+ begin // {
+ high_count <= high_count - 1;
+ mclk_div <= 1'b1;
+ end // }
+ else if(low_count != 0)
+ begin // {
+ low_count <= low_count - 1;
+ mclk_div <= 1'b0;
+ end // }
+ else
+ begin // {
+ high_count <= clk_div_ratio[WD:1] + clk_div_ratio[0];
+ low_count <= clk_div_ratio[WD:1] + 1;
+ mclk_div <= ~mclk_div;
+ end // }
+ end // }
+end // }
+
+
+endmodule
+
diff --git a/verilog/rtl/lib/clk_skew_adjust.gv b/verilog/rtl/lib/clk_skew_adjust.gv
new file mode 100644
index 0000000..fc811c0
--- /dev/null
+++ b/verilog/rtl/lib/clk_skew_adjust.gv
@@ -0,0 +1,205 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// clock skew adjust ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block is useful for global clock skew adjustment ////
+//// logic implementation: ////
+//// clk_out = (sel=0) ? clk_in : ////
+//// (sel=1) ? clk_d1 : ////
+//// (sel=1) ? clk_d2 : ////
+//// ..... ////
+//// (sel=15)? clk_d15 :clk_in ////
+//// ////
+//// Note: each d* indicate clk buf delay ////
+//// ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 29th Feb 2021, Dinesh A ////
+//// Initial version ////
+///
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+// Clock-in is east pad direction
+// clock out give in other three direction for better placement
+/////////////////////////////////////////////////////////////////////
+module clk_skew_adjust(
+`ifdef USE_POWER_PINS
+ vccd1,// User area 1 1.8V supply
+ vssd1,// User area 1 digital ground
+`endif
+clk_in, sel, clk_out);
+
+
+`ifdef USE_POWER_PINS
+ input vccd1;// User area 1 1.8V supply
+ input vssd1;// User area 1 digital ground
+`endif
+ input clk_in;
+ output clk_out;
+ input [3:0] sel;
+ wire in0;
+ wire in1;
+ wire in2;
+ wire in3;
+ wire in4;
+ wire in5;
+ wire in6;
+ wire in7;
+ wire in8;
+ wire in9;
+ wire in10;
+ wire in11;
+ wire in12;
+ wire in13;
+ wire in14;
+ wire in15;
+
+ wire clk_d1;
+ wire clk_d2;
+ wire clk_d3;
+ wire clk_d4;
+ wire clk_d5;
+ wire clk_d6;
+ wire clk_d7;
+ wire clk_d8;
+ wire clk_d9;
+ wire clk_d10;
+ wire clk_d11;
+ wire clk_d12;
+ wire clk_d13;
+ wire clk_d14;
+ wire clk_d15;
+
+ wire d00;
+ wire d01;
+ wire d02;
+ wire d03;
+ wire d04;
+ wire d05;
+ wire d06;
+ wire d07;
+ wire d10;
+ wire d11;
+ wire d12;
+ wire d13;
+ wire d20;
+ wire d21;
+ wire d30;
+
+
+ ctech_delay_clkbuf clkbuf_1 (.A(clk_in), .X(clk_d1));
+ ctech_delay_clkbuf clkbuf_2 (.A(clk_d1), .X(clk_d2));
+ ctech_delay_clkbuf clkbuf_3 (.A(clk_d2), .X(clk_d3));
+ ctech_delay_clkbuf clkbuf_4 (.A(clk_d3), .X(clk_d4));
+ ctech_delay_clkbuf clkbuf_5 (.A(clk_d4), .X(clk_d5));
+ ctech_delay_clkbuf clkbuf_6 (.A(clk_d5), .X(clk_d6));
+ ctech_delay_clkbuf clkbuf_7 (.A(clk_d6), .X(clk_d7));
+ ctech_delay_clkbuf clkbuf_8 (.A(clk_d7), .X(clk_d8));
+ ctech_delay_clkbuf clkbuf_9 (.A(clk_d8), .X(clk_d9));
+ ctech_delay_clkbuf clkbuf_10 (.A(clk_d9), .X(clk_d10));
+ ctech_delay_clkbuf clkbuf_11 (.A(clk_d10), .X(clk_d11));
+ ctech_delay_clkbuf clkbuf_12 (.A(clk_d11), .X(clk_d12));
+ ctech_delay_clkbuf clkbuf_13 (.A(clk_d12), .X(clk_d13));
+ ctech_delay_clkbuf clkbuf_14 (.A(clk_d13), .X(clk_d14));
+ ctech_delay_clkbuf clkbuf_15 (.A(clk_d14), .X(clk_d15));
+
+
+ // Tap point selection
+ assign in0 = clk_in;
+ assign in1 = clk_d1;
+ assign in2 = clk_d2;
+ assign in3 = clk_d3;
+ assign in4 = clk_d4;
+ assign in5 = clk_d5;
+ assign in6 = clk_d6;
+ assign in7 = clk_d7;
+ assign in8 = clk_d8;
+ assign in9 = clk_d9;
+ assign in10 = clk_d10;
+ assign in11 = clk_d11;
+ assign in12 = clk_d12;
+ assign in13 = clk_d13;
+ assign in14 = clk_d14;
+ assign in15 = clk_d15;
+
+
+ // first level mux - 8
+ ctech_mux2x1_2 u_mux_level_00 ( .X (d00) , .A0 (in0), .A1(in1), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_01 ( .X (d01) , .A0 (in2), .A1(in3), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_02 ( .X (d02) , .A0 (in4), .A1(in5), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_03 ( .X (d03) , .A0 (in6), .A1(in7), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_04 ( .X (d04) , .A0 (in8), .A1(in9), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_05 ( .X (d05) , .A0 (in10), .A1(in11), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_06 ( .X (d06) , .A0 (in12), .A1(in13), .S(sel[0]));
+ ctech_mux2x1_2 u_mux_level_07 ( .X (d07) , .A0 (in14), .A1(in15), .S(sel[0]));
+
+ // second level mux - 4
+ ctech_mux2x1_2 u_mux_level_10 ( .X (d10) , .A0 (d00), .A1(d01), .S(sel[1]));
+ ctech_mux2x1_2 u_mux_level_11 ( .X (d11) , .A0 (d02), .A1(d03), .S(sel[1]));
+ ctech_mux2x1_2 u_mux_level_12 ( .X (d12) , .A0 (d04), .A1(d05), .S(sel[1]));
+ ctech_mux2x1_2 u_mux_level_13 ( .X (d13) , .A0 (d06), .A1(d07), .S(sel[1]));
+
+ // third level mux - 2
+ ctech_mux2x1_2 u_mux_level_20 ( .X (d20) , .A0 (d10), .A1(d11), .S(sel[2]));
+ ctech_mux2x1_2 u_mux_level_21 ( .X (d21) , .A0 (d12), .A1(d13), .S(sel[2]));
+
+ // fourth level mux - 1
+ ctech_mux2x1_4 u_mux_level_30 ( .X (d30) , .A0 (d20), .A1(d21), .S(sel[3]));
+
+
+ assign clk_out = d30;
+
+endmodule
diff --git a/verilog/rtl/lib/ctech_cells.sv b/verilog/rtl/lib/ctech_cells.sv
new file mode 100644
index 0000000..c9528de
--- /dev/null
+++ b/verilog/rtl/lib/ctech_cells.sv
@@ -0,0 +1,90 @@
+
+module ctech_mux2x1 (
+ input logic A0,
+ input logic A1,
+ input logic S ,
+ output logic X);
+
+`ifndef SYNTHESIS
+assign X = (S) ? A1 : A0;
+`else
+sky130_fd_sc_hd__mux2_8 u_mux (.A0 (A0), .A1 (A1), .S (S), .X (X));
+`endif
+
+endmodule
+
+module ctech_mux2x1_2 (
+ input logic A0,
+ input logic A1,
+ input logic S ,
+ output logic X);
+
+`ifndef SYNTHESIS
+assign X = (S) ? A1 : A0;
+`else
+sky130_fd_sc_hd__mux2_2 u_mux (.A0 (A0), .A1 (A1), .S (S), .X (X));
+`endif
+
+endmodule
+
+module ctech_mux2x1_4 (
+ input logic A0,
+ input logic A1,
+ input logic S ,
+ output logic X);
+
+`ifndef SYNTHESIS
+assign X = (S) ? A1 : A0;
+`else
+sky130_fd_sc_hd__mux2_4 u_mux (.A0 (A0), .A1 (A1), .S (S), .X (X));
+`endif
+
+endmodule
+
+module ctech_buf (
+ input logic A,
+ output logic X);
+
+`ifndef SYNTHESIS
+assign X = A;
+`else
+ sky130_fd_sc_hd__bufbuf_8 u_buf (.A(A),.X(X));
+`endif
+
+endmodule
+
+module ctech_clk_buf (
+ input logic A,
+ output logic X);
+
+`ifndef SYNTHESIS
+assign X = A;
+`else
+ sky130_fd_sc_hd__clkbuf_8 u_buf (.A(A),.X(X));
+`endif
+
+endmodule
+
+module ctech_delay_buf (
+ input logic A,
+ output logic X);
+
+`ifndef SYNTHESIS
+ assign X = A;
+`else
+ sky130_fd_sc_hd__dlygate4sd3_1 u_dly (.X(X),.A(A));
+`endif
+
+endmodule
+
+module ctech_delay_clkbuf (
+ input logic A,
+ output logic X);
+
+`ifndef SYNTHESIS
+ assign X = A;
+`else
+ sky130_fd_sc_hd__clkdlybuf4s15_2 u_dly (.X(X),.A(A));
+`endif
+
+endmodule
diff --git a/verilog/rtl/lib/double_sync_high.v b/verilog/rtl/lib/double_sync_high.v
new file mode 100755
index 0000000..d1d2ca6
--- /dev/null
+++ b/verilog/rtl/lib/double_sync_high.v
@@ -0,0 +1,106 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// OMS 8051 cores common library Module ////
+//// ////
+//// This file is part of the OMS 8051 cores project ////
+//// http://www.opencores.org/cores/oms8051mini/ ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// ////
+//// Description ////
+//// OMS 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Nov 26, 2016 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//----------------------------------------------------------------------------
+// Simple Double sync logic with Reset value = 0
+// This double signal should be used for signal transiting from low to high
+//----------------------------------------------------------------------------
+
+module double_sync_high (
+ in_data ,
+ out_clk ,
+ out_rst_n ,
+ out_data
+ );
+
+parameter WIDTH = 1;
+
+input [WIDTH-1:0] in_data ; // Input from Different clock domain
+input out_clk ; // Output clock
+input out_rst_n ; // Active low Reset
+output[WIDTH-1:0] out_data ; // Output Data
+
+
+reg [WIDTH-1:0] in_data_s ; // One Cycle sync
+reg [WIDTH-1:0] in_data_2s ; // two Cycle sync
+reg [WIDTH-1:0] in_data_3s ; // three Cycle sync
+
+assign out_data = in_data_3s;
+
+always @(negedge out_rst_n or posedge out_clk)
+begin
+ if(out_rst_n == 1'b0)
+ begin
+ in_data_s <= {WIDTH{1'b0}};
+ in_data_2s <= {WIDTH{1'b0}};
+ in_data_3s <= {WIDTH{1'b0}};
+ end
+ else
+ begin
+ in_data_s <= in_data;
+ in_data_2s <= in_data_s;
+ in_data_3s <= in_data_2s;
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/lib/double_sync_low.v b/verilog/rtl/lib/double_sync_low.v
new file mode 100755
index 0000000..efd4269
--- /dev/null
+++ b/verilog/rtl/lib/double_sync_low.v
@@ -0,0 +1,106 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// OMS 8051 cores common library Module ////
+//// ////
+//// This file is part of the OMS 8051 cores project ////
+//// http://www.opencores.org/cores/oms8051mini/ ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// ////
+//// Description ////
+//// OMS 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Nov 26, 2016 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//----------------------------------------------------------------------------
+// Simple Double sync logic with Reset value = 1
+// This double signal should be used for signal transiting from low to high
+//----------------------------------------------------------------------------
+
+module double_sync_low (
+ in_data ,
+ out_clk ,
+ out_rst_n ,
+ out_data
+ );
+
+parameter WIDTH = 1;
+
+input [WIDTH-1:0] in_data ; // Input from Different clock domain
+input out_clk ; // Output clock
+input out_rst_n ; // Active low Reset
+output[WIDTH-1:0] out_data ; // Output Data
+
+
+reg [WIDTH-1:0] in_data_s ; // One Cycle sync
+reg [WIDTH-1:0] in_data_2s ; // two Cycle sync
+reg [WIDTH-1:0] in_data_3s ; // three Cycle sync
+
+assign out_data = in_data_3s;
+
+always @(negedge out_rst_n or posedge out_clk)
+begin
+ if(out_rst_n == 1'b0)
+ begin
+ in_data_s <= {WIDTH{1'b1}};
+ in_data_2s <= {WIDTH{1'b1}};
+ in_data_3s <= {WIDTH{1'b1}};
+ end
+ else
+ begin
+ in_data_s <= in_data;
+ in_data_2s <= in_data_s;
+ in_data_3s <= in_data_2s;
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/lib/pulse_gen_type1.sv b/verilog/rtl/lib/pulse_gen_type1.sv
new file mode 100644
index 0000000..838fe03
--- /dev/null
+++ b/verilog/rtl/lib/pulse_gen_type1.sv
@@ -0,0 +1,37 @@
+
+//------------------------------------------------------------------------
+// This module is used to generate 1ms and 1sec pulse based on 1us trigger
+// pulse
+//------------------------------------------------------------------------
+
+module pulse_gen_type1(
+ output logic clk_pulse,
+
+ input logic clk,
+ input logic reset_n,
+ input logic trigger
+);
+
+parameter WD= 10; // This will count from 0 to 1023
+parameter MAX_CNT = 999;
+
+logic [WD-1:0] cnt;
+
+assign clk_pulse = (cnt == 0) && trigger;
+
+always @ (posedge clk or negedge reset_n)
+begin
+ if (reset_n == 1'b0) begin
+ cnt <= 'b0;
+ end else begin
+ if(trigger) begin
+ if(cnt >= MAX_CNT)
+ cnt <= 0;
+ else
+ cnt <= cnt +1;
+ end
+ end
+end
+
+endmodule
+
diff --git a/verilog/rtl/lib/pulse_gen_type2.sv b/verilog/rtl/lib/pulse_gen_type2.sv
new file mode 100644
index 0000000..9bc759e
--- /dev/null
+++ b/verilog/rtl/lib/pulse_gen_type2.sv
@@ -0,0 +1,36 @@
+
+//------------------------------------------------------------------------
+// This module is used to generate 1us based on config value
+//------------------------------------------------------------------------
+
+module pulse_gen_type2 #(parameter WD = 10)
+ (
+ output logic clk_pulse,
+
+ input logic clk,
+ input logic reset_n,
+ input logic [WD-1:0] cfg_max_cnt
+);
+
+
+logic [WD-1:0] cnt;
+
+
+always @ (posedge clk or negedge reset_n)
+begin
+ if (reset_n == 1'b0) begin
+ cnt <= 'b0;
+ clk_pulse <= 'b0;
+ end else begin
+ if(cnt == cfg_max_cnt) begin
+ cnt <= 0;
+ clk_pulse <= 1'b1;
+ end else begin
+ cnt <= cnt +1;
+ clk_pulse <= 1'b0;
+ end
+ end
+end
+
+endmodule
+
diff --git a/verilog/rtl/lib/registers.v b/verilog/rtl/lib/registers.v
new file mode 100755
index 0000000..e4a87a1
--- /dev/null
+++ b/verilog/rtl/lib/registers.v
@@ -0,0 +1,329 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Tubo 8051 cores common library Module ////
+//// ////
+//// This file is part of the Turbo 8051 cores project ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//// Description ////
+//// Turbo 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : Mar 2, 2011 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+/*********************************************************************
+** module: bit register
+
+** description: infers a register, make it modular
+ ***********************************************************************/
+module bit_register (
+ //inputs
+ we,
+ clk,
+ reset_n,
+ data_in,
+
+ //outputs
+ data_out
+ );
+
+//---------------------------------
+// Reset Default value
+//---------------------------------
+parameter RESET_DEFAULT = 1'h0;
+
+ input we;
+ input clk;
+ input reset_n;
+ input data_in;
+ output data_out;
+
+ reg data_out;
+
+ //infer the register
+ always @(posedge clk or negedge reset_n)
+ begin
+ if (!reset_n)
+ data_out <= RESET_DEFAULT;
+ else if (we)
+ data_out <= data_in;
+ end // always @ (posedge clk or negedge reset_n)
+endmodule // register
+
+
+/*********************************************************************
+** module: req register.
+
+** description: This register is set by cpu writting 1 and reset by
+ harward req = 1
+
+ Note: When there is a clash between cpu and hardware, cpu is given higher
+ priority
+
+ ***********************************************************************/
+module req_register (
+ //inputs
+ clk,
+ reset_n,
+ cpu_we,
+ cpu_req,
+ hware_ack,
+
+ //outputs
+ data_out
+ );
+
+//---------------------------------
+// Reset Default value
+//---------------------------------
+parameter RESET_DEFAULT = 1'h0;
+
+ input clk ;
+ input reset_n ;
+ input cpu_we ; // cpu write enable
+ input cpu_req ; // CPU Request
+ input hware_ack; // Hardware Ack
+ output data_out ;
+
+ reg data_out;
+
+ //infer the register
+ always @(posedge clk or negedge reset_n)
+ begin
+ if (!reset_n)
+ data_out <= RESET_DEFAULT;
+ else if (cpu_we & cpu_req) // Set on CPU Request
+ data_out <= 1'b1;
+ else if (hware_ack) // Reset the flag on Hardware ack
+ data_out <= 1'b0;
+ end // always @ (posedge clk or negedge reset_n)
+endmodule // register
+
+
+/*********************************************************************
+** module: req register.
+
+** description: This register is cleared by cpu writting 1 and set by
+ harward req = 1
+
+ Note: When there is a clash between cpu and hardware,
+ hardware is given higher priority
+
+ ***********************************************************************/
+module stat_register (
+ //inputs
+ clk,
+ reset_n,
+ cpu_we,
+ cpu_ack,
+ hware_req,
+
+ //outputs
+ data_out
+ );
+
+//---------------------------------
+// Reset Default value
+//---------------------------------
+parameter RESET_DEFAULT = 1'h0;
+
+ input clk ;
+ input reset_n ;
+ input cpu_we ; // cpu write enable
+ input cpu_ack ; // CPU Ack
+ input hware_req; // Hardware Req
+ output data_out ;
+
+ reg data_out;
+
+ //infer the register
+ always @(posedge clk or negedge reset_n)
+ begin
+ if (!reset_n)
+ data_out <= RESET_DEFAULT;
+ else if (hware_req) // Set the flag on Hardware Req
+ data_out <= 1'b1;
+ else if (cpu_we & cpu_ack) // Clear on CPU Ack
+ data_out <= 1'b0;
+ end // always @ (posedge clk or negedge reset_n)
+endmodule // register
+
+
+
+
+
+/*********************************************************************
+ module: generic register
+***********************************************************************/
+module generic_register (
+ //List of Inputs
+ we,
+ data_in,
+ reset_n,
+ clk,
+
+ //List of Outs
+ data_out
+ );
+
+ parameter WD = 1;
+ parameter RESET_DEFAULT = 0;
+ input [WD-1:0] we;
+ input [WD-1:0] data_in;
+ input reset_n;
+ input clk;
+ output [WD-1:0] data_out;
+
+
+generate
+ genvar i;
+ for (i = 0; i < WD; i = i + 1) begin : gen_bit_reg
+ bit_register #(RESET_DEFAULT[i]) u_bit_reg (
+ .we (we[i]),
+ .clk (clk),
+ .reset_n (reset_n),
+ .data_in (data_in[i]),
+ .data_out (data_out[i])
+ );
+ end
+endgenerate
+
+
+endmodule
+
+
+/*********************************************************************
+ module: generic interrupt status
+***********************************************************************/
+module generic_intr_stat_reg (
+ //inputs
+ clk,
+ reset_n,
+ reg_we,
+ reg_din,
+ hware_req,
+
+ //outputs
+ data_out
+ );
+
+ parameter WD = 1;
+ parameter RESET_DEFAULT = 0;
+ input [WD-1:0] reg_we;
+ input [WD-1:0] reg_din;
+ input [WD-1:0] hware_req;
+ input reset_n;
+ input clk;
+ output [WD-1:0] data_out;
+
+
+generate
+ genvar i;
+ for (i = 0; i < WD; i = i + 1) begin : gen_bit_reg
+ stat_register #(RESET_DEFAULT[i]) u_bit_reg (
+ //inputs
+ . clk (clk ),
+ . reset_n (reset_n ),
+ . cpu_we (reg_we[i] ),
+ . cpu_ack (reg_din[i] ),
+ . hware_req (hware_req[i] ),
+
+ //outputs
+ . data_out (data_out[i] )
+ );
+
+ end
+endgenerate
+
+
+endmodule
+
+/*********************************************************************
+ module: generic 32b register
+***********************************************************************/
+module gen_32b_reg (
+ //List of Inputs
+ cs,
+ we,
+ data_in,
+ reset_n,
+ clk,
+
+ //List of Outs
+ data_out
+ );
+
+ parameter RESET_DEFAULT = 32'h0;
+ input [3:0] we;
+ input cs;
+ input [31:0] data_in;
+ input reset_n;
+ input clk;
+ output [31:0] data_out;
+
+
+ reg [31:0] data_out;
+
+always @ (posedge clk or negedge reset_n) begin
+ if (reset_n == 1'b0) begin
+ data_out <= RESET_DEFAULT ;
+ end
+ else begin
+ if(cs && we[0]) data_out[7:0] <= data_in[7:0];
+ if(cs && we[1]) data_out[15:8] <= data_in[15:8];
+ if(cs && we[2]) data_out[23:16] <= data_in[23:16];
+ if(cs && we[3]) data_out[31:24] <= data_in[31:24];
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/lib/reset_sync.sv b/verilog/rtl/lib/reset_sync.sv
new file mode 100644
index 0000000..d96c719
--- /dev/null
+++ b/verilog/rtl/lib/reset_sync.sv
@@ -0,0 +1,101 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Active low reset synchronization ////
+//// ////
+//// This file is part of the yifive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description: ////
+//// Synchronize the active low reset to destination clock ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// v0: June 17, 2021, Dinesh A ////
+//// Initial version ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module reset_sync (
+ scan_mode ,
+ dclk , // Destination clock domain
+ arst_n , // active low async reset
+ srst_n
+ );
+
+parameter WIDTH = 1;
+
+input scan_mode ; // test mode
+input dclk ; // Destination clock
+input arst_n ; // Async Reset
+output srst_n ; // Sync Reset w.r.t dclk
+
+
+reg in_data_s ; // One Cycle sync
+reg in_data_2s ; // two Cycle sync
+
+assign srst_n = (scan_mode) ? arst_n : in_data_2s;
+
+always @(negedge arst_n or posedge dclk)
+begin
+ if(arst_n == 1'b0)
+ begin
+ in_data_s <= 1'b0;
+ in_data_2s <= 1'b0;
+ end
+ else
+ begin
+ in_data_s <= 1'b1;
+ in_data_2s <= in_data_s;
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/lib/ser_inf_32b.sv b/verilog/rtl/lib/ser_inf_32b.sv
new file mode 100644
index 0000000..8228852
--- /dev/null
+++ b/verilog/rtl/lib/ser_inf_32b.sv
@@ -0,0 +1,121 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ser_inf_32 ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block manages the serial to Parallel conversion ////
+//// This block usefull for Bist SDI/SDO access ////
+//// Function: ////
+//// 1. When reg_wr=1, this block set shift=1 and shift ////
+//// reg_wdata serial through sdi for 32 cycles and ////
+//// asserts Reg Ack ////
+//// 2. When reg_rd=1, this block set shoft=1 and serial ////
+//// capture the sdo to reg_rdata for 32 cycles and ////
+//// asserts Reg Ack ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 20th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module ser_inf_32b
+ (
+
+ // Master Port
+ input logic rst_n , // Regular Reset signal
+ input logic clk , // System clock
+ input logic reg_wr , // Write Request
+ input logic reg_rd , // Read Request
+ input logic [31:0] reg_wdata , // data output
+ output logic [31:0] reg_rdata , // data input
+ output logic reg_ack , // acknowlegement
+
+ // Slave Port
+ output logic sdi , // Serial SDI
+ output logic shift , // Shift Signal
+ input logic sdo // Serial SDO
+
+ );
+
+
+ parameter IDLE = 1'b0;
+ parameter SHIFT_DATA = 1'b1;
+
+ logic state;
+ logic [5:0] bit_cnt;
+ logic [31:0] shift_data;
+
+
+always@(negedge rst_n or posedge clk)
+begin
+ if(rst_n == 0) begin
+ state <= IDLE;
+ reg_rdata <= 'h0;
+ reg_ack <= 1'b0;
+ sdi <= 1'b0;
+ bit_cnt <= 6'h0;
+ shift <= 'b0;
+ shift_data <= 32'h0;
+ end else begin
+ case(state)
+ IDLE: begin
+ reg_ack <= 1'b0;
+ bit_cnt <= 6'h0;
+ if(reg_wr) begin
+ shift <= 'b1;
+ shift_data <= reg_wdata;
+ state <= SHIFT_DATA;
+ end else if(reg_rd) begin
+ shift <= 'b1;
+ shift_data <= 'h0;
+ state <= SHIFT_DATA;
+ end
+ end
+ SHIFT_DATA: begin
+ shift_data <= {1'b0,shift_data[31:1]};
+ reg_rdata <= {sdo,reg_rdata[31:1]};
+ sdi <= shift_data[0];
+ if(bit_cnt < 31) begin
+ bit_cnt <= bit_cnt +1;
+ end else begin
+ reg_ack <= 1'b1;
+ shift <= 'b0;
+ state <= IDLE;
+ end
+ end
+ endcase
+ end
+end
+
+
+
+
+endmodule
diff --git a/verilog/rtl/lib/ser_shift.sv b/verilog/rtl/lib/ser_shift.sv
new file mode 100644
index 0000000..21ef9dc
--- /dev/null
+++ b/verilog/rtl/lib/ser_shift.sv
@@ -0,0 +1,76 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ser_shift ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/riscdunio.git ////
+//// ////
+//// Description ////
+//// This block manages the parallel to serial conversion ////
+//// This block usefull for Bist SDI/SDO access ////
+//// asserts Reg Ack ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 16th Dec 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module ser_shift
+ #(parameter WD = 32)
+ (
+
+ // Master Port
+ input logic rst_n , // Regular Reset signal
+ input logic clk , // System clock
+ input logic load , // load request
+ input logic shift , // shift
+ input logic [WD-1:0] load_data , // load data
+ input logic sdi , // sdi
+ output logic sdo // sdo
+
+
+ );
+
+logic [WD-1:0] shift_reg;
+
+always@(negedge rst_n or posedge clk)
+begin
+ if(rst_n == 0) begin
+ shift_reg <= 'h0;
+ end else if(load) begin
+ shift_reg <= load_data;
+ end else if(shift) begin
+ shift_reg <= {sdi,shift_reg[WD-1:1]};
+ end
+end
+
+assign sdo = shift_reg[0];
+
+
+
+endmodule
diff --git a/verilog/rtl/lib/sync_fifo.sv b/verilog/rtl/lib/sync_fifo.sv
new file mode 100644
index 0000000..464a26c
--- /dev/null
+++ b/verilog/rtl/lib/sync_fifo.sv
@@ -0,0 +1,167 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+/*********************************************************************
+
+ This file is part of the sdram controller project
+ http://www.opencores.org/cores/sdr_ctrl/
+ https://github.com/dineshannayya/yifive_r0.git
+
+ Description: SYNC FIFO
+ Parameters:
+ W : Width (integer)
+ D : Depth (integer, power of 2, 4 to 256)
+
+ To Do:
+ nothing
+
+ Author(s): Dinesh Annayya, dinesha@opencores.org
+
+ Copyright (C) 2000 Authors and OPENCORES.ORG
+
+ This source file may be used and distributed without
+ restriction provided that this copyright statement is not
+ removed from the file and that any derivative work contains
+ the original copyright notice and the associated disclaimer.
+
+ This source file is free software; you can redistribute it
+ and/or modify it under the terms of the GNU Lesser General
+ Public License as published by the Free Software Foundation;
+ either version 2.1 of the License, or (at your option) any
+later version.
+
+ This source is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the GNU Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this source; if not, download it
+ from http://www.opencores.org/lgpl.shtml
+
+*******************************************************************/
+
+
+module sync_fifo (clk,
+ reset_n,
+ wr_en,
+ wr_data,
+ full,
+ empty,
+ rd_en,
+ rd_data);
+
+ parameter W = 8;
+ parameter D = 4;
+
+ parameter AW = (D == 2) ? 1 :
+ (D == 4) ? 2 :
+ (D == 8) ? 3 :
+ (D == 16) ? 4 :
+ (D == 32) ? 5 :
+ (D == 64) ? 6 :
+ (D == 128) ? 7 :
+ (D == 256) ? 8 : 0;
+
+ output [W-1 : 0] rd_data;
+ input [W-1 : 0] wr_data;
+ input clk, reset_n, wr_en, rd_en;
+ output full, empty;
+
+ // synopsys translate_off
+
+ initial begin
+ if (AW == 0) begin
+ $display ("%m : ERROR!!! Fifo depth %d not in range 4 to 256", D);
+ end // if (AW == 0)
+ end // initial begin
+
+ // synopsys translate_on
+
+
+ reg [W-1 : 0] mem[D-1 : 0];
+ reg [AW-1 : 0] rd_ptr, wr_ptr;
+ reg full, empty;
+
+ wire [W-1 : 0] rd_data;
+
+ always @ (posedge clk or negedge reset_n)
+ if (reset_n == 1'b0) begin
+ wr_ptr <= {AW{1'b0}} ;
+ end
+ else begin
+ if (wr_en & !full) begin
+ wr_ptr <= wr_ptr + 1'b1 ;
+ end
+ end
+
+ always @ (posedge clk or negedge reset_n)
+ if (reset_n == 1'b0) begin
+ rd_ptr <= {AW{1'b0}} ;
+ end
+ else begin
+ if (rd_en & !empty) begin
+ rd_ptr <= rd_ptr + 1'b1 ;
+ end
+ end
+
+
+ always @ (posedge clk or negedge reset_n)
+ if (reset_n == 1'b0) begin
+ empty <= 1'b1 ;
+ end
+ else begin
+ empty <= (((wr_ptr - rd_ptr) == {{(AW-1){1'b0}}, 1'b1}) & rd_en & ~wr_en) ? 1'b1 :
+ ((wr_ptr == rd_ptr) & ~rd_en & wr_en) ? 1'b0 : empty ;
+ end
+
+ always @ (posedge clk or negedge reset_n)
+ if (reset_n == 1'b0) begin
+ full <= 1'b0 ;
+ end
+ else begin
+ full <= (((wr_ptr - rd_ptr) == {{(AW-1){1'b1}}, 1'b0}) & ~rd_en & wr_en) ? 1'b1 :
+ (((wr_ptr - rd_ptr) == {AW{1'b1}}) & rd_en & ~wr_en) ? 1'b0 : full ;
+ end
+
+ always @ (posedge clk)
+ if (wr_en)
+ mem[wr_ptr] <= wr_data;
+
+assign rd_data = mem[rd_ptr];
+
+
+// synopsys translate_off
+ always @(posedge clk) begin
+ if (wr_en && full) begin
+ $display("%m : Error! sfifo overflow!");
+ end
+ end
+
+ always @(posedge clk) begin
+ if (rd_en && empty) begin
+ $display("%m : error! sfifo underflow!");
+ end
+ end
+
+// synopsys translate_on
+//---------------------------------------
+
+endmodule
+
+
diff --git a/verilog/rtl/lib/sync_fifo2.sv b/verilog/rtl/lib/sync_fifo2.sv
new file mode 100755
index 0000000..f71ad30
--- /dev/null
+++ b/verilog/rtl/lib/sync_fifo2.sv
@@ -0,0 +1,222 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+/*********************************************************************
+
+ SYNC FIFO with empty,aempty,full,afull
+
+
+ Description: SYNC FIFO
+
+ To Do:
+ nothing
+
+ Author(s): Dinesh Annayya, dinesha@opencores.org
+
+ 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
+
+*******************************************************************/
+
+//-------------------------------------------
+// sync FIFO
+//-----------------------------------------------
+//`timescale 1ns/1ps
+
+module sync_fifo2 (clk,
+ reset_n,
+ wr_en,
+ wr_data,
+ full,
+ afull,
+ rd_en,
+ empty,
+ aempty,
+ rd_data);
+
+ parameter W = 4'd8;
+ parameter DP = 3'd4;
+ parameter WR_FAST = 1'b1;
+ parameter RD_FAST = 1'b1;
+ parameter FULL_DP = DP;
+ parameter EMPTY_DP = 1'b0;
+
+ parameter AW = (DP == 2) ? 1 :
+ (DP == 4) ? 2 :
+ (DP == 8) ? 3 :
+ (DP == 16) ? 4 :
+ (DP == 32) ? 5 :
+ (DP == 64) ? 6 :
+ (DP == 128) ? 7 :
+ (DP == 256) ? 8 : 0;
+
+ output [W-1 : 0] rd_data;
+ input [W-1 : 0] wr_data;
+ input clk, reset_n, wr_en, rd_en;
+ output full, empty;
+ output afull, aempty; // about full and about to empty
+
+
+ // synopsys translate_off
+
+ initial begin
+ if (AW == 0) begin
+ $display ("%m : ERROR!!! Fifo depth %d not in range 2 to 256", DP);
+ end // if (AW == 0)
+ end // initial begin
+
+ // synopsys translate_on
+
+ reg [W-1 : 0] mem[DP-1 : 0];
+
+ /*********************** write side ************************/
+ reg [AW:0] wr_ptr;
+ reg full_q;
+ wire full_c;
+ wire afull_c;
+ wire [AW:0]wr_ptr_inc = wr_ptr + 1'b1;
+ wire [AW:0]wr_cnt = get_cnt(wr_ptr, rd_ptr);
+
+ assign full_c = (wr_cnt == FULL_DP) ? 1'b1 : 1'b0;
+ assign afull_c = (wr_cnt == FULL_DP-1) ? 1'b1 : 1'b0;
+
+
+ always @(posedge clk or negedge reset_n) begin
+ if (!reset_n) begin
+ wr_ptr <= 0;
+ full_q <= 0;
+ end
+ else if (wr_en) begin
+ wr_ptr <= wr_ptr_inc;
+ if (wr_cnt == (FULL_DP-1)) begin
+ full_q <= 1'b1;
+ end
+ end
+ else begin
+ if (full_q && (wr_cnt<FULL_DP)) begin
+ full_q <= 1'b0;
+ end
+ end
+ end
+
+ assign full = (WR_FAST == 1) ? full_c : full_q;
+ assign afull = afull_c;
+
+ always @(posedge clk) begin
+ if (wr_en) begin
+ mem[wr_ptr[AW-1:0]] <= wr_data;
+ end
+ end
+
+
+
+ /************************ read side *****************************/
+ reg [AW:0] rd_ptr;
+ reg empty_q;
+ wire empty_c;
+ wire aempty_c;
+ wire [AW:0] rd_ptr_inc = rd_ptr + 1'b1;
+ wire [AW:0] rd_cnt = get_cnt(wr_ptr, rd_ptr);
+
+ assign empty_c = (rd_cnt == 0) ? 1'b1 : 1'b0;
+ assign aempty_c = (rd_cnt == 1) ? 1'b1 : 1'b0;
+
+ always @(posedge clk or negedge reset_n) begin
+ if (!reset_n) begin
+ rd_ptr <= 0;
+ empty_q <= 1'b1;
+ end
+ else begin
+ if (rd_en) begin
+ rd_ptr <= rd_ptr_inc;
+ if (rd_cnt==(EMPTY_DP+1)) begin
+ empty_q <= 1'b1;
+ end
+ end
+ else begin
+ if (empty_q && (rd_cnt!=EMPTY_DP)) begin
+ empty_q <= 1'b0;
+ end
+ end
+ end
+ end
+
+ assign empty = (RD_FAST == 1) ? empty_c : empty_q;
+ assign aempty = aempty_c;
+
+ reg [W-1 : 0] rd_data_q;
+
+ wire [W-1 : 0] rd_data_c = mem[rd_ptr[AW-1:0]];
+
+
+ always @(posedge clk) begin
+ rd_data_q <= rd_data_c;
+ end
+ assign rd_data = (RD_FAST == 1) ? rd_data_c : rd_data_q;
+
+
+
+
+function [AW:0] get_cnt;
+input [AW:0] wr_ptr, rd_ptr;
+begin
+ if (wr_ptr >= rd_ptr) begin
+ get_cnt = (wr_ptr - rd_ptr);
+ end
+ else begin
+ get_cnt = DP*2 - (rd_ptr - wr_ptr);
+ end
+end
+endfunction
+
+// synopsys translate_off
+always @(posedge clk) begin
+ if (wr_en && full) begin
+ $display($time, "%m Error! afifo overflow!");
+ $stop;
+ end
+end
+
+always @(posedge clk) begin
+ if (rd_en && empty) begin
+ $display($time, "%m error! afifo underflow!");
+ $stop;
+ end
+end
+// synopsys translate_on
+
+endmodule
diff --git a/verilog/rtl/lib/sync_wbb.sv b/verilog/rtl/lib/sync_wbb.sv
new file mode 100644
index 0000000..e2cc794
--- /dev/null
+++ b/verilog/rtl/lib/sync_wbb.sv
@@ -0,0 +1,336 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// sync Wishbone Interface iBurst Enable and lack ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block does async Wishbone from one clock to other ////
+//// clock domain
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 25th Feb 2021, Dinesh A ////
+//// initial version ////
+//// 0.2 - 28th Feb 2021, Dinesh A ////
+//// reduced the response FIFO path depth to 2 as ////
+//// return path used by only read logic and read is ////
+//// blocking request and expect only one location will ////
+//// be used ////
+//// 0.3 - 20 Jan 2022, Dinesh A ////
+//// added wishbone burst mode. Additional signal added ////
+//// A. *bl - 10 Bit word Burst count, 1 - 1 DW(32 bit)////
+//// B. *lack - Last Burst ack ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module sync_wbb
+ #(parameter AW = 32,
+ parameter BW = 4,
+ parameter BL = 10,
+ parameter DW = 32)
+ (
+
+ // Master Port
+ input logic rst_n , // Regular Reset signal
+ input logic clk_i , // System clock
+ input logic wbm_cyc_i , // strobe/request
+ input logic wbm_stb_i , // strobe/request
+ input logic [AW-1:0] wbm_adr_i , // address
+ input logic wbm_we_i , // write
+ input logic [DW-1:0] wbm_dat_i , // data output
+ input logic [BW-1:0] wbm_sel_i , // byte enable
+ input logic [3:0] wbm_tid_i ,
+ input logic [BL-1:0] wbm_bl_i , // Burst Count
+ input logic wbm_bry_i , // Burst Ready
+ output logic [DW-1:0] wbm_dat_o , // data input
+ output logic wbm_ack_o , // acknowlegement
+ output logic wbm_lack_o , // Last Burst access
+ output logic wbm_err_o , // error
+
+ // Slave Port
+ output logic wbs_cyc_o , // strobe/request
+ output logic wbs_stb_o , // strobe/request
+ output logic [AW-1:0] wbs_adr_o , // address
+ output logic wbs_we_o , // write
+ output logic [DW-1:0] wbs_dat_o , // data output
+ output logic [BW-1:0] wbs_sel_o , // byte enable
+ output logic [3:0] wbs_tid_o ,
+ output logic [BL-1:0] wbs_bl_o , // Burst Count
+ output logic wbs_bry_o , // Busrt WData Avialble Or Ready To accept Rdata
+ input logic [DW-1:0] wbs_dat_i , // data input
+ input logic wbs_ack_i , // acknowlegement
+ input logic wbs_lack_i , // Last Ack
+ input logic wbs_err_i // error
+
+ );
+
+
+
+parameter CFW = AW+DW+BW+BL+4+1 ; // COMMAND FIFO WIDTH
+parameter RFW = DW+1+1 ; // RESPONSE FIFO WIDTH
+
+parameter IDLE = 2'b00;
+parameter WRITE_DATA = 2'b01;
+parameter READ_DATA = 2'b10;
+
+
+//-------------------------------------------------
+// Master Interface
+// -------------------------------------------------
+logic m_cmd_wr_en ;
+logic [CFW-1:0] m_cmd_wr_data ;
+logic m_cmd_wr_full ;
+logic m_cmd_wr_afull ;
+
+logic m_resp_rd_empty ;
+logic m_resp_rd_aempty ;
+logic m_resp_rd_en ;
+logic [RFW-1:0] m_resp_rd_data ;
+logic [BL-1:0] m_bl_cnt ;
+logic [1:0] m_state ;
+
+// Master Write Interface
+
+
+
+assign m_cmd_wr_data = {wbm_adr_i,wbm_we_i,wbm_dat_i,wbm_sel_i,wbm_tid_i,wbm_bl_i};
+
+assign wbm_dat_o = m_resp_rd_data[DW-1:0];
+assign wbm_err_o = 'b0;
+
+always@(negedge rst_n or posedge clk_i)
+begin
+ if(rst_n == 0) begin
+ m_cmd_wr_en <= 'b0;
+ m_resp_rd_en <= 'b0;
+ m_state <= 'h0;
+ m_bl_cnt <= 'h0;
+ wbm_ack_o <= 'b0;
+ wbm_lack_o <= 'b0;
+ end else begin
+ case(m_state)
+ IDLE: begin
+ // Read DATA
+ // Make sure that FIFO is not overflow and there is no previous
+ // pending write + fifo is about to full
+ if(wbm_stb_i && !wbm_we_i && wbm_bry_i && !m_cmd_wr_full && !(m_cmd_wr_afull && m_cmd_wr_en) && !wbm_lack_o) begin
+ m_bl_cnt <= wbm_bl_i;
+ m_cmd_wr_en <= 'b1;
+ m_state <= READ_DATA;
+ end else if(wbm_stb_i && wbm_we_i && wbm_bry_i && !m_cmd_wr_full && !(m_cmd_wr_afull && m_cmd_wr_en) && !wbm_lack_o) begin
+ wbm_ack_o <= 'b1;
+ m_cmd_wr_en <= 'b1;
+ m_bl_cnt <= wbm_bl_i-1;
+ if(wbm_bl_i == 'h1) begin
+ wbm_lack_o <= 'b1;
+ m_state <= IDLE;
+ end else begin
+ m_bl_cnt <= wbm_bl_i-1;
+ m_state <= WRITE_DATA;
+ end
+ end else begin
+ m_resp_rd_en <= 'b0;
+ m_cmd_wr_en <= 'b0;
+ wbm_ack_o <= 'b0;
+ wbm_lack_o <= 'b0;
+ end
+ end
+
+ // Write next Transaction
+ WRITE_DATA: begin
+ if(m_cmd_wr_full != 1 && !(m_cmd_wr_afull && m_cmd_wr_en) && wbm_bry_i) begin
+ wbm_ack_o <= 'b1;
+ m_cmd_wr_en <= 'b1;
+ if(m_bl_cnt == 1) begin
+ wbm_lack_o <= 'b1;
+ m_state <= IDLE;
+ end else begin
+ m_bl_cnt <= m_bl_cnt-1;
+ end
+ end else begin
+ m_cmd_wr_en <= 'b0;
+ wbm_ack_o <= 'b0;
+ wbm_lack_o <= 'b0;
+ end
+ end
+
+ // Read Transaction
+ READ_DATA: begin
+ // Check Back to Back Ack and last Location case
+ if(((wbm_ack_o == 0 && m_resp_rd_empty != 1) ||
+ (wbm_ack_o == 1 && m_resp_rd_aempty != 1)) && wbm_bry_i) begin
+ m_resp_rd_en <= 'b1;
+ wbm_ack_o <= 'b1;
+ if(m_bl_cnt == 1) begin
+ wbm_lack_o <= 'b1;
+ m_state <= IDLE;
+ end else begin
+ m_bl_cnt <= m_bl_cnt-1;
+ end
+ end else begin
+ m_resp_rd_en <= 'b0;
+ m_cmd_wr_en <= 'b0;
+ wbm_ack_o <= 'b0;
+ wbm_lack_o <= 'b0;
+ end
+ end
+ endcase
+ end
+end
+
+
+//------------------------------
+// Slave Interface
+//-------------------------------
+
+logic [CFW-1:0] s_cmd_rd_data ;
+logic [CFW-1:0] s_cmd_rd_data_l ;
+logic s_cmd_rd_empty ;
+logic s_cmd_rd_aempty ;
+logic s_cmd_rd_en ;
+logic s_resp_wr_en ;
+logic [RFW-1:0] s_resp_wr_data ;
+logic s_resp_wr_full ;
+logic s_resp_wr_afull ;
+logic wbs_ack_f ;
+logic wbs_stb_l ;
+logic wbs_burst ;
+
+wire wbs_stb_pedge = (wbs_stb_l == 1'b0) && wbs_stb_o;
+
+
+always@(negedge rst_n or posedge clk_i)
+begin
+ if(rst_n == 0) begin
+ wbs_ack_f <= 1'b0;
+ wbs_stb_l <= 1'b0;
+ wbs_burst <= 'h0;
+ s_cmd_rd_data_l <= 'h0;
+ end else begin
+ wbs_ack_f <= wbs_lack_i;
+ wbs_stb_l <= wbs_stb_o;
+ if(s_cmd_rd_en)
+ s_cmd_rd_data_l <= s_cmd_rd_data;
+ if(wbs_stb_pedge && wbs_bl_o > 'h1)
+ wbs_burst <= 1'b1;
+ else if(wbs_lack_i)
+ wbs_burst <= 1'b0;
+ end
+end
+
+
+// Read Interface
+
+
+assign {wbs_adr_o,wbs_we_o,wbs_dat_o,wbs_sel_o,wbs_tid_o,wbs_bl_o} = (s_cmd_rd_empty) ? s_cmd_rd_data_l: s_cmd_rd_data;
+// All the downstream logic expect Stobe is getting de-asserted
+// atleast for 1 cycle after ack is generated
+assign wbs_stb_o = (wbs_burst) ? 1'b1 : ((wbs_ack_f) ? 1'b0 : (s_cmd_rd_empty) ? 1'b0: 1'b1);
+assign wbs_cyc_o = (wbs_burst) ? 1'b1 : ((wbs_ack_f) ? 1'b0 : (s_cmd_rd_empty) ? 1'b0: 1'b1);
+
+// Generate bust ready only we have space inside response fifo
+// In Write Phase,
+// Generate burst ready, only when we have wdata & space in response fifo
+// In Read Phase
+// Generate burst ready, only when space in response fifo
+//
+assign wbs_bry_o = (wbs_we_o) ? ((s_cmd_rd_empty || (s_cmd_rd_en && s_cmd_rd_aempty)) ? 1'b0: 1'b1) :
+ (s_resp_wr_full || (s_resp_wr_en && s_resp_wr_afull)) ? 1'b0: 1'b1;
+
+// During Write phase, cmd fifo will have wdata, so dequeue for every ack
+// During Read Phase, cmd fifo will be written only one time, hold the bus
+// untill last ack received
+assign s_cmd_rd_en = (wbs_stb_o && wbs_we_o) ? wbs_ack_i: wbs_lack_i;
+
+// Write Interface
+// response send only for read logic
+assign s_resp_wr_en = wbs_stb_o & (!wbs_we_o) & wbs_ack_i ;
+assign s_resp_wr_data = {wbs_err_i,wbs_lack_i,wbs_dat_i};
+
+sync_fifo2 #(.W(CFW), .DP(4),.WR_FAST(1), .RD_FAST(1)) u_cmd_if (
+ // Sync w.r.t WR clock
+ .clk (clk_i ),
+ .reset_n (rst_n ),
+ .wr_en (m_cmd_wr_en ),
+ .wr_data (m_cmd_wr_data ),
+ .full (m_cmd_wr_full ),
+ .afull (m_cmd_wr_afull ),
+
+ // Sync w.r.t RD Clock
+ .rd_en (s_cmd_rd_en ),
+ .empty (s_cmd_rd_empty ), // sync'ed to rd_clk
+ .aempty (s_cmd_rd_aempty ), // sync'ed to rd_clk
+ .rd_data (s_cmd_rd_data )
+ );
+
+
+// Response used only for read path,
+// As cache access will be busrt of 512 location, To
+// support continous ack, depth is increase to 8 location
+sync_fifo2 #(.W(RFW), .DP(4), .WR_FAST(1), .RD_FAST(1)) u_resp_if (
+ // Sync w.r.t WR clock
+ .clk (clk_i ),
+ .reset_n (rst_n ),
+ .wr_en (s_resp_wr_en ),
+ .wr_data (s_resp_wr_data ),
+ .full (s_resp_wr_full ),
+ .afull (s_resp_wr_afull ),
+
+ // Sync w.r.t RD Clock
+ .rd_en (m_resp_rd_en ),
+ .empty (m_resp_rd_empty ), // sync'ed to rd_clk
+ .aempty (m_resp_rd_aempty ), // sync'ed to rd_clk
+ .rd_data (m_resp_rd_data )
+ );
+
+
+
+endmodule
diff --git a/verilog/rtl/lib/wb_interface.v b/verilog/rtl/lib/wb_interface.v
new file mode 100644
index 0000000..f25b147
--- /dev/null
+++ b/verilog/rtl/lib/wb_interface.v
@@ -0,0 +1,404 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// yifive common library Module ////
+//// ////
+//// This file is part of the yifive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description: ////
+//// This module does the DMA to wishbone I/f ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// v0: Nov 26, 2016, Dinesh A ////
+//// This files copied from my open core ////
+//// turbo8051 project ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module wb_interface (
+ rst ,
+ clk ,
+
+ dma_req_i ,
+ dma_write_i ,
+ dma_addr_i ,
+ dma_length_i ,
+ dma_ack_o ,
+ dma_done_o ,
+
+ dma_start_o ,
+ dma_wr_o ,
+ dma_rd_o ,
+ dma_last_o ,
+ dma_wdata_i ,
+ dma_rdata_o ,
+
+ // external memory
+ wbd_dat_i ,
+ wbd_dat_o ,
+ wbd_adr_o ,
+ wbd_be_o ,
+ wbd_we_o ,
+ wbd_ack_i ,
+ wbd_stb_o ,
+ wbd_cyc_o ,
+ wbd_err_i
+
+
+ );
+
+
+
+input rst ;
+input clk ;
+
+input dma_req_i ;
+input dma_write_i ;
+input [25:0] dma_addr_i ;
+input [7:0] dma_length_i ;
+output dma_ack_o ;
+output dma_done_o ; // indicates end of DMA transaction
+
+output dma_start_o ;
+output dma_wr_o ;
+output dma_rd_o ;
+output dma_last_o ;
+input [31:0] dma_wdata_i ;
+output [31:0] dma_rdata_o ;
+
+//--------------------------------
+// WB interface
+//--------------------------------
+input [31:0] wbd_dat_i ; // data input
+output [31:0] wbd_dat_o ; // data output
+output [23:0] wbd_adr_o ; // address
+output [3:0] wbd_be_o ; // byte enable
+output wbd_we_o ; // write
+input wbd_ack_i ; // acknowlegement
+output wbd_stb_o ; // strobe/request
+output wbd_cyc_o ; // wb cycle
+input wbd_err_i ; // we error
+
+//------------------------------------
+// Reg Declaration
+//--------------------------------
+reg [2:0] state ;
+reg [2:0] state_d ;
+reg [7:0] preq_len ; // pending request length in bytes
+reg wbd_we_o ; // westbone write req
+reg [23:0] wbd_adr_o ; // westnone address
+reg dma_ack_o ; // dma ack
+reg [7:0] twbtrans ; // total westbone transaction
+reg dma_wr_o ; // dma write request
+reg dma_rd_o ; // dma read request
+reg [31:0] temp_data ; // temp holding data
+reg [1:0] be_sof ; // Byte enable starting alignment
+reg [31:0] wbd_dat_o ; // westbone data out
+reg [3:0] wbd_be_o ; // west bone byte enable
+reg [31:0] dma_rdata_o ; // dma read data
+reg wbd_stb_o ;
+reg dma_start_o ; // dma first transfer
+reg dma_last_o ; // dma last transfer
+
+parameter WB_IDLE = 3'b000;
+parameter WB_REQ = 3'b001;
+parameter WB_WR_PHASE = 3'b010;
+parameter WB_RD_PHASE_SOF = 3'b011;
+parameter WB_RD_PHASE_CONT = 3'b100;
+
+assign dma_done_o = (state == WB_IDLE) && (state_d != WB_IDLE);
+
+always @(posedge rst or posedge clk)
+begin
+ if(rst) begin
+ state <= WB_IDLE;
+ state_d <= WB_IDLE;
+ wbd_we_o <= 0;
+ wbd_adr_o <= 0;
+ preq_len <= 0;
+ dma_ack_o <= 0;
+ twbtrans <= 0;
+ dma_wr_o <= 0;
+ dma_rd_o <= 0;
+ temp_data <= 0;
+ be_sof <= 0;
+ wbd_dat_o <= 0;
+ wbd_be_o <= 0;
+ dma_rdata_o <= 0;
+ wbd_stb_o <= 0;
+ dma_start_o <= 0;
+ dma_last_o <= 0;
+ end
+ else begin
+ state_d <= state;
+ case(state)
+ WB_IDLE :
+ begin
+ if(dma_req_i)
+ begin
+ dma_ack_o <= 1;
+ wbd_we_o <= dma_write_i;
+ wbd_adr_o <= dma_addr_i[25:2];
+ be_sof <= dma_addr_i[1] << 1 + dma_addr_i[0];
+ preq_len <= dma_length_i;
+ // total wb transfer
+ twbtrans <= dma_length_i[7:2] +
+ |(dma_length_i[1:0]) +
+ |(dma_addr_i[1:0]);
+ state <= WB_REQ;
+ end
+ dma_wr_o <= 0;
+ dma_rd_o <= 0;
+ wbd_stb_o <= 0;
+ dma_start_o <= 0;
+ end
+ WB_REQ :
+ begin
+ dma_ack_o <= 0;
+ wbd_stb_o <= 1;
+ if(wbd_we_o) begin
+ dma_wr_o <= 1;
+ dma_start_o <= 1;
+ temp_data <= dma_wdata_i;
+ if(be_sof == 0) begin
+ wbd_dat_o <= dma_wdata_i;
+ wbd_be_o <= 4'b1111;
+ preq_len <= preq_len - 4;
+ end
+ else if(be_sof == 1) begin
+ wbd_dat_o <= {dma_wdata_i[23:0],8'h0};
+ wbd_be_o <= 4'b1110;
+ preq_len <= preq_len - 3;
+ end
+ else if(be_sof == 2) begin
+ wbd_dat_o <= {dma_wdata_i[15:0],16'h0};
+ wbd_be_o <= 4'b1100;
+ preq_len <= preq_len - 2;
+ end
+ else begin
+ wbd_dat_o <= {dma_wdata_i[7:0],23'h0};
+ wbd_be_o <= 4'b1000;
+ preq_len <= preq_len - 1;
+ end
+ twbtrans <= twbtrans -1;
+ state <= WB_WR_PHASE;
+ if(twbtrans == 1)
+ dma_last_o <= 1;
+ end
+ else begin
+ state <= WB_RD_PHASE_SOF;
+ end
+ end
+ WB_WR_PHASE :
+ begin
+ dma_start_o <= 0;
+ if(wbd_ack_i) begin
+ if(twbtrans == 1)
+ dma_last_o <= 1;
+ else
+ dma_last_o <= 0;
+ if(twbtrans > 0) begin
+ temp_data <= dma_wdata_i;
+ twbtrans <= twbtrans -1;
+ if(be_sof == 0) begin
+ wbd_dat_o <= dma_wdata_i;
+ end
+ else if(be_sof == 1) begin
+ wbd_dat_o <= {dma_wdata_i[23:0],temp_data[31:24]};
+ end
+ else if(be_sof == 2) begin
+ wbd_dat_o <= {dma_wdata_i[15:0],temp_data[31:16]};
+ end
+ else begin
+ wbd_dat_o <= {dma_wdata_i[7:0],temp_data[31:8]};
+ end
+
+ if(twbtrans > 1) begin // If the Pending Transfer is more than 1
+ dma_wr_o <= 1;
+ wbd_be_o <= 4'b1111;
+ preq_len <= preq_len - 4;
+ end
+ else begin // for last write access
+ wbd_be_o <= preq_len[1:0] == 2'b00 ? 4'b1111:
+ preq_len[1:0] == 2'b01 ? 4'b0001:
+ preq_len[1:0] == 2'b10 ? 4'b0011: 4'b0111;
+
+ case({be_sof[1:0],preq_len[1:0]})
+ // Start alignment = 0
+ 4'b0001 : dma_wr_o <= 1;
+ 4'b0010 : dma_wr_o <= 1;
+ 4'b0011 : dma_wr_o <= 1;
+ 4'b0000 : dma_wr_o <= 1;
+ // Start alignment = 1
+ 4'b0101 : dma_wr_o <= 0;
+ 4'b0110 : dma_wr_o <= 1;
+ 4'b0111 : dma_wr_o <= 1;
+ 4'b0100 : dma_wr_o <= 1;
+ // Start alignment = 2
+ 4'b1001 : dma_wr_o <= 0;
+ 4'b1010 : dma_wr_o <= 0;
+ 4'b1011 : dma_wr_o <= 1;
+ 4'b1000 : dma_wr_o <= 1;
+ // Start alignment = 3
+ 4'b1101 : dma_wr_o <= 0;
+ 4'b1110 : dma_wr_o <= 0;
+ 4'b1111 : dma_wr_o <= 0;
+ 4'b1100 : dma_wr_o <= 1;
+ endcase
+ end
+ end
+ else begin
+ dma_wr_o <= 0;
+ wbd_stb_o <= 0;
+ state <= WB_IDLE;
+ end
+ end
+ else begin
+ dma_last_o <= 0;
+ dma_wr_o <= 0;
+ end
+ end
+ WB_RD_PHASE_SOF :
+ begin
+ if(wbd_ack_i) begin
+ twbtrans <= twbtrans -1;
+ if(twbtrans == 1) begin // If the Pending Transfer is 1
+ dma_rd_o <= 1;
+ dma_start_o<= 1;
+ if(be_sof == 0) begin
+ dma_rdata_o <= wbd_dat_i;
+ preq_len <= preq_len - 4;
+ end
+ else if(be_sof == 1) begin
+ dma_rdata_o <= {8'h0,wbd_dat_i[31:24]};
+ preq_len <= preq_len - 3;
+ end
+ else if(be_sof == 2) begin
+ dma_rdata_o <= {16'h0,wbd_dat_i[31:16]};
+ preq_len <= preq_len - 2;
+ end
+ else begin
+ dma_rdata_o <= {23'h0,wbd_dat_i[31:8]};
+ preq_len <= preq_len - 0;
+ end
+ dma_last_o <= 1;
+ state <= WB_IDLE;
+ end
+ else begin // pending transction is more than 1
+ if(be_sof == 0) begin
+ dma_rdata_o <= wbd_dat_i;
+ dma_rd_o <= 1;
+ dma_start_o <= 1;
+ preq_len <= preq_len - 4;
+ end
+ else if(be_sof == 1) begin
+ temp_data <= {8'h0,wbd_dat_i[31:24]};
+ dma_rd_o <= 0;
+ preq_len <= preq_len - 3;
+ end
+ else if(be_sof == 2) begin
+ temp_data <= {16'h0,wbd_dat_i[31:16]};
+ preq_len <= preq_len - 2;
+ end
+ else begin
+ temp_data <= {23'h0,wbd_dat_i[31:8]};
+ preq_len <= preq_len - 0;
+ end
+ state <= WB_RD_PHASE_CONT;
+ end
+ end
+ else begin
+ dma_rd_o <= 0;
+ end
+ end
+ WB_RD_PHASE_CONT:
+ begin
+ dma_start_o <= 0;
+ if(wbd_ack_i) begin
+ dma_rd_o <= 1;
+ twbtrans <= twbtrans -1;
+ if(be_sof == 0) begin
+ dma_rdata_o <= wbd_dat_i;
+ preq_len <= preq_len - 4;
+ end
+ else if(be_sof == 1) begin
+ dma_rdata_o <= {wbd_dat_i[7:0],temp_data[23:0]};
+ temp_data <= {8'h0,wbd_dat_i[31:8]};
+ preq_len <= preq_len - 3;
+ end
+ else if(be_sof == 2) begin
+ dma_rdata_o <= {wbd_dat_i[15:0],temp_data[15:0]};
+ temp_data <= {16'h0,wbd_dat_i[31:16]};
+ preq_len <= preq_len - 2;
+ end
+ else begin
+ dma_rdata_o <= {wbd_dat_i[23:0],temp_data[7:0]};
+ temp_data <= {24'h0,wbd_dat_i[31:23]};
+ preq_len <= preq_len - 1;
+ end
+ if(twbtrans == 1) begin // If the it's last transfer
+ dma_last_o <= 1;
+ state <= WB_IDLE;
+ end
+ end
+ else begin
+ dma_last_o <= 0;
+ dma_rd_o <= 0;
+ end
+ end
+ endcase
+ end
+end
+
+
+
+endmodule
diff --git a/verilog/rtl/lib/wb_stagging.sv b/verilog/rtl/lib/wb_stagging.sv
new file mode 100644
index 0000000..2661005
--- /dev/null
+++ b/verilog/rtl/lib/wb_stagging.sv
@@ -0,0 +1,192 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//----------------------------------------------------------------------
+// This logic create a holding register for Wishbone interface.
+// This is usefull to break timing issue at interconnect
+//
+// Limitation: Due to stagging FF, Continous Burst of Wishbone will have one
+// cycle break between each transaction
+//----------------------------------------------------------------------
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Wishbone Stagging FF ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This logic create a holding FF for Wishbone interface. ////
+//// This is usefull to break timing issue at interconnect ////
+//// ////
+//// Limitation: Due to stagging FF, Continous Burst of ////
+//// Wishbone will have one cycle break between each transaction ////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module wb_stagging (
+ input logic clk_i,
+ input logic rst_n,
+ // WishBone Input master I/P
+ input logic [31:0] m_wbd_dat_i,
+ input logic [31:0] m_wbd_adr_i,
+ input logic [3:0] m_wbd_sel_i,
+ input logic [9:0] m_wbd_bl_i,
+ input logic m_wbd_bry_i,
+ input logic m_wbd_we_i,
+ input logic m_wbd_cyc_i,
+ input logic m_wbd_stb_i,
+ input logic [3:0] m_wbd_tid_i,
+ output logic [31:0] m_wbd_dat_o,
+ output logic m_wbd_ack_o,
+ output logic m_wbd_lack_o,
+ output logic m_wbd_err_o,
+
+ // Slave Interface
+ input logic [31:0] s_wbd_dat_i,
+ input logic s_wbd_ack_i,
+ input logic s_wbd_lack_i,
+ input logic s_wbd_err_i,
+ output logic [31:0] s_wbd_dat_o,
+ output logic [31:0] s_wbd_adr_o,
+ output logic [3:0] s_wbd_sel_o,
+ output logic [9:0] s_wbd_bl_o,
+ output logic s_wbd_bry_o,
+ output logic s_wbd_we_o,
+ output logic s_wbd_cyc_o,
+ output logic s_wbd_stb_o,
+ output logic [3:0] s_wbd_tid_o
+
+);
+
+logic [31:0] m_wbd_dat_i_ff ; // Flopped vesion of m_wbd_dat_i
+logic [31:0] m_wbd_adr_i_ff ; // Flopped vesion of m_wbd_adr_i
+logic [3:0] m_wbd_sel_i_ff ; // Flopped vesion of m_wbd_sel_i
+logic [9:0] m_wbd_bl_i_ff ; // Flopped vesion of m_wbd_bl_i
+logic m_wbd_bry_i_ff ; // Flopped vesion of m_wbd_bry_i
+logic m_wbd_we_i_ff ; // Flopped vesion of m_wbd_we_i
+logic m_wbd_cyc_i_ff ; // Flopped vesion of m_wbd_cyc_i
+logic m_wbd_stb_i_ff ; // Flopped vesion of m_wbd_stb_i
+logic [3:0] m_wbd_tid_i_ff ; // Flopped vesion of m_wbd_tid_i
+logic [31:0] s_wbd_dat_i_ff ; // Flopped vesion of s_wbd_dat_i
+logic s_wbd_ack_i_ff ; // Flopped vesion of s_wbd_ack_i
+logic s_wbd_lack_i_ff ; // Flopped vesion of s_wbd_ack_i
+logic s_wbd_err_i_ff ; // Flopped vesion of s_wbd_err_i
+
+
+assign s_wbd_dat_o = m_wbd_dat_i_ff;
+assign s_wbd_adr_o = m_wbd_adr_i_ff;
+assign s_wbd_sel_o = m_wbd_sel_i_ff;
+assign s_wbd_bl_o = m_wbd_bl_i_ff;
+assign s_wbd_bry_o = m_wbd_bry_i_ff;
+assign s_wbd_we_o = m_wbd_we_i_ff;
+assign s_wbd_cyc_o = m_wbd_cyc_i_ff;
+assign s_wbd_stb_o = m_wbd_stb_i_ff;
+assign s_wbd_tid_o = m_wbd_tid_i_ff;
+
+assign m_wbd_dat_o = s_wbd_dat_i_ff;
+assign m_wbd_ack_o = s_wbd_ack_i_ff;
+assign m_wbd_lack_o = s_wbd_lack_i_ff;
+assign m_wbd_err_o = s_wbd_err_i_ff;
+
+always @(negedge rst_n or posedge clk_i)
+begin
+ if(rst_n == 1'b0) begin
+ m_wbd_dat_i_ff <= 'h0;
+ m_wbd_adr_i_ff <= 'h0;
+ m_wbd_sel_i_ff <= 'h0;
+ m_wbd_bl_i_ff <= 'h0;
+ m_wbd_bry_i_ff <= 'b0;
+ m_wbd_we_i_ff <= 'h0;
+ m_wbd_cyc_i_ff <= 'h0;
+ m_wbd_stb_i_ff <= 'h0;
+ m_wbd_tid_i_ff <= 'h0;
+ s_wbd_dat_i_ff <= 'h0;
+ s_wbd_ack_i_ff <= 'h0;
+ s_wbd_lack_i_ff <= 'h0;
+ s_wbd_err_i_ff <= 'h0;
+ end else begin
+ s_wbd_dat_i_ff <= s_wbd_dat_i;
+ s_wbd_ack_i_ff <= s_wbd_ack_i;
+ s_wbd_lack_i_ff <= s_wbd_lack_i;
+ s_wbd_err_i_ff <= s_wbd_err_i;
+ if((m_wbd_stb_i && m_wbd_bry_i && s_wbd_ack_i == 0 && m_wbd_lack_o == 0) ||
+ (m_wbd_stb_i && m_wbd_bry_i && s_wbd_ack_i == 1 && s_wbd_lack_i == 0)) begin
+ m_wbd_dat_i_ff <= m_wbd_dat_i;
+ m_wbd_adr_i_ff <= m_wbd_adr_i;
+ m_wbd_sel_i_ff <= m_wbd_sel_i;
+ m_wbd_we_i_ff <= m_wbd_we_i;
+ m_wbd_cyc_i_ff <= m_wbd_cyc_i;
+ m_wbd_stb_i_ff <= m_wbd_stb_i;
+ m_wbd_tid_i_ff <= m_wbd_tid_i;
+ m_wbd_bl_i_ff <= m_wbd_bl_i;
+ m_wbd_bry_i_ff <= 'b1;
+ end else if ((m_wbd_stb_i && !m_wbd_bry_i && s_wbd_ack_i == 1 && s_wbd_lack_i == 0)) begin // De-Assert burst ready
+ m_wbd_bry_i_ff <= 'b0;
+ end else if (s_wbd_lack_i) begin
+ m_wbd_dat_i_ff <= 'h0;
+ m_wbd_adr_i_ff <= 'h0;
+ m_wbd_sel_i_ff <= 'h0;
+ m_wbd_we_i_ff <= 'h0;
+ m_wbd_cyc_i_ff <= 'h0;
+ m_wbd_stb_i_ff <= 'h0;
+ m_wbd_tid_i_ff <= 'h0;
+ m_wbd_bl_i_ff <= 'h0;
+ m_wbd_bry_i_ff <= 'b0;
+ end
+ end
+end
+
+
+endmodule
+
diff --git a/verilog/rtl/mbist/include/mbist_def.svh b/verilog/rtl/mbist/include/mbist_def.svh
new file mode 100644
index 0000000..10fb2ea
--- /dev/null
+++ b/verilog/rtl/mbist/include/mbist_def.svh
@@ -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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+`ifndef BIST_DEFINE_SVH
+`define BIST_DEFINE_SVH
+
+// BIST ADDRESS CONTRL
+//
+//parameter BIST_ADDR_WD = 9 ;
+//parameter BIST_ADDR_START = 10'h000 ;
+//parameter BIST_ADDR_END = 10'h3FB ;
+
+// BIST DATA CONTRL
+//parameter BIST_DATA_WD = 32;
+parameter BIST_DATA_PAT_SIZE = 8;
+parameter BIST_DATA_PAT_TYPE1 = 64'h5555_5555_5555_5555;
+parameter BIST_DATA_PAT_TYPE2 = 64'h3333_3333_3333_3333;
+parameter BIST_DATA_PAT_TYPE3 = 64'h0F0F_0F0F_0F0F_0F0F;
+parameter BIST_DATA_PAT_TYPE4 = 64'h00FF_00FF_00FF_00FF;
+parameter BIST_DATA_PAT_TYPE5 = 64'h0000_FFFF_0000_FFFF;
+parameter BIST_DATA_PAT_TYPE6 = 64'h0000_0000_FFFF_FFFF;
+parameter BIST_DATA_PAT_TYPE7 = 64'hFFFF_FFFF_FFFF_FFFF;
+parameter BIST_DATA_PAT_TYPE8 = 64'h0000_0000_0000_0000;
+
+// BIST STIMULATION SELECT
+
+parameter BIST_STI_SIZE = 5;
+parameter BIST_STI_WD = 15;
+// Additional 3'b000 added at end of each stimulus to flush out the comparion
+// result + to handle error fix case
+parameter BIST_STIMULUS_TYPE1 = 15'b100100100100000;
+parameter BIST_STIMULUS_TYPE2 = 15'b100010101011000;
+parameter BIST_STIMULUS_TYPE3 = 15'b110011100010000;
+parameter BIST_STIMULUS_TYPE4 = 15'b000010101011000;
+parameter BIST_STIMULUS_TYPE5 = 15'b010011100010000;
+parameter BIST_STIMULUS_TYPE6 = 15'b000000000000000;
+parameter BIST_STIMULUS_TYPE7 = 15'b000000000000000;
+parameter BIST_STIMULUS_TYPE8 = 15'b000000000000000;
+
+
+// Operation
+parameter BIST_OP_SIZE = 4;
+
+// BIST ADDRESS REPAIR
+//parameter BIST_RAD_WD_I = BIST_ADDR_WD;
+//parameter BIST_RAD_WD_O = BIST_ADDR_WD;
+parameter BIST_ERR_LIMIT = 4;
+// Make Sure that this address in outside the valid address range
+//parameter BIST_REPAIR_ADDR_START = 10'h3FC ;
+
+`endif // BIST_DEFINE_SVH
diff --git a/verilog/rtl/mbist/run_iverilog b/verilog/rtl/mbist/run_iverilog
new file mode 100755
index 0000000..f5f5020
--- /dev/null
+++ b/verilog/rtl/mbist/run_iverilog
@@ -0,0 +1,17 @@
+iverilog -g2005-sv -DFUNCTIONAL -D UNIT_DELAY=#0.1 \
+src/top/mbist_top.sv \
+src/core/mbist_addr_gen.sv \
+src/core/mbist_fsm.sv \
+src/core/mbist_op_sel.sv \
+src/core/mbist_repair_addr.sv \
+src/core/mbist_data_cmp.sv \
+src/core/mbist_mux.sv \
+src/core/mbist_pat_sel.sv \
+src/core/mbist_sti_sel.sv \
+src/core/mbist_mem_wrapper.sv \
+-I include/ \
+../lib/ctech_cells.sv \
+../lib/reset_sync.sv \
+../clk_skew_adjust/src/clk_skew_adjust.gv \
+$PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v \
+$PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/verilog/primitives.v
diff --git a/verilog/rtl/mbist/run_verilator b/verilog/rtl/mbist/run_verilator
new file mode 100755
index 0000000..1dd5d6b
--- /dev/null
+++ b/verilog/rtl/mbist/run_verilator
@@ -0,0 +1,17 @@
+verilator -cc \
+src/top/mbist_top1.sv \
+src/core/mbist_addr_gen.sv \
+src/core/mbist_fsm.sv \
+src/core/mbist_op_sel.sv \
+src/core/mbist_repair_addr.sv \
+src/core/mbist_data_cmp.sv \
+src/core/mbist_mux.sv \
+src/core/mbist_pat_sel.sv \
+src/core/mbist_sti_sel.sv \
++incdir+include/ \
+../lib/ctech_cells.sv \
+../lib/reset_sync.sv \
+-v $PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v \
+-v $PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/verilog/primitives.v \
+--timescale 1ns/100ps \
+--bbox-unsup
diff --git a/verilog/rtl/mbist/src/core/mbist_addr_gen.sv b/verilog/rtl/mbist/src/core/mbist_addr_gen.sv
new file mode 100644
index 0000000..ffcf42c
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_addr_gen.sv
@@ -0,0 +1,116 @@
+///////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Address Generator ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist address gen ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "mbist_def.svh"
+
+module mbist_addr_gen
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic last_addr, // Last address access
+ output logic [BIST_ADDR_WD-1:0] bist_addr, // Bist Address
+ output logic sdo, // scan data output
+ input logic clk, // clock input
+ input logic rst_n, // asynchronous reset
+ input logic run, // stop or start state machine
+ input logic updown, // count up or down
+ input logic bist_shift, // shift scan input
+ input logic bist_load, // load scan input
+ input logic sdi // scan data input
+
+);
+
+
+logic [BIST_ADDR_WD-1:0] next_addr; // Next Address
+logic [BIST_ADDR_WD-1:0] start_addr; // Address Start Address
+logic [BIST_ADDR_WD-1:0] end_addr; // Address Stop Address
+
+
+assign last_addr = (((updown == 1'b1)&&(bist_addr == end_addr))||((updown == 1'b0)&&(bist_addr == start_addr)))?1'b1:1'b0;
+
+
+/******************************
+ Address register
+ Basic Assumption: Allways counter start with upcounting
+*********************************/
+
+
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) bist_addr <= BIST_ADDR_START ;
+ else if(bist_load) bist_addr <= start_addr;
+ else bist_addr <= next_addr;
+end
+
+/* Input combinational block */
+
+always_comb begin
+ if(run) begin
+ if((bist_addr == end_addr)&&(updown == 1'b1))
+ next_addr = start_addr ;
+ else if((bist_addr == start_addr)&&(updown == 1'b0))
+ next_addr = end_addr ;
+ else next_addr = (updown)?bist_addr+1'b1:bist_addr-1'b1;
+ end
+ else next_addr = bist_addr;
+end
+
+
+/* Start register */
+
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) start_addr <= BIST_ADDR_START ;
+ else if(bist_shift) start_addr <= {sdi, start_addr[BIST_ADDR_WD-1:1]};
+end
+
+/* Start register */
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) end_addr <= BIST_ADDR_END ;
+ else if(bist_shift) end_addr <= {start_addr[0], end_addr[BIST_ADDR_WD-1:1]};
+end
+
+
+assign sdo = end_addr[0];
+
+endmodule
+
diff --git a/verilog/rtl/mbist/src/core/mbist_data_cmp.sv b/verilog/rtl/mbist/src/core/mbist_data_cmp.sv
new file mode 100644
index 0000000..45dd343
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_data_cmp.sv
@@ -0,0 +1,116 @@
+///////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Data Comparator ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist data comparator ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+`include "mbist_def.svh"
+
+
+module mbist_data_cmp
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic error,
+ output logic error_correct,
+ output logic correct,
+ output logic [BIST_ADDR_WD-1:0] error_addr,
+ output logic [3:0] error_cnt,
+ input logic clk,
+ input logic rst_n,
+ input logic compare,
+ input logic addr_inc_phase,
+ input logic read_invert,
+ input logic [BIST_DATA_WD-1:0] comp_data,
+ input logic [BIST_DATA_WD-1:0] rxd_data,
+ input logic [BIST_ADDR_WD-1:0] addr
+
+ );
+
+logic mask_compare;
+logic [BIST_DATA_WD-1:0] exp_data;
+logic comp_status;
+
+assign exp_data = (read_invert) ? ~comp_data: comp_data;
+
+/* Comparison register */
+
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) begin
+ comp_status <= 1'b0;
+ error_addr <= 'b0;
+ end else if(compare && !mask_compare) begin
+ comp_status <= |(exp_data ^ rxd_data);
+ error_addr <= addr;
+ end else begin
+ comp_status <= 1'b0;
+ end
+end
+
+// Due to cycle diference between compare and write opperation
+// There is chance two error reported for same address
+// To avoid this, once error is detected, comparision is masked
+// unit the next address phase
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) begin
+ error_cnt <= 'b0;
+ correct <='b0;
+ mask_compare <= 'b0;
+ error <= '0;
+ end else if(mask_compare && addr_inc_phase) begin
+ mask_compare <= 1'b0;
+ end else if(comp_status && (error_cnt < BIST_ERR_LIMIT) ) begin
+ error_cnt <= error_cnt+1;
+ mask_compare <= 1'b1;
+ correct <='b1;
+ end else if(comp_status && (error_cnt == BIST_ERR_LIMIT) ) begin
+ error <= '1;
+ end
+end
+
+assign error_correct = (error_cnt < BIST_ERR_LIMIT) ? comp_status : 1'b0;
+
+endmodule
+
+
+
+
+
+
diff --git a/verilog/rtl/mbist/src/core/mbist_fsm.sv b/verilog/rtl/mbist/src/core/mbist_fsm.sv
new file mode 100644
index 0000000..7672ee7
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_fsm.sv
@@ -0,0 +1,141 @@
+///////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Main control FSM ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// MBIST Main control FSM to control Command, Address, Write ////
+//// and Read compare phase ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+module mbist_fsm
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic cmd_phase, // Command Phase
+ output logic cmp_phase, // Compare Phase
+ output logic run_op, // Move to Next Operation
+ output logic run_addr, // Move to Next Address
+ output logic run_sti, // Move to Next Stimulus
+ output logic run_pat, // Move to next pattern
+ output logic bist_done, // Bist Test Done
+
+
+ input logic clk, // Clock
+ input logic rst_n, // Reset
+ input logic bist_run, // Bist Run
+ input logic bist_error, // Bist Error
+ input logic op_reverse, // Address Reverse in Next Cycle
+ input logic last_op, // Last Operation
+ input logic last_addr, // Last Address
+ input logic last_sti, // Last Stimulus
+ input logic last_pat // Last Pattern
+
+
+);
+
+parameter FSM_PHASE1 = 2'b00;
+parameter FSM_PHASE2 = 2'b01;
+parameter FSM_EXIT = 2'b10;
+
+logic [1:0] state;
+
+
+
+always @(posedge clk or negedge rst_n)
+begin
+ if(!rst_n) begin
+ cmd_phase <= 0;
+ cmp_phase <= 0;
+ run_op <= 0;
+ run_addr <= 0;
+ run_sti <= 0;
+ run_pat <= 0;
+ bist_done <= 0;
+ state <= FSM_PHASE1;
+ end else if(bist_run) begin
+ case(state)
+ FSM_PHASE1 :
+ begin
+ cmd_phase <= 1;
+ cmp_phase <= 0;
+ run_op <= 0;
+ run_addr <= 0;
+ run_sti <= 0;
+ run_pat <= 0;
+ state <= FSM_PHASE2;
+ end
+ FSM_PHASE2 :
+ begin
+ if((last_addr && last_op && last_sti && last_pat) || bist_error) begin
+ cmd_phase <= 0;
+ cmp_phase <= 0;
+ run_op <= 0;
+ run_addr <= 0;
+ run_sti <= 0;
+ run_pat <= 0;
+ state <= FSM_EXIT;
+ end else begin
+ cmd_phase <= 0;
+ cmp_phase <= 1;
+ run_op <= 1;
+ if(last_op && !(last_addr && op_reverse))
+ run_addr <= 1;
+ if(last_addr && last_op)
+ run_sti <= 1;
+ if(last_addr && last_op && last_sti)
+ run_pat <= 1;
+ state <= FSM_PHASE1;
+ end
+ end
+ FSM_EXIT: bist_done <= 1;
+ default: state <= FSM_PHASE1;
+ endcase
+ end else begin
+ cmd_phase <= 0;
+ cmp_phase <= 0;
+ run_op <= 0;
+ run_addr <= 0;
+ run_sti <= 0;
+ run_pat <= 0;
+ state <= FSM_PHASE1;
+ end
+end
+
+
+
+endmodule
diff --git a/verilog/rtl/mbist/src/core/mbist_mem_wrapper.sv b/verilog/rtl/mbist/src/core/mbist_mem_wrapper.sv
new file mode 100644
index 0000000..8f31671
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_mem_wrapper.sv
@@ -0,0 +1,102 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Memory wrapper ////
+//// ////
+//// This file is part of the mbist_ctrl project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block does wishbone to SRAM signal mapping ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 18 Nov 2021, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+module mbist_mem_wrapper #(
+ parameter BIST_NO_SRAM=4,
+ parameter BIST_ADDR_WD=10,
+ parameter BIST_DATA_WD=32) (
+ input logic rst_n ,
+ // WB I/F
+ input logic [(BIST_NO_SRAM+1)/2-1:0] sram_id ,
+ input logic wb_clk_i , // System clock
+ input logic [(BIST_NO_SRAM+1)/2-1:0] mem_cs , // Chip Select
+ input logic mem_req , // strobe/request
+ input logic [BIST_ADDR_WD-1:0] mem_addr , // address
+ input logic mem_we , // write
+ input logic [BIST_DATA_WD-1:0] mem_wdata , // data output
+ input logic [BIST_DATA_WD/8-1:0] mem_wmask , // byte enable
+ output logic [BIST_DATA_WD-1:0] mem_rdata , // data input
+ // MEM PORT
+ output logic func_clk ,
+ output logic func_cen ,
+ output logic func_web ,
+ output logic [BIST_DATA_WD/8-1:0] func_mask ,
+ output logic [BIST_ADDR_WD-1:0] func_addr ,
+ input logic [BIST_DATA_WD-1:0] func_dout ,
+ output logic [BIST_DATA_WD-1:0] func_din
+
+);
+
+
+// Memory Write PORT
+assign func_clk = wb_clk_i;
+assign func_cen = (mem_cs == sram_id) ? !mem_req : 1'b1;
+assign func_web = (mem_cs == sram_id) ? !mem_we : 1'b1;
+assign func_mask = mem_wmask;
+assign func_addr = mem_addr;
+assign func_din = mem_wdata;
+assign mem_rdata = func_dout;
+
+
+
+
+endmodule
diff --git a/verilog/rtl/mbist/src/core/mbist_mux.sv b/verilog/rtl/mbist/src/core/mbist_mux.sv
new file mode 100755
index 0000000..0341b16
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_mux.sv
@@ -0,0 +1,154 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST and MEMORY Mux Control Selection ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate MBIST and Memory control selection ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "mbist_def.svh"
+module mbist_mux
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ input logic scan_mode,
+
+ input logic rst_n,
+ // MBIST CTRL SIGNAL
+ input logic bist_en,
+ input logic [BIST_ADDR_WD-1:0] bist_addr,
+ input logic [BIST_DATA_WD-1:0] bist_wdata,
+ input logic bist_clk,
+ input logic bist_wr,
+ input logic bist_rd,
+ input logic bist_error,
+ input logic [BIST_ADDR_WD-1:0] bist_error_addr,
+ output logic bist_correct,
+ input logic bist_sdi,
+ input logic bist_load,
+ input logic bist_shift,
+ output logic bist_sdo,
+
+ input logic func_clk,
+ input logic func_cen,
+ input logic func_web,
+ input logic [BIST_DATA_WD/8-1:0] func_mask,
+ input logic [BIST_ADDR_WD-1:0] func_addr,
+ input logic [BIST_DATA_WD-1:0] func_din,
+ output logic [BIST_DATA_WD-1:0] func_dout,
+
+
+ // towards memory
+
+ output logic mem_clk,
+ output logic mem_cen,
+ output logic mem_web,
+ output logic [BIST_DATA_WD/8-1:0] mem_mask,
+ output logic [BIST_ADDR_WD-1:0] mem_addr,
+ output logic [BIST_DATA_WD-1:0] mem_din,
+ input logic [BIST_DATA_WD-1:0] mem_dout
+ );
+
+
+parameter BIST_MASK_WD = BIST_DATA_WD/8;
+
+wire [BIST_ADDR_WD-1:0] addr;
+
+
+
+assign addr = (bist_en) ? bist_addr : func_addr;
+
+assign mem_cen = (bist_en) ? !(bist_rd | bist_wr) : func_cen;
+assign mem_web = (bist_en) ? !bist_wr : func_web;
+assign mem_mask = (bist_en) ? {{BIST_MASK_WD}{1'b1}} : func_mask;
+
+//assign mem_clk_a = (bist_en) ? bist_clk : func_clk_a;
+//assign mem_clk_b = (bist_en) ? bist_clk : func_clk_b;
+
+ctech_mux2x1 u_mem_clk_sel (.A0 (func_clk),.A1 (bist_clk),.S (bist_en), .X (mem_clk));
+
+//ctech_clk_buf u_mem_clk (.A (mem_clk_cts), . X(mem_clk));
+
+assign mem_din = (bist_en) ? bist_wdata : func_din;
+
+
+
+// During scan, SRAM data is unknown, feed data in back to avoid unknow
+// propagation
+assign func_dout = (scan_mode) ? mem_din : mem_dout;
+
+mbist_repair_addr
+ #(.BIST_ADDR_WD (BIST_ADDR_WD),
+ .BIST_DATA_WD (BIST_DATA_WD),
+ .BIST_ADDR_START (BIST_ADDR_START),
+ .BIST_ADDR_END (BIST_ADDR_END),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O))
+ u_repair(
+ .AddressOut (mem_addr ),
+ .Correct (bist_correct ),
+ .sdo (bist_sdo ),
+
+ .AddressIn (addr ),
+ .clk (mem_clk ),
+ .rst_n (rst_n ),
+ .Error (bist_error ),
+ .ErrorAddr (bist_error_addr ),
+ .bist_load (bist_load ),
+ .bist_shift (bist_shift ),
+ .sdi (bist_sdi )
+);
+
+
+
+
+
+endmodule
+
+
+
+
+
+
+
+
+
+
+
diff --git a/verilog/rtl/mbist/src/core/mbist_op_sel.sv b/verilog/rtl/mbist/src/core/mbist_op_sel.sv
new file mode 100644
index 0000000..a995b8e
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_op_sel.sv
@@ -0,0 +1,132 @@
+///////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Operation Selection ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate Operation Selection ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+`include "mbist_def.svh"
+// bist stimulus selection
+
+module mbist_op_sel
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic op_read , // Opertion Read
+ output logic op_write , // Operation Write
+ output logic op_invert , // Opertaion Data Invert
+ output logic op_updown , // Operation Address Up Down
+ output logic op_reverse , // Operation Reverse
+ output logic op_repeatflag , // Operation Repeat flag
+ output logic sdo , // Scan Data Out
+ output logic last_op , // last operation
+
+ input logic clk , // Clock
+ input logic rst_n , // Reset
+ input logic scan_shift , // Scan Shift
+ input logic sdi , // Scan data in
+ input logic re_init , // Re-init when there is error correction
+ input logic run , // Run
+ input logic [BIST_STI_WD-1:0] stimulus
+
+);
+
+
+logic [BIST_OP_SIZE-1:0] op_sel ;// Actual Operation
+logic [7:0] tmp_op ;// Warning : Assming Max opertion is 8
+logic [7:0] tmpinvert ;// read control
+logic [7:0] tmpread ;// write control
+logic [7:0] tmpwrite ;// invertor control
+integer index ;// output index */
+integer loop ;// bit count
+
+
+/* Operation Selection Selection */
+
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) op_sel <= {1'b1,{(BIST_OP_SIZE-1){1'b0}}};
+ else if(scan_shift) op_sel <= {sdi, op_sel[BIST_OP_SIZE-1:1]};
+ else if(re_init) op_sel <= {1'b1,{(BIST_OP_SIZE-1){1'b0}}}; // need fix for pmbist moode
+ else if(run) op_sel <= {op_sel[0],op_sel[BIST_OP_SIZE-1:1]};
+end
+
+assign op_updown = stimulus[BIST_STI_WD-1];
+assign op_reverse = stimulus[BIST_STI_WD-2];
+assign op_repeatflag = stimulus[BIST_STI_WD-3];
+// Re-wind the operation, when the is error correct
+assign last_op = (re_init) ? 1'b0 : op_sel[0];
+
+
+
+always_comb
+begin
+ loop=0;
+ tmpinvert = 8'h0;
+ tmpread = 8'h0;
+ tmpwrite = 8'h0;
+ for(index = 0 ; index < BIST_OP_SIZE ; index = index+1)begin
+ tmpinvert[index] = stimulus[loop];
+ tmpread[index] = stimulus[loop+1];
+ tmpwrite[index] = stimulus[loop+2];
+ loop = loop + 3;
+ end
+end
+
+
+always_comb
+begin
+ tmp_op = 8'b00000000;
+ tmp_op[BIST_OP_SIZE-1:0] = op_sel;
+ case(tmp_op)
+ 8'b10000000: {op_read,op_write,op_invert} = {tmpread[7],tmpwrite[7],tmpinvert[7]};
+ 8'b01000000: {op_read,op_write,op_invert} = {tmpread[6],tmpwrite[6],tmpinvert[6]};
+ 8'b00100000: {op_read,op_write,op_invert} = {tmpread[5],tmpwrite[5],tmpinvert[5]};
+ 8'b00010000: {op_read,op_write,op_invert} = {tmpread[4],tmpwrite[4],tmpinvert[4]};
+ 8'b00001000: {op_read,op_write,op_invert} = {tmpread[3],tmpwrite[3],tmpinvert[3]};
+ 8'b00000100: {op_read,op_write,op_invert} = {tmpread[2],tmpwrite[2],tmpinvert[2]};
+ 8'b00000010: {op_read,op_write,op_invert} = {tmpread[1],tmpwrite[1],tmpinvert[1]};
+ 8'b00000001: {op_read,op_write,op_invert} = {tmpread[0],tmpwrite[0],tmpinvert[0]};
+ default: {op_read,op_write,op_invert} = {tmpread[0],tmpwrite[0],tmpinvert[0]};
+ endcase
+end
+
+
+endmodule
diff --git a/verilog/rtl/mbist/src/core/mbist_pat_sel.sv b/verilog/rtl/mbist/src/core/mbist_pat_sel.sv
new file mode 100644
index 0000000..47a5c98
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_pat_sel.sv
@@ -0,0 +1,116 @@
+///////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Pattern Selection ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist pattern selection ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+`include "mbist_def.svh"
+//-----------------------------------
+// MBIST Data Pattern Selection Logic
+//-----------------------------------
+module mbist_pat_sel
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic pat_last, // Last pattern
+ output logic [BIST_DATA_WD-1:0] pat_data, // pattern data
+ output logic sdo, // scan data output
+ input logic clk, // clock
+ input logic rst_n, // reset
+ input logic run, // stop or start state machine
+ input logic scan_shift, // scan shift
+ input logic sdi // scan input
+
+);
+
+
+logic [BIST_DATA_PAT_SIZE-1:0] pat_sel ;/* Pattern Select */
+logic [63:0] pattern;
+
+integer index ;/* output index */
+
+
+
+// last pattern
+assign pat_last = pat_sel[0];
+
+
+/* Pattern Selection */
+
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) pat_sel <= {1'b1,{(BIST_DATA_PAT_SIZE-1){1'b0}}};
+ else if(scan_shift) pat_sel <= {sdi, pat_sel[BIST_DATA_PAT_SIZE-1:1]};
+ else if(run) pat_sel <= {pat_sel[0],pat_sel[BIST_DATA_PAT_SIZE-1:1]};
+end
+
+
+/* Pattern Selection */
+logic [7:0] tmp_pat;
+always_comb
+begin
+ tmp_pat = 8'b00000000;
+ tmp_pat[7:8-BIST_DATA_PAT_SIZE] = pat_sel;
+ case(tmp_pat)
+ 8'b10000000: pattern = BIST_DATA_PAT_TYPE1;
+ 8'b01000000: pattern = BIST_DATA_PAT_TYPE2;
+ 8'b00100000: pattern = BIST_DATA_PAT_TYPE3;
+ 8'b00010000: pattern = BIST_DATA_PAT_TYPE4;
+ 8'b00001000: pattern = BIST_DATA_PAT_TYPE5;
+ 8'b00000100: pattern = BIST_DATA_PAT_TYPE6;
+ 8'b00000010: pattern = BIST_DATA_PAT_TYPE7;
+ 8'b00000001: pattern = BIST_DATA_PAT_TYPE8;
+ default: pattern = BIST_DATA_PAT_TYPE1;
+ endcase
+end
+
+/* Data distributor */
+
+always_comb
+begin
+ for(index = 0 ; index < BIST_DATA_WD ; index = index + 1) begin
+ pat_data[index] = pattern[index%64];
+ end
+end
+
+assign sdo = pat_sel[0];
+
+endmodule
+
+
diff --git a/verilog/rtl/mbist/src/core/mbist_repair_addr.sv b/verilog/rtl/mbist/src/core/mbist_repair_addr.sv
new file mode 100644
index 0000000..47871d6
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_repair_addr.sv
@@ -0,0 +1,151 @@
+///////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Address Repair ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist address repair ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+// BIST address Repair Logic
+
+`include "mbist_def.svh"
+
+module mbist_repair_addr
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic [BIST_RAD_WD_O-1:0] AddressOut,
+ output logic Correct,
+ output logic sdo, // scan data output
+
+ input logic [BIST_RAD_WD_I-1:0] AddressIn,
+ input logic clk,
+ input logic rst_n,
+ input logic Error,
+ input logic [BIST_RAD_WD_I-1:0] ErrorAddr,
+ input logic bist_load,
+ input logic bist_shift, // shift scan input
+ input logic sdi // scan data input
+
+
+);
+
+logic [3:0] ErrorCnt; // Assumed Maximum Error correction is less than 16
+
+logic [BIST_RAD_WD_I-1:0] RepairMem [0:BIST_ERR_LIMIT-1];
+integer i;
+
+
+always@(posedge clk or negedge rst_n)
+begin
+ if(!rst_n) begin
+ ErrorCnt <= '0;
+ Correct <= '0;
+ // Initialize the Repair RAM for SCAN purpose
+ for(i =0; i < BIST_ERR_LIMIT; i = i+1) begin
+ RepairMem[i] = 'h0;
+ end
+ end else if(Error) begin
+ if(ErrorCnt <= BIST_ERR_LIMIT) begin
+ ErrorCnt <= ErrorCnt+1;
+ RepairMem[ErrorCnt] <= ErrorAddr;
+ Correct <= 1'b1;
+ end else begin
+ Correct <= 1'b0;
+ end
+ end
+end
+
+integer index;
+
+always_comb
+begin
+ AddressOut = AddressIn;
+ for(index=0; index < BIST_ERR_LIMIT; index=index+1) begin
+ if(ErrorCnt > index && AddressIn == RepairMem[index]) begin
+ AddressOut = BIST_REPAIR_ADDR_START+index;
+ $display("STATUS: MBIST ADDRESS REPAIR: %m => Old Addr: %x Nex Addr: %x",AddressIn,AddressOut);
+ end
+ end
+end
+
+/********************************************
+* Serial shifting the Repair address
+* *******************************************/
+integer j;
+logic [0:BIST_ERR_LIMIT-1] sdi_in;
+logic [0:BIST_ERR_LIMIT-1] sdo_out;
+// Daisy chain the Serial In/OUT
+always_comb begin
+ for(j =0; j < BIST_ERR_LIMIT; j=j+1) begin
+ sdi_in[j] =(j==0) ? sdi : sdo_out[j-1];
+ end
+end
+
+assign sdo = sdo_out[BIST_ERR_LIMIT-1];
+
+genvar no;
+generate
+for (no = 0; $unsigned(no) < BIST_ERR_LIMIT; no=no+1) begin : num
+
+ ser_shift
+ #(.WD(16)) u_shift(
+
+ // Master Port
+ .rst_n (rst_n ),
+ .clk (clk ),
+ .load (bist_load ),
+ .shift (bist_shift ),
+ .load_data (RepairMem[no] ),
+ .sdi (sdi_in[no] ),
+ .sdo (sdo_out[no] )
+
+
+ );
+end
+endgenerate
+
+endmodule
+
+
+
+
+
+
diff --git a/verilog/rtl/mbist/src/core/mbist_sti_sel.sv b/verilog/rtl/mbist/src/core/mbist_sti_sel.sv
new file mode 100644
index 0000000..459dc9f
--- /dev/null
+++ b/verilog/rtl/mbist/src/core/mbist_sti_sel.sv
@@ -0,0 +1,105 @@
+///////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST Stimulus Selection ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate stimulus slectiion ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+`include "mbist_def.svh"
+// bist stimulus selection
+
+module mbist_sti_sel
+ #( parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1F8,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+ output logic sdo , // Scan Data Out
+ output logic last_stimulus , // last stimulus
+ output logic [BIST_STI_WD-1:0] stimulus ,
+
+ input logic clk , // Clock
+ input logic rst_n , // Reset
+ input logic scan_shift , // Scan Shift
+ input logic sdi , // Scan data in
+ input logic run // Run
+
+);
+
+logic [BIST_STI_SIZE-1:0] sti_sel ; // Stimulation Selection
+logic [7:0] tmp_sti ; // Warning: Max Stimulus assmed is 8
+
+
+
+/* Pattern Selection */
+
+always @(posedge clk or negedge rst_n) begin
+ if(!rst_n) sti_sel <= {1'b1,{(BIST_STI_SIZE-1){1'b0}}};
+ else if(scan_shift) sti_sel <= {sdi, sti_sel[BIST_STI_SIZE-1:1]};
+ else if(run) sti_sel <= {sti_sel[0],sti_sel[BIST_STI_SIZE-1:1]};
+end
+
+
+/* Pattern Selection */
+always_comb
+begin
+ tmp_sti = 8'b00000000;
+ tmp_sti[7:8-BIST_STI_SIZE] = sti_sel;
+ case(tmp_sti)
+ 8'b10000000: stimulus = BIST_STIMULUS_TYPE1;
+ 8'b01000000: stimulus = BIST_STIMULUS_TYPE2;
+ 8'b00100000: stimulus = BIST_STIMULUS_TYPE3;
+ 8'b00010000: stimulus = BIST_STIMULUS_TYPE4;
+ 8'b00001000: stimulus = BIST_STIMULUS_TYPE5;
+ 8'b00000100: stimulus = BIST_STIMULUS_TYPE6;
+ 8'b00000010: stimulus = BIST_STIMULUS_TYPE7;
+ 8'b00000001: stimulus = BIST_STIMULUS_TYPE8;
+ default: stimulus = BIST_STIMULUS_TYPE1;
+ endcase
+end
+
+
+/* Assign output */
+
+assign sdo = sti_sel[0];
+assign last_stimulus = sti_sel[0];
+
+
+
+endmodule
diff --git a/verilog/rtl/mbist/src/top/mbist_top.sv b/verilog/rtl/mbist/src/top/mbist_top.sv
new file mode 100644
index 0000000..806ce13
--- /dev/null
+++ b/verilog/rtl/mbist/src/top/mbist_top.sv
@@ -0,0 +1,566 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST TOP ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist controller with row ////
+//// redendency feature ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// 0.1 - 26th Oct 2021, Dinesh A ////
+//// Fixed Error Address are serial shifted through ////
+//// sdi/sdo ////
+//// 0.2 - 15 Dec 2021, Dinesh A ////
+//// Added support for common MBIST for 4 SRAM ////
+//// 0.3 - 29th Dec 2021, Dinesh A ////
+//// yosys synthesis issue for two dimension variable ////
+//// changed the variable defination from logic to wire ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "mbist_def.svh"
+module mbist_top
+ #(
+ parameter BIST_NO_SRAM = 4,
+ parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1FB,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+`ifdef USE_POWER_PINS
+ inout vccd1, // User area 1 1.8V supply
+ inout vssd1, // User area 1 digital ground
+`endif
+
+ // Clock Skew Adjust
+ input wire wbd_clk_int,
+ output wire wbd_clk_mbist,
+ input wire [3:0] cfg_cska_mbist, // clock skew adjust for web host
+
+ input logic rst_n,
+
+ // MBIST I/F
+ input wire bist_en,
+ input wire bist_run,
+ input wire bist_shift,
+ input wire bist_load,
+ input wire bist_sdi,
+
+ output wire [3:0] bist_error_cnt0,
+ output wire [3:0] bist_error_cnt1,
+ output wire [3:0] bist_error_cnt2,
+ output wire [3:0] bist_error_cnt3,
+ output wire [BIST_NO_SRAM-1:0] bist_correct ,
+ output wire [BIST_NO_SRAM-1:0] bist_error ,
+ output wire bist_done,
+ output wire bist_sdo,
+
+
+ // WB I/F
+ input wire wb_clk_i, // System clock
+ input wire wb_clk2_i, // System clock2 is no cts
+ input wire mem_req, // strobe/request
+ input wire [(BIST_NO_SRAM+1)/2-1:0] mem_cs,
+ input wire [BIST_ADDR_WD-1:0] mem_addr, // address
+ input wire mem_we , // write
+ input wire [BIST_DATA_WD-1:0] mem_wdata, // data output
+ input wire [BIST_DATA_WD/8-1:0] mem_wmask, // byte enable
+ output wire [BIST_DATA_WD-1:0] mem_rdata, // data input
+
+ // towards memory
+ // PORT-A
+ output wire [BIST_NO_SRAM-1:0] mem_clk_a,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a0,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a1,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a2,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a3,
+ output wire [BIST_NO_SRAM-1:0] mem_cen_a,
+ output wire [BIST_NO_SRAM-1:0] mem_web_a,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a0,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a1,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a2,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a3,
+ output wire [BIST_DATA_WD-1:0] mem_din_a0,
+ output wire [BIST_DATA_WD-1:0] mem_din_a1,
+ output wire [BIST_DATA_WD-1:0] mem_din_a2,
+ output wire [BIST_DATA_WD-1:0] mem_din_a3,
+
+ input wire [BIST_DATA_WD-1:0] mem_dout_a0,
+ input wire [BIST_DATA_WD-1:0] mem_dout_a1,
+ input wire [BIST_DATA_WD-1:0] mem_dout_a2,
+ input wire [BIST_DATA_WD-1:0] mem_dout_a3,
+
+
+ // PORT-B
+ output wire [BIST_NO_SRAM-1:0] mem_clk_b,
+ output wire [BIST_NO_SRAM-1:0] mem_cen_b,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b0,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b1,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b2,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b3
+
+
+
+
+);
+
+parameter NO_SRAM_WD = (BIST_NO_SRAM+1)/2;
+
+// FUNCTIONAL PORT
+wire func_clk[0:BIST_NO_SRAM-1];
+wire func_cen[0:BIST_NO_SRAM-1];
+wire func_web[0:BIST_NO_SRAM-1];
+wire [BIST_DATA_WD/8-1:0]func_mask[0:BIST_NO_SRAM-1];
+wire [BIST_ADDR_WD-1:0]func_addr[0:BIST_NO_SRAM-1];
+wire [BIST_DATA_WD-1:0]func_dout[0:BIST_NO_SRAM-1];
+wire [BIST_DATA_WD-1:0]func_din[0:BIST_NO_SRAM-1];
+
+//----------------------------------------------------
+// Local variable defination
+// ---------------------------------------------------
+//
+wire srst_n ; // sync reset w.r.t bist_clk
+wire cmd_phase ; // Command Phase
+wire cmp_phase ; // Compare Phase
+wire run_op ; // Run next Operation
+wire run_addr ; // Run Next Address
+wire run_sti ; // Run Next Stimulus
+wire run_pat ; // Run Next Pattern
+wire op_updown ; // Adress updown direction
+wire last_addr ; // last address indication
+wire last_sti ; // last stimulus
+wire last_op ; // last operation
+wire last_pat ; // last pattern
+wire [BIST_DATA_WD-1:0] pat_data ; // Selected Data Pattern
+wire [BIST_STI_WD-1:0] stimulus ; // current stimulus
+wire compare ; // compare data
+wire op_repeatflag;
+wire op_reverse;
+wire op_read ;
+wire op_write ;
+wire op_invert ;
+
+
+wire bist_error_correct[0:BIST_NO_SRAM-1] ;
+wire [BIST_ADDR_WD-1:0]bist_error_addr[0:BIST_NO_SRAM-1] ; // bist address
+
+wire [BIST_ADDR_WD-1:0]bist_addr ; // bist address
+wire [BIST_DATA_WD-1:0] bist_wdata ; // bist write data
+wire bist_wr ;
+wire bist_rd ;
+wire [BIST_DATA_WD-1:0] wb_dat[0:BIST_NO_SRAM-1]; // data input
+
+//--------------------------------------------------------
+// As yosys does not support two dimensional var,
+// converting it single dimension
+// -------------------------------------------------------
+wire [3:0] bist_error_cnt_i [0:BIST_NO_SRAM-1];
+
+assign bist_error_cnt0 = bist_error_cnt_i[0];
+assign bist_error_cnt1 = bist_error_cnt_i[1];
+assign bist_error_cnt2 = bist_error_cnt_i[2];
+assign bist_error_cnt3 = bist_error_cnt_i[3];
+
+
+// Towards MEMORY PORT - A
+wire [BIST_ADDR_WD-1:0] mem_addr_a_i[0:BIST_NO_SRAM-1];
+wire [BIST_DATA_WD/8-1:0] mem_mask_a_i[0:BIST_NO_SRAM-1];
+wire [BIST_DATA_WD-1:0] mem_dout_a_i[0:BIST_NO_SRAM-1];
+wire [BIST_DATA_WD-1:0] mem_din_a_i[0:BIST_NO_SRAM-1];
+
+assign mem_addr_a0 = mem_addr_a_i[0];
+assign mem_addr_a1 = mem_addr_a_i[1];
+assign mem_addr_a2 = mem_addr_a_i[2];
+assign mem_addr_a3 = mem_addr_a_i[3];
+
+assign mem_din_a0 = mem_din_a_i[0];
+assign mem_din_a1 = mem_din_a_i[1];
+assign mem_din_a2 = mem_din_a_i[2];
+assign mem_din_a3 = mem_din_a_i[3];
+
+assign mem_mask_a0= mem_mask_a_i[0];
+assign mem_mask_a1= mem_mask_a_i[1];
+assign mem_mask_a2= mem_mask_a_i[2];
+assign mem_mask_a3= mem_mask_a_i[3];
+
+// FROM MEMORY
+assign mem_dout_a_i[0] = mem_dout_a0;
+assign mem_dout_a_i[1] = mem_dout_a1;
+assign mem_dout_a_i[2] = mem_dout_a2;
+assign mem_dout_a_i[3] = mem_dout_a3;
+
+// Towards MEMORY PORT - A
+assign mem_clk_b = 'b0;
+assign mem_cen_b = 'b0;
+assign mem_addr_b0 = 'b0;
+assign mem_addr_b1 = 'b0;
+assign mem_addr_b2 = 'b0;
+assign mem_addr_b3 = 'b0;
+
+//---------------------------------------------------
+// Manage the SDI => SDO Diasy chain
+// --------------------------------------------------
+//---------------------------------
+// SDI => SDO diasy chain
+// bist_sdi => bist_addr_sdo => bist_sti_sdo => bist_op_sdo => bist_pat_sdo => bist_sdo
+// ---------------------------------
+wire bist_addr_sdo ;
+wire bist_sti_sdo ;
+wire bist_op_sdo ;
+wire bist_pat_sdo ;
+
+wire bist_ms_sdi[0:BIST_NO_SRAM-1];
+wire bist_ms_sdo[0:BIST_NO_SRAM-1];
+
+// Adjust the SDI => SDO Daisy chain
+assign bist_ms_sdi[0] = bist_pat_sdo;
+assign bist_ms_sdi[1] = bist_ms_sdo[0];
+assign bist_ms_sdi[2] = bist_ms_sdo[1];
+assign bist_ms_sdi[3] = bist_ms_sdo[2];
+assign bist_sdo = bist_ms_sdo[3];
+
+// Pick the correct read path
+assign mem_rdata = wb_dat[mem_cs];
+
+assign bist_wr = (cmd_phase && op_write);
+assign bist_rd = (cmd_phase && op_read);
+
+assign compare = (cmp_phase && op_read);
+assign bist_wdata = (op_invert) ? ~pat_data : pat_data;
+
+// Clock Tree branching to avoid clock latency towards SRAM path
+wire wb_clk_b1,wb_clk_b2;
+//ctech_clk_buf u_cts_wb_clk_b1 (.A (wb_clk_i), . X(wb_clk_b1));
+//ctech_clk_buf u_cts_wb_clk_b2 (.A (wb_clk_i), . X(wb_clk_b2));
+
+// wb_host clock skew control
+clk_skew_adjust u_skew_mbist
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_mbist ),
+ .clk_out (wbd_clk_mbist )
+ );
+
+reset_sync u_reset_sync (
+ .scan_mode (1'b0 ),
+ .dclk (wb_clk_i ), // Destination clock domain
+ .arst_n (rst_n ), // active low async reset
+ .srst_n (srst_n )
+ );
+
+
+integer i;
+reg bist_error_and;
+reg bist_error_correct_or;
+
+always_comb begin
+ bist_error_and =0;
+ bist_error_correct_or = 0;
+ for(i=0; i <BIST_NO_SRAM; i = i+1) begin
+ bist_error_and = bist_error_and & bist_error[i];
+ bist_error_correct_or = bist_error_correct_or | bist_error_correct[i];
+ end
+end
+
+
+// bist main control FSM
+
+mbist_fsm
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_fsm (
+
+ .cmd_phase (cmd_phase ),
+ .cmp_phase (cmp_phase ),
+ .run_op (run_op ),
+ .run_addr (run_addr ),
+ .run_sti (run_sti ),
+ .run_pat (run_pat ),
+ .bist_done (bist_done ),
+
+
+ .clk (wb_clk_i ),
+ .rst_n (srst_n ),
+ .bist_run (bist_run ),
+ .last_op (last_op ),
+ .last_addr (last_addr ),
+ .last_sti (last_sti ),
+ .last_pat (last_pat ),
+ .op_reverse (op_reverse ),
+ .bist_error (bist_error_and )
+);
+
+
+// bist address generation
+mbist_addr_gen
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_addr_gen(
+ .last_addr (last_addr ),
+ .bist_addr (bist_addr ),
+ .sdo (bist_addr_sdo ),
+
+ .clk (wb_clk_i ),
+ .rst_n (srst_n ),
+ .run (run_addr ),
+ .updown (op_updown ),
+ .bist_shift (bist_shift ),
+ .bist_load (bist_load ),
+ .sdi (bist_sdi )
+
+);
+
+
+// BIST current stimulus selection
+mbist_sti_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_sti_sel(
+
+ .sdo (bist_sti_sdo ),
+ .last_stimulus (last_sti ),
+ .stimulus (stimulus ),
+
+ .clk (wb_clk_i ),
+ .rst_n (srst_n ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_addr_sdo ),
+ .run (run_sti )
+
+);
+
+
+// Bist Operation selection
+mbist_op_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_op_sel (
+
+ .op_read (op_read ),
+ .op_write (op_write ),
+ .op_invert (op_invert ),
+ .op_updown (op_updown ),
+ .op_reverse (op_reverse ),
+ .op_repeatflag (op_repeatflag ),
+ .sdo (bist_op_sdo ),
+ .last_op (last_op ),
+
+ .clk (wb_clk_i ),
+ .rst_n (srst_n ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_sti_sdo ),
+ .re_init (bist_error_correct_or ),
+ .run (run_op ),
+ .stimulus (stimulus )
+
+ );
+
+
+
+mbist_pat_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_pat_sel (
+ .pat_last (last_pat ),
+ .pat_data (pat_data ),
+ .sdo (bist_pat_sdo ),
+ .clk (wb_clk_i ),
+ .rst_n (srst_n ),
+ .run (run_pat ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_op_sdo )
+
+ );
+
+
+
+
+
+genvar sram_no;
+generate
+for (sram_no = 0; $unsigned(sram_no) < BIST_NO_SRAM; sram_no=sram_no+1) begin : mem_no
+
+
+mbist_data_cmp
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+
+
+ u_cmp (
+ .error (bist_error[sram_no] ),
+ .error_correct (bist_error_correct[sram_no] ),
+ .correct ( ), // same signal available at bist mux
+ .error_addr (bist_error_addr[sram_no] ),
+ .error_cnt (bist_error_cnt_i[sram_no] ),
+ .clk (wb_clk_i ),
+ .rst_n (srst_n ),
+ .addr_inc_phase (run_addr ),
+ .compare (compare ),
+ .read_invert (op_invert ),
+ .comp_data (pat_data ),
+ .rxd_data (func_dout[sram_no] ),
+ .addr (bist_addr )
+
+ );
+
+ // WB To Memory Signal Mapping
+ mbist_mem_wrapper #(
+ .BIST_NO_SRAM (BIST_NO_SRAM ),
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD )
+ ) u_mem_wrapper_(
+ .rst_n (srst_n ),
+ // WB I/F
+ .sram_id (NO_SRAM_WD'(sram_no) ),
+ .wb_clk_i (wb_clk2_i ), // System clock
+ .mem_cs (mem_cs ), // Chip Select
+ .mem_req (mem_req ), // strobe/request
+ .mem_addr (mem_addr ), // address
+ .mem_we (mem_we ), // write
+ .mem_wdata (mem_wdata ), // data output
+ .mem_wmask (mem_wmask ), // byte enable
+ .mem_rdata (wb_dat[sram_no] ), // data input
+ // MEM A PORT
+ .func_clk (func_clk[sram_no] ),
+ .func_cen (func_cen[sram_no] ),
+ .func_web (func_web[sram_no] ),
+ .func_mask (func_mask[sram_no] ),
+ .func_addr (func_addr[sram_no] ),
+ .func_din (func_din[sram_no] ),
+ .func_dout (func_dout[sram_no] )
+ );
+
+
+mbist_mux
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_mem_sel (
+
+ .scan_mode (1'b0 ),
+
+ .rst_n (srst_n ),
+ // MBIST CTRL SIGNAL
+ .bist_en (bist_en ),
+ .bist_addr (bist_addr ),
+ .bist_wdata (bist_wdata ),
+ .bist_clk (wb_clk2_i ),
+ .bist_wr (bist_wr ),
+ .bist_rd (bist_rd ),
+ .bist_error (bist_error_correct[sram_no]),
+ .bist_error_addr (bist_error_addr[sram_no] ),
+ .bist_correct (bist_correct[sram_no] ),
+ .bist_sdi (bist_ms_sdi[sram_no] ),
+ .bist_load (bist_load ),
+ .bist_shift (bist_shift ),
+ .bist_sdo (bist_ms_sdo[sram_no] ),
+
+ // FUNCTIONAL CTRL SIGNAL
+ .func_clk (func_clk[sram_no] ),
+ .func_cen (func_cen[sram_no] ),
+ .func_web (func_web[sram_no] ),
+ .func_mask (func_mask[sram_no] ),
+ .func_addr (func_addr[sram_no] ),
+ .func_din (func_din[sram_no] ),
+ .func_dout (func_dout[sram_no] ),
+
+
+ // towards memory
+ // Memory Out Port
+ .mem_clk (mem_clk_a[sram_no] ),
+ .mem_cen (mem_cen_a[sram_no] ),
+ .mem_web (mem_web_a[sram_no] ),
+ .mem_mask (mem_mask_a_i[sram_no] ),
+ .mem_addr (mem_addr_a_i[sram_no] ),
+ .mem_din (mem_din_a_i[sram_no] ),
+ .mem_dout (mem_dout_a_i[sram_no] )
+
+ );
+end
+endgenerate
+
+endmodule
+
diff --git a/verilog/rtl/mbist/src/top/mbist_top1.sv b/verilog/rtl/mbist/src/top/mbist_top1.sv
new file mode 100644
index 0000000..10fdbfd
--- /dev/null
+++ b/verilog/rtl/mbist/src/top/mbist_top1.sv
@@ -0,0 +1,469 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST TOP ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist controller with row ////
+//// redendency feature ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// 0.1 - 26th Oct 2021, Dinesh A ////
+//// Fixed Error Address are serial shifted through ////
+//// sdi/sdo ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "mbist_def.svh"
+module mbist_top1
+ #(
+ parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1FB,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+`ifdef USE_POWER_PINS
+ inout vccd1, // User area 1 1.8V supply
+ inout vssd1, // User area 1 digital ground
+`endif
+
+ // Clock Skew Adjust
+ input logic wbd_clk_int,
+ output logic wbd_clk_mbist,
+ input logic [3:0] cfg_cska_mbist, // clock skew adjust for web host
+
+ input logic rst_n,
+
+ // MBIST I/F
+ input logic bist_en,
+ input logic bist_run,
+ input logic bist_shift,
+ input logic bist_load,
+ input logic bist_sdi,
+
+ output logic [3:0] bist_error_cnt,
+ output logic bist_correct,
+ output logic bist_error,
+ output logic bist_done,
+ output logic bist_sdo,
+
+
+ // WB I/F
+ input logic wb_clk_i, // System clock
+ input logic wb_cyc_i, // strobe/request
+ input logic wb_stb_i, // strobe/request
+ input logic [BIST_ADDR_WD-1:0] wb_adr_i, // address
+ input logic wb_we_i , // write
+ input logic [BIST_DATA_WD-1:0] wb_dat_i, // data output
+ input logic [BIST_DATA_WD/8-1:0] wb_sel_i, // byte enable
+ output logic [BIST_DATA_WD-1:0] wb_dat_o, // data input
+ output logic wb_ack_o, // acknowlegement
+ output logic wb_err_o, // error
+
+ // towards memory
+ // PORT-A
+ output logic mem_clk_a,
+ output logic [BIST_ADDR_WD-1:0]mem_addr_a,
+ output logic mem_cen_a,
+ output logic [BIST_DATA_WD-1:0]mem_din_b,
+ // PORT-B
+ output logic mem_clk_b,
+ output logic mem_cen_b,
+ output logic mem_web_b,
+ output logic [BIST_DATA_WD/8-1:0]mem_mask_b,
+ output logic [BIST_ADDR_WD-1:0]mem_addr_b,
+ input logic [BIST_DATA_WD-1:0]mem_dout_a
+
+
+
+
+);
+
+// FUNCTIONAL A PORT
+logic func_clk_a;
+logic func_cen_a;
+logic [BIST_ADDR_WD-1:0]func_addr_a;
+logic [BIST_DATA_WD-1:0]func_dout_a;
+
+// Functional B Port
+logic func_clk_b;
+logic func_cen_b;
+logic func_web_b;
+logic [BIST_DATA_WD/8-1:0]func_mask_b;
+logic [BIST_ADDR_WD-1:0]func_addr_b;
+logic [BIST_DATA_WD-1:0]func_din_b;
+//----------------------------------------------------
+// Local variable defination
+// ---------------------------------------------------
+//
+logic srst_n ; // sync reset w.r.t bist_clk
+logic cmd_phase ; // Command Phase
+logic cmp_phase ; // Compare Phase
+logic run_op ; // Run next Operation
+logic run_addr ; // Run Next Address
+logic run_sti ; // Run Next Stimulus
+logic run_pat ; // Run Next Pattern
+logic op_updown ; // Adress updown direction
+logic last_addr ; // last address indication
+logic last_sti ; // last stimulus
+logic last_op ; // last operation
+logic last_pat ; // last pattern
+logic [BIST_DATA_WD-1:0] pat_data ; // Selected Data Pattern
+logic [BIST_STI_WD-1:0] stimulus ; // current stimulus
+logic compare ; // compare data
+logic op_repeatflag;
+logic op_reverse;
+logic op_read ;
+logic op_write ;
+logic op_invert ;
+
+//---------------------------------
+// SDI => SDO diasy chain
+// bist_sdi => bist_addr_sdo => bist_sti_sdo => bist_op_sdo => bist_pat_sdo => bist_sdo
+// ---------------------------------
+logic bist_addr_sdo ;
+logic bist_sti_sdo ;
+logic bist_op_sdo ;
+logic bist_pat_sdo ;
+
+logic bist_error_correct ;
+logic [BIST_ADDR_WD-1:0]bist_error_addr ; // bist address
+
+logic [BIST_ADDR_WD-1:0]bist_addr ; // bist address
+logic [BIST_DATA_WD-1:0] bist_wdata ; // bist write data
+logic bist_wr ;
+logic bist_rd ;
+
+
+assign bist_wr = (cmd_phase && op_write);
+assign bist_rd = (cmd_phase && op_read);
+
+assign compare = (cmp_phase && op_read);
+assign bist_wdata = (op_invert) ? ~pat_data : pat_data;
+
+// Clock Tree branching to avoid clock latency towards SRAM path
+wire wb_clk_b1,wb_clk_b2;
+ctech_clk_buf u_cts_wb_clk_b1 (.A (wb_clk_i), . X(wb_clk_b1));
+ctech_clk_buf u_cts_wb_clk_b2 (.A (wb_clk_i), . X(wb_clk_b2));
+
+// wb_host clock skew control
+clk_skew_adjust u_skew_mbist
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_mbist ),
+ .clk_out (wbd_clk_mbist )
+ );
+
+reset_sync u_reset_sync (
+ .scan_mode (1'b0 ),
+ .dclk (wb_clk_b1 ), // Destination clock domain
+ .arst_n (rst_n ), // active low async reset
+ .srst_n (srst_n )
+ );
+
+
+
+// bist main control FSM
+
+mbist_fsm
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_fsm (
+
+ .cmd_phase (cmd_phase ),
+ .cmp_phase (cmp_phase ),
+ .run_op (run_op ),
+ .run_addr (run_addr ),
+ .run_sti (run_sti ),
+ .run_pat (run_pat ),
+ .bist_done (bist_done ),
+
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .bist_run (bist_run ),
+ .last_op (last_op ),
+ .last_addr (last_addr ),
+ .last_sti (last_sti ),
+ .last_pat (last_pat ),
+ .op_reverse (op_reverse ),
+ .bist_error (bist_error )
+);
+
+
+// bist address generation
+mbist_addr_gen
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_addr_gen(
+ .last_addr (last_addr ),
+ .bist_addr (bist_addr ),
+ .sdo (bist_addr_sdo ),
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .run (run_addr ),
+ .updown (op_updown ),
+ .scan_shift (bist_shift ),
+ .scan_load (bist_load ),
+ .sdi (bist_sdi )
+
+);
+
+
+// BIST current stimulus selection
+mbist_sti_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_sti_sel(
+
+ .sdo (bist_sti_sdo ),
+ .last_stimulus (last_sti ),
+ .stimulus (stimulus ),
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_addr_sdo ),
+ .run (run_sti )
+
+);
+
+
+// Bist Operation selection
+mbist_op_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_op_sel (
+
+ .op_read (op_read ),
+ .op_write (op_write ),
+ .op_invert (op_invert ),
+ .op_updown (op_updown ),
+ .op_reverse (op_reverse ),
+ .op_repeatflag (op_repeatflag ),
+ .sdo (bist_op_sdo ),
+ .last_op (last_op ),
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_sti_sdo ),
+ .re_init (bist_error_correct ),
+ .run (run_op ),
+ .stimulus (stimulus )
+
+ );
+
+
+
+mbist_pat_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_pat_sel (
+ .pat_last (last_pat ),
+ .pat_data (pat_data ),
+ .sdo (bist_pat_sdo ),
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .run (run_pat ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_op_sdo )
+
+ );
+
+
+mbist_data_cmp
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+
+
+ u_cmp (
+ .error (bist_error ),
+ .error_correct (bist_error_correct ),
+ .correct ( ), // same signal available at bist mux
+ .error_addr (bist_error_addr ),
+ .error_cnt (bist_error_cnt ),
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .addr_inc_phase (run_addr ),
+ .compare (compare ),
+ .read_invert (op_invert ),
+ .comp_data (pat_data ),
+ .rxd_data (func_dout_a ),
+ .addr (bist_addr )
+
+ );
+
+
+mbist_mem_wrapper #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD )
+ ) u_mem_wrapper(
+ .rst_n (srst_n ),
+ // WB I/F
+ .wb_clk_i (wb_clk_b2 ), // System clock
+ .wb_cyc_i (wb_cyc_i ), // strobe/request
+ .wb_stb_i (wb_stb_i ), // strobe/request
+ .wb_adr_i (wb_adr_i ), // address
+ .wb_we_i (wb_we_i ), // write
+ .wb_dat_i (wb_dat_i ), // data output
+ .wb_sel_i (wb_sel_i ), // byte enable
+ .wb_dat_o (wb_dat_o ), // data input
+ .wb_ack_o (wb_ack_o ), // acknowlegement
+ .wb_err_o (wb_err_o ), // error
+ // MEM A PORT
+ .func_clk_a (func_clk_a ),
+ .func_cen_a (func_cen_a ),
+ .func_addr_a (func_addr_a ),
+ .func_dout_a (func_dout_a ),
+
+ // Functional B Port
+ .func_clk_b (func_clk_b ),
+ .func_cen_b (func_cen_b ),
+ .func_web_b (func_web_b ),
+ .func_mask_b (func_mask_b ),
+ .func_addr_b (func_addr_b ),
+ .func_din_b (func_din_b )
+ );
+
+
+mbist_mux
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_mem_sel (
+
+ .scan_mode (1'b0 ),
+
+ .rst_n (srst_n ),
+ // MBIST CTRL SIGNAL
+ .bist_en (bist_en ),
+ .bist_addr (bist_addr ),
+ .bist_wdata (bist_wdata ),
+ .bist_clk (wb_clk_b2 ),
+ .bist_wr (bist_wr ),
+ .bist_rd (bist_rd ),
+ .bist_error (bist_error_correct),
+ .bist_error_addr (bist_error_addr),
+ .bist_correct (bist_correct ),
+ .bist_sdi (bist_pat_sdo),
+ .bist_shift (bist_shift),
+ .bist_sdo (bist_sdo),
+
+ // FUNCTIONAL CTRL SIGNAL
+ .func_clk_a (func_clk_a ),
+ .func_cen_a (func_cen_a ),
+ .func_addr_a (func_addr_a ),
+ // Common for func and Mbist i/f
+ .func_dout_a (func_dout_a ),
+
+ .func_clk_b (func_clk_b ),
+ .func_cen_b (func_cen_b ),
+ .func_web_b (func_web_b ),
+ .func_mask_b (func_mask_b ),
+ .func_addr_b (func_addr_b ),
+ .func_din_b (func_din_b ),
+
+
+ // towards memory
+ // Memory Out Port
+ .mem_clk_a (mem_clk_a ),
+ .mem_cen_a (mem_cen_a ),
+ .mem_addr_a (mem_addr_a ),
+ .mem_dout_a (mem_dout_a ),
+
+ // Memory Input Port
+ .mem_clk_b (mem_clk_b ),
+ .mem_cen_b (mem_cen_b ),
+ .mem_web_b (mem_web_b ),
+ .mem_mask_b (mem_mask_b ),
+ .mem_addr_b (mem_addr_b ),
+ .mem_din_b (mem_din_b )
+ );
+
+
+endmodule
+
diff --git a/verilog/rtl/mbist/src/top/mbist_top2.sv b/verilog/rtl/mbist/src/top/mbist_top2.sv
new file mode 100644
index 0000000..89433df
--- /dev/null
+++ b/verilog/rtl/mbist/src/top/mbist_top2.sv
@@ -0,0 +1,479 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST TOP ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist controller with row ////
+//// redendency feature ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// 0.1 - 26th Oct 2021, Dinesh A ////
+//// Fixed Error Address are serial shifted through ////
+//// sdi/sdo ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "mbist_def.svh"
+module mbist_top2
+ #( parameter SCW = 8, // SCAN CHAIN WIDTH
+ parameter BIST_ADDR_WD = 8,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 8'h00,
+ parameter BIST_ADDR_END = 8'hFB,
+ parameter BIST_REPAIR_ADDR_START = 8'hFC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+`ifdef USE_POWER_PINS
+ inout vccd1, // User area 1 1.8V supply
+ inout vssd1, // User area 1 digital ground
+`endif
+
+ // Scan I/F
+ input logic scan_en,
+ input logic scan_mode,
+ input logic [SCW-1:0] scan_si,
+ output logic [SCW-1:0] scan_so,
+ output logic scan_en_o,
+ output logic scan_mode_o,
+
+ // Clock Skew Adjust
+ input logic wbd_clk_int,
+ output logic wbd_clk_mbist,
+ input logic [3:0] cfg_cska_mbist, // clock skew adjust for web host
+
+ input logic rst_n,
+
+ // MBIST I/F
+ input logic bist_en,
+ input logic bist_run,
+ input logic bist_shift,
+ input logic bist_load,
+ input logic bist_sdi,
+
+ output logic [3:0] bist_error_cnt,
+ output logic bist_correct,
+ output logic bist_error,
+ output logic bist_done,
+ output logic bist_sdo,
+
+
+ // WB I/F
+ input logic wb_clk_i, // System clock
+ input logic wb_cyc_i, // strobe/request
+ input logic wb_stb_i, // strobe/request
+ input logic [BIST_ADDR_WD-1:0] wb_adr_i, // address
+ input logic wb_we_i , // write
+ input logic [BIST_DATA_WD-1:0] wb_dat_i, // data output
+ input logic [BIST_DATA_WD/8-1:0] wb_sel_i, // byte enable
+ output logic [BIST_DATA_WD-1:0] wb_dat_o, // data input
+ output logic wb_ack_o, // acknowlegement
+ output logic wb_err_o, // error
+
+ // towards memory
+ // PORT-A
+ output logic mem_clk_a,
+ output logic [BIST_ADDR_WD-1:0]mem_addr_a,
+ output logic mem_cen_a,
+ output logic [BIST_DATA_WD-1:0]mem_din_b,
+ // PORT-B
+ output logic mem_clk_b,
+ output logic mem_cen_b,
+ output logic mem_web_b,
+ output logic [BIST_DATA_WD/8-1:0]mem_mask_b,
+ output logic [BIST_ADDR_WD-1:0]mem_addr_b,
+ input logic [BIST_DATA_WD-1:0]mem_dout_a
+
+
+
+
+);
+
+// FUNCTIONAL A PORT
+logic func_clk_a;
+logic func_cen_a;
+logic [BIST_ADDR_WD-1:0]func_addr_a;
+logic [BIST_DATA_WD-1:0]func_dout_a;
+
+// Functional B Port
+logic func_clk_b;
+logic func_cen_b;
+logic func_web_b;
+logic [BIST_DATA_WD/8-1:0]func_mask_b;
+logic [BIST_ADDR_WD-1:0]func_addr_b;
+logic [BIST_DATA_WD-1:0]func_din_b;
+//----------------------------------------------------
+// Local variable defination
+// ---------------------------------------------------
+//
+logic srst_n ; // sync reset w.r.t bist_clk
+logic cmd_phase ; // Command Phase
+logic cmp_phase ; // Compare Phase
+logic run_op ; // Run next Operation
+logic run_addr ; // Run Next Address
+logic run_sti ; // Run Next Stimulus
+logic run_pat ; // Run Next Pattern
+logic op_updown ; // Adress updown direction
+logic last_addr ; // last address indication
+logic last_sti ; // last stimulus
+logic last_op ; // last operation
+logic last_pat ; // last pattern
+logic [BIST_DATA_WD-1:0] pat_data ; // Selected Data Pattern
+logic [BIST_STI_WD-1:0] stimulus ; // current stimulus
+logic compare ; // compare data
+logic op_repeatflag;
+logic op_reverse;
+logic op_read ;
+logic op_write ;
+logic op_invert ;
+
+//---------------------------------
+// SDI => SDO diasy chain
+// bist_sdi => bist_addr_sdo => bist_sti_sdo => bist_op_sdo => bist_pat_sdo => bist_sdo
+// ---------------------------------
+logic bist_addr_sdo ;
+logic bist_sti_sdo ;
+logic bist_op_sdo ;
+logic bist_pat_sdo ;
+
+logic bist_error_correct ;
+logic [BIST_ADDR_WD-1:0]bist_error_addr ; // bist address
+
+logic [BIST_ADDR_WD-1:0]bist_addr ; // bist address
+logic [BIST_DATA_WD-1:0] bist_wdata ; // bist write data
+logic bist_wr ;
+logic bist_rd ;
+
+assign scan_en_o = scan_en;
+assign scan_mode_o = scan_mode;
+
+assign bist_wr = (cmd_phase && op_write);
+assign bist_rd = (cmd_phase && op_read);
+
+assign compare = (cmp_phase && op_read);
+assign bist_wdata = (op_invert) ? ~pat_data : pat_data;
+
+// Clock Tree branching to avoid clock latency towards SRAM path
+wire wb_clk_b1,wb_clk_b2;
+ctech_clk_buf u_cts_wb_clk_b1 (.A (wb_clk_i), . X(wb_clk_b1));
+ctech_clk_buf u_cts_wb_clk_b2 (.A (wb_clk_i), . X(wb_clk_b2));
+
+// wb_host clock skew control
+clk_skew_adjust u_skew_mbist
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_mbist ),
+ .clk_out (wbd_clk_mbist )
+ );
+
+reset_sync u_reset_sync (
+ .scan_mode (scan_mode ),
+ .dclk (wb_clk_b1 ), // Destination clock domain
+ .arst_n (rst_n ), // active low async reset
+ .srst_n (srst_n )
+ );
+
+
+
+// bist main control FSM
+
+mbist_fsm
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_fsm (
+
+ .cmd_phase (cmd_phase ),
+ .cmp_phase (cmp_phase ),
+ .run_op (run_op ),
+ .run_addr (run_addr ),
+ .run_sti (run_sti ),
+ .run_pat (run_pat ),
+ .bist_done (bist_done ),
+
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .bist_run (bist_run ),
+ .last_op (last_op ),
+ .last_addr (last_addr ),
+ .last_sti (last_sti ),
+ .last_pat (last_pat ),
+ .op_reverse (op_reverse ),
+ .bist_error (bist_error )
+);
+
+
+// bist address generation
+mbist_addr_gen
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_addr_gen(
+ .last_addr (last_addr ),
+ .bist_addr (bist_addr ),
+ .sdo (bist_addr_sdo ),
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .run (run_addr ),
+ .updown (op_updown ),
+ .scan_shift (bist_shift ),
+ .scan_load (bist_load ),
+ .sdi (bist_sdi )
+
+);
+
+
+// BIST current stimulus selection
+mbist_sti_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_sti_sel(
+
+ .sdo (bist_sti_sdo ),
+ .last_stimulus (last_sti ),
+ .stimulus (stimulus ),
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_addr_sdo ),
+ .run (run_sti )
+
+);
+
+
+// Bist Operation selection
+mbist_op_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_op_sel (
+
+ .op_read (op_read ),
+ .op_write (op_write ),
+ .op_invert (op_invert ),
+ .op_updown (op_updown ),
+ .op_reverse (op_reverse ),
+ .op_repeatflag (op_repeatflag ),
+ .sdo (bist_op_sdo ),
+ .last_op (last_op ),
+
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_sti_sdo ),
+ .re_init (bist_error_correct ),
+ .run (run_op ),
+ .stimulus (stimulus )
+
+ );
+
+
+
+mbist_pat_sel
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_pat_sel (
+ .pat_last (last_pat ),
+ .pat_data (pat_data ),
+ .sdo (bist_pat_sdo ),
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .run (run_pat ),
+ .scan_shift (bist_shift ),
+ .sdi (bist_op_sdo )
+
+ );
+
+
+mbist_data_cmp
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+
+
+ u_cmp (
+ .error (bist_error ),
+ .error_correct (bist_error_correct ),
+ .correct ( ), // same signal available at bist mux
+ .error_addr (bist_error_addr ),
+ .error_cnt (bist_error_cnt ),
+ .clk (wb_clk_b1 ),
+ .rst_n (srst_n ),
+ .addr_inc_phase (run_addr ),
+ .compare (compare ),
+ .read_invert (op_invert ),
+ .comp_data (pat_data ),
+ .rxd_data (func_dout_a ),
+ .addr (bist_addr )
+
+ );
+
+
+mbist_mem_wrapper #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD )
+ ) u_mem_wrapper(
+ .rst_n (srst_n ),
+ // WB I/F
+ .wb_clk_i (wb_clk_b2 ), // System clock
+ .wb_cyc_i (wb_cyc_i ), // strobe/request
+ .wb_stb_i (wb_stb_i ), // strobe/request
+ .wb_adr_i (wb_adr_i ), // address
+ .wb_we_i (wb_we_i ), // write
+ .wb_dat_i (wb_dat_i ), // data output
+ .wb_sel_i (wb_sel_i ), // byte enable
+ .wb_dat_o (wb_dat_o ), // data input
+ .wb_ack_o (wb_ack_o ), // acknowlegement
+ .wb_err_o (wb_err_o ), // error
+ // MEM A PORT
+ .func_clk_a (func_clk_a ),
+ .func_cen_a (func_cen_a ),
+ .func_addr_a (func_addr_a ),
+ .func_dout_a (func_dout_a ),
+
+ // Functional B Port
+ .func_clk_b (func_clk_b ),
+ .func_cen_b (func_cen_b ),
+ .func_web_b (func_web_b ),
+ .func_mask_b (func_mask_b ),
+ .func_addr_b (func_addr_b ),
+ .func_din_b (func_din_b )
+ );
+
+
+mbist_mux
+ #(
+ .BIST_ADDR_WD (BIST_ADDR_WD ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (BIST_ADDR_START ),
+ .BIST_ADDR_END (BIST_ADDR_END ),
+ .BIST_REPAIR_ADDR_START (BIST_REPAIR_ADDR_START ),
+ .BIST_RAD_WD_I (BIST_RAD_WD_I ),
+ .BIST_RAD_WD_O (BIST_RAD_WD_O )
+ )
+ u_mem_sel (
+
+ .scan_mode (scan_mode ),
+
+ .rst_n (srst_n ),
+ // MBIST CTRL SIGNAL
+ .bist_en (bist_en ),
+ .bist_addr (bist_addr ),
+ .bist_wdata (bist_wdata ),
+ .bist_clk (wb_clk_b2 ),
+ .bist_wr (bist_wr ),
+ .bist_rd (bist_rd ),
+ .bist_error (bist_error_correct),
+ .bist_error_addr (bist_error_addr),
+ .bist_correct (bist_correct ),
+ .bist_sdi (bist_pat_sdo),
+ .bist_shift (bist_shift),
+ .bist_sdo (bist_sdo),
+
+ // FUNCTIONAL CTRL SIGNAL
+ .func_clk_a (func_clk_a ),
+ .func_cen_a (func_cen_a ),
+ .func_addr_a (func_addr_a ),
+ // Common for func and Mbist i/f
+ .func_dout_a (func_dout_a ),
+
+ .func_clk_b (func_clk_b ),
+ .func_cen_b (func_cen_b ),
+ .func_web_b (func_web_b ),
+ .func_mask_b (func_mask_b ),
+ .func_addr_b (func_addr_b ),
+ .func_din_b (func_din_b ),
+
+
+ // towards memory
+ // Memory Out Port
+ .mem_clk_a (mem_clk_a ),
+ .mem_cen_a (mem_cen_a ),
+ .mem_addr_a (mem_addr_a ),
+ .mem_dout_a (mem_dout_a ),
+
+ // Memory Input Port
+ .mem_clk_b (mem_clk_b ),
+ .mem_cen_b (mem_cen_b ),
+ .mem_web_b (mem_web_b ),
+ .mem_mask_b (mem_mask_b ),
+ .mem_addr_b (mem_addr_b ),
+ .mem_din_b (mem_din_b )
+ );
+
+
+endmodule
+
diff --git a/verilog/rtl/mbist_wrapper/src/mbist_wb.sv b/verilog/rtl/mbist_wrapper/src/mbist_wb.sv
new file mode 100644
index 0000000..ef989dd
--- /dev/null
+++ b/verilog/rtl/mbist_wrapper/src/mbist_wb.sv
@@ -0,0 +1,179 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//
+// MBIST wishbone Burst access to SRAM Write and Read access
+// Note: BUSRT crossing the SRAM boundary is not supported due to sram
+// 2 cycle pipe line delay
+//////////////////////////////////////////////////////////////////////
+
+module mbist_wb
+ #(
+ parameter BIST_NO_SRAM = 4,
+ parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32) (
+
+`ifdef USE_POWER_PINS
+ inout vccd1, // User area 1 1.8V supply
+ inout vssd1, // User area 1 digital ground
+`endif
+
+
+ input logic rst_n,
+
+
+ // WB I/F
+ input logic wb_clk_i, // System clock
+ input logic wb_stb_i, // strobe/request
+ input logic [BIST_ADDR_WD-1:0] wb_adr_i, // address
+ input logic [(BIST_NO_SRAM+1)/2-1:0] wb_cs_i, // address
+ input logic wb_we_i , // write
+ input logic [BIST_DATA_WD-1:0] wb_dat_i, // data output
+ input logic [BIST_DATA_WD/8-1:0] wb_sel_i, // byte enable
+ input logic [9:0] wb_bl_i, // Burst Length
+ input logic wb_bry_i, // Burst Ready
+ output logic [BIST_DATA_WD-1:0] wb_dat_o, // data input
+ output logic wb_ack_o, // acknowlegement
+ output logic wb_lack_o, // acknowlegement
+ output logic wb_err_o, // error
+
+ output logic mem_req,
+ output logic [(BIST_NO_SRAM+1)/2-1:0] mem_cs,
+ output logic [BIST_ADDR_WD-1:0] mem_addr,
+ output logic [31:0] mem_wdata,
+ output logic mem_we,
+ output logic [3:0] mem_wmask,
+ input logic [31:0] mem_rdata
+
+
+
+
+);
+
+parameter IDLE = 2'b00;
+parameter WRITE_ACTION = 2'b01;
+parameter READ_ACTION1 = 2'b10;
+parameter READ_ACTION2 = 2'b11;
+
+
+logic [9:0] mem_bl_cnt ;
+logic wb_ack_l ;
+logic [BIST_ADDR_WD-1:0] mem_next_addr;
+logic [1:0] state;
+logic mem_hval; // Mem Hold Data valid
+logic [31:0] mem_hdata; // Mem Hold Data
+
+
+assign mem_wdata = wb_dat_i;
+
+always @(negedge rst_n, posedge wb_clk_i) begin
+ if (~rst_n) begin
+ mem_bl_cnt <= 'h0;
+ mem_addr <= 'h0;
+ mem_next_addr <= 'h0;
+ wb_ack_l <= 'b0;
+ wb_dat_o <= 'h0;
+ mem_req <= 'b0;
+ mem_cs <= 'b0;
+ mem_wmask <= 'h0;
+ mem_we <= 'h0;
+ mem_hval <= 'b0;
+ mem_hdata <= 'h0;
+ state <= IDLE;
+ end else begin
+ case(state)
+ IDLE: begin
+ mem_bl_cnt <= 'h1;
+ wb_ack_o <= 'b0;
+ wb_lack_o <= 'b0;
+ if(wb_stb_i && wb_bry_i && ~wb_we_i && !wb_lack_o) begin
+ mem_cs <= wb_cs_i;
+ mem_addr <= wb_adr_i;
+ mem_req <= 'b1;
+ mem_we <= 'b0;
+ state <= READ_ACTION1;
+ end else if(wb_stb_i && wb_bry_i && wb_we_i && !wb_lack_o) begin
+ mem_cs <= wb_cs_i;
+ mem_next_addr<= wb_adr_i;
+ mem_we <= 'b1;
+ mem_wmask <= wb_sel_i;
+ state <= WRITE_ACTION;
+ end else begin
+ mem_req <= 1'b0;
+ end
+ end
+
+ WRITE_ACTION: begin
+ if (wb_stb_i && wb_bry_i ) begin
+ wb_ack_o <= 'b1;
+ mem_req <= 1'b1;
+ mem_addr <= mem_next_addr;
+ if((wb_stb_i && wb_bry_i ) && (wb_bl_i == mem_bl_cnt)) begin
+ wb_lack_o <= 'b1;
+ state <= IDLE;
+ end else begin
+ mem_bl_cnt <= mem_bl_cnt+1;
+ mem_next_addr<= mem_next_addr+1;
+ end
+ end else begin
+ wb_ack_o <= 'b0;
+ mem_req <= 1'b0;
+ end
+ end
+ READ_ACTION1: begin
+ mem_addr <= mem_addr +1;
+ mem_hval <= 1'b0;
+ wb_ack_l <= 'b1;
+ mem_bl_cnt <= 'h1;
+ state <= READ_ACTION2;
+ end
+
+ // Wait for Ack from application layer
+ READ_ACTION2: begin
+ // If the not the last ack, update memory pointer
+ // accordingly
+ wb_ack_l <= wb_ack_o;
+ if (wb_stb_i && wb_bry_i ) begin
+ wb_ack_o <= 1'b1;
+ mem_bl_cnt <= mem_bl_cnt+1;
+ mem_addr <= mem_addr +1;
+ if(wb_ack_l || wb_ack_o ) begin // If back to back ack
+ wb_dat_o <= mem_rdata;
+ mem_hval <= 1'b0;
+ end else begin // Pick from previous holding data
+ mem_hval <= 1'b1;
+ wb_dat_o <= mem_hdata;
+ mem_hdata <= mem_rdata;
+ end
+ if((wb_stb_i && wb_bry_i ) && (wb_bl_i == mem_bl_cnt)) begin
+ wb_lack_o <= 1'b1;
+ state <= IDLE;
+ end
+ end else begin
+ wb_ack_o <= 1'b0;
+ if(!mem_hval) begin
+ mem_hdata <= mem_rdata;
+ mem_hval <= 1'b1;
+ end
+ end
+ end
+ endcase
+ end
+end
+
+endmodule
diff --git a/verilog/rtl/mbist_wrapper/src/mbist_wrapper.sv b/verilog/rtl/mbist_wrapper/src/mbist_wrapper.sv
new file mode 100644
index 0000000..07c5ce3
--- /dev/null
+++ b/verilog/rtl/mbist_wrapper/src/mbist_wrapper.sv
@@ -0,0 +1,369 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// MBIST TOP ////
+//// ////
+//// This file is part of the mbist_ctrl cores project ////
+//// https://github.com/dineshannayya/mbist_ctrl.git ////
+//// ////
+//// Description ////
+//// This block integrate mbist controller with row ////
+//// redendency feature ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.0 - 11th Oct 2021, Dinesh A ////
+//// Initial integration ////
+//// 0.1 - 26th Oct 2021, Dinesh A ////
+//// Fixed Error Address are serial shifted through ////
+//// sdi/sdo ////
+//// 0.2 - 15 Dec 2021, Dinesh A ////
+//// Added support for common MBIST for 4 SRAM ////
+//// 0.3 - 29th Dec 2021, Dinesh A ////
+//// yosys synthesis issue for two dimension variable ////
+//// changed the variable defination from logic to wire ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "mbist_def.svh"
+module mbist_wrapper
+ #(
+ parameter BIST_NO_SRAM = 4,
+ parameter BIST_ADDR_WD = 9,
+ parameter BIST_DATA_WD = 32,
+ parameter BIST_ADDR_START = 9'h000,
+ parameter BIST_ADDR_END = 9'h1FB,
+ parameter BIST_REPAIR_ADDR_START = 9'h1FC,
+ parameter BIST_RAD_WD_I = BIST_ADDR_WD,
+ parameter BIST_RAD_WD_O = BIST_ADDR_WD) (
+
+`ifdef USE_POWER_PINS
+ inout vccd1, // User area 1 1.8V supply
+ inout vssd1, // User area 1 digital ground
+`endif
+
+ // Clock Skew Adjust
+ input wire wbd_clk_int,
+ output wire wbd_clk_mbist,
+ input wire [3:0] cfg_cska_mbist, // clock skew adjust for web host
+
+ input logic rst_n,
+
+ // MBIST I/F
+ input wire bist_en,
+ input wire bist_run,
+ input wire bist_shift,
+ input wire bist_load,
+ input wire bist_sdi,
+
+ output wire [3:0] bist_error_cnt0,
+ output wire [3:0] bist_error_cnt1,
+ output wire [3:0] bist_error_cnt2,
+ output wire [3:0] bist_error_cnt3,
+ output wire [BIST_NO_SRAM-1:0] bist_correct ,
+ output wire [BIST_NO_SRAM-1:0] bist_error ,
+ output wire bist_done,
+ output wire bist_sdo,
+
+
+ // WB I/F
+ input wire wb_clk_i, // System clock
+ input wire wb_clk2_i, // System clock2 is no cts
+ input wire wb_stb_i, // strobe/request
+ input wire [(BIST_NO_SRAM+1)/2-1:0] wb_cs_i,
+ input wire [BIST_ADDR_WD-1:0] wb_adr_i, // address
+ input wire wb_we_i , // write
+ input wire [BIST_DATA_WD-1:0] wb_dat_i, // data output
+ input wire [BIST_DATA_WD/8-1:0] wb_sel_i, // byte enable
+ input wire [9:0] wb_bl_i, // burst
+ input wire wb_bry_i, // burst ready
+ output wire [BIST_DATA_WD-1:0] wb_dat_o, // data input
+ output wire wb_ack_o, // acknowlegement
+ output wire wb_lack_o, // acknowlegement
+ output wire wb_err_o, // error
+
+
+ // towards memory
+ // PORT-A
+ output wire [BIST_NO_SRAM-1:0] mem_clk_a,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a0,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a1,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a2,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_a3,
+ output wire [BIST_NO_SRAM-1:0] mem_cen_a,
+ output wire [BIST_NO_SRAM-1:0] mem_web_a,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a0,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a1,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a2,
+ output wire [BIST_DATA_WD/8-1:0] mem_mask_a3,
+ output wire [BIST_DATA_WD-1:0] mem_din_a0,
+ output wire [BIST_DATA_WD-1:0] mem_din_a1,
+ output wire [BIST_DATA_WD-1:0] mem_din_a2,
+ output wire [BIST_DATA_WD-1:0] mem_din_a3,
+
+ input wire [BIST_DATA_WD-1:0] mem_dout_a0,
+ input wire [BIST_DATA_WD-1:0] mem_dout_a1,
+ input wire [BIST_DATA_WD-1:0] mem_dout_a2,
+ input wire [BIST_DATA_WD-1:0] mem_dout_a3,
+
+
+ // PORT-B
+ output wire [BIST_NO_SRAM-1:0] mem_clk_b,
+ output wire [BIST_NO_SRAM-1:0] mem_cen_b,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b0,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b1,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b2,
+ output wire [BIST_ADDR_WD-1:0] mem_addr_b3
+
+
+
+);
+
+parameter NO_SRAM_WD = (BIST_NO_SRAM+1)/2;
+parameter BIST1_ADDR_WD = 11; // 512x32 SRAM
+
+logic mem_req; // strobe/request
+logic [(BIST_NO_SRAM+1)/2-1:0] mem_cs;
+logic [BIST_ADDR_WD-1:0] mem_addr; // address
+logic mem_we ; // write
+logic [BIST_DATA_WD-1:0] mem_wdata; // data output
+logic [BIST_DATA_WD/8-1:0] mem_wmask; // byte enable
+logic [BIST_DATA_WD-1:0] mem_rdata; // data input
+
+
+mbist_wb #(
+ .BIST_NO_SRAM (4 ),
+ .BIST_ADDR_WD (BIST1_ADDR_WD-2 ),
+ .BIST_DATA_WD (BIST_DATA_WD )
+ )
+ u_wb (
+
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+
+ .rst_n (rst_n ),
+ // WB I/F
+ .wb_clk_i (wb_clk_i ),
+ .wb_stb_i (wb_stb_i ),
+ .wb_cs_i (wb_cs_i ),
+ .wb_adr_i (wb_adr_i ),
+ .wb_we_i (wb_we_i ),
+ .wb_dat_i (wb_dat_i ),
+ .wb_sel_i (wb_sel_i ),
+ .wb_bl_i (wb_bl_i ),
+ .wb_bry_i (wb_bry_i ),
+ .wb_dat_o (wb_dat_o ),
+ .wb_ack_o (wb_ack_o ),
+ .wb_lack_o (wb_lack_o ),
+ .wb_err_o ( ),
+
+ .mem_req (mem_req ),
+ .mem_cs (mem_cs ),
+ .mem_addr (mem_addr ),
+ .mem_we (mem_we ),
+ .mem_wdata (mem_wdata ),
+ .mem_wmask (mem_wmask ),
+ .mem_rdata (mem_rdata )
+
+
+
+
+);
+
+
+mbist_top #(
+ `ifndef SYNTHESIS
+ .BIST_NO_SRAM (4 ),
+ .BIST_ADDR_WD (BIST1_ADDR_WD-2 ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (9'h000 ),
+ .BIST_ADDR_END (9'h1FB ),
+ .BIST_REPAIR_ADDR_START (9'h1FC ),
+ .BIST_RAD_WD_I (BIST1_ADDR_WD-2 ),
+ .BIST_RAD_WD_O (BIST1_ADDR_WD-2 )
+ `endif
+ )
+ u_mbist (
+
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+
+ // Clock Skew adjust
+ .wbd_clk_int (wbd_clk_int ),
+ .cfg_cska_mbist (cfg_cska_mbist ),
+ .wbd_clk_mbist (wbd_clk_mbist ),
+
+ // WB I/F
+ .wb_clk2_i (wb_clk2_i ),
+ .wb_clk_i (wb_clk_i ),
+ .mem_req (mem_req ),
+ .mem_cs (mem_cs ),
+ .mem_addr (mem_addr ),
+ .mem_we (mem_we ),
+ .mem_wdata (mem_wdata ),
+ .mem_wmask (mem_wmask ),
+ .mem_rdata (mem_rdata ),
+
+ .rst_n (rst_n ),
+
+
+ .bist_en (bist_en ),
+ .bist_run (bist_run ),
+ .bist_shift (bist_shift ),
+ .bist_load (bist_load ),
+ .bist_sdi (bist_sdi ),
+
+ .bist_error_cnt3 (bist_error_cnt3 ),
+ .bist_error_cnt2 (bist_error_cnt2 ),
+ .bist_error_cnt1 (bist_error_cnt1 ),
+ .bist_error_cnt0 (bist_error_cnt0 ),
+ .bist_correct (bist_correct ),
+ .bist_error (bist_error ),
+ .bist_done (bist_done ),
+ .bist_sdo (bist_sdo ),
+
+ // towards memory
+ // PORT-A
+ .mem_clk_a (mem_clk_a ),
+ .mem_addr_a0 (mem_addr_a0 ),
+ .mem_addr_a1 (mem_addr_a1 ),
+ .mem_addr_a2 (mem_addr_a2 ),
+ .mem_addr_a3 (mem_addr_a3 ),
+ .mem_cen_a (mem_cen_a ),
+ .mem_web_a (mem_web_a ),
+ .mem_mask_a0 (mem_mask_a0 ),
+ .mem_mask_a1 (mem_mask_a1 ),
+ .mem_mask_a2 (mem_mask_a2 ),
+ .mem_mask_a3 (mem_mask_a3 ),
+ .mem_din_a0 (mem_din_a0 ),
+ .mem_din_a1 (mem_din_a1 ),
+ .mem_din_a2 (mem_din_a2 ),
+ .mem_din_a3 (mem_din_a3 ),
+ .mem_dout_a0 (mem_dout_a0 ),
+ .mem_dout_a1 (mem_dout_a1 ),
+ .mem_dout_a2 (mem_dout_a2 ),
+ .mem_dout_a3 (mem_dout_a3 ),
+ // PORT-B
+ .mem_clk_b (mem_clk_b ),
+ .mem_cen_b (mem_cen_b ),
+ .mem_addr_b0 (mem_addr_b0 ),
+ .mem_addr_b1 (mem_addr_b1 ),
+ .mem_addr_b2 (mem_addr_b2 ),
+ .mem_addr_b3 (mem_addr_b3 )
+
+
+);
+
+
+/**
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram0_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1),// User area 1 1.8V supply
+ .vssd1 (vssd1),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[0]),
+ .csb0 (mem_cen_a[0]),
+ .web0 (mem_web_a[0]),
+ .wmask0 (mem0_mask_a),
+ .addr0 (mem0_addr_a),
+ .din0 (mem0_din_a),
+ .dout0 (mem0_dout_a),
+// Port 1: R
+ .clk1 (mem_clk_b[0]),
+ .csb1 (mem_cen_b[0]),
+ .addr1 (mem0_addr_b),
+ .dout1 ()
+ );
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram1_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1),// User area 1 1.8V supply
+ .vssd1 (vssd1),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[1]),
+ .csb0 (mem_cen_a[1]),
+ .web0 (mem_web_a[1]),
+ .wmask0 (mem1_mask_a),
+ .addr0 (mem1_addr_a),
+ .din0 (mem1_din_a),
+ .dout0 (mem1_dout_a),
+// Port 1: R
+ .clk1 (mem_clk_b[1]),
+ .csb1 (mem_cen_b[1]),
+ .addr1 (mem1_addr_b),
+ .dout1 ()
+ );
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram2_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1),// User area 1 1.8V supply
+ .vssd1 (vssd1),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[2]),
+ .csb0 (mem_cen_a[2]),
+ .web0 (mem_web_a[2]),
+ .wmask0 (mem2_mask_a),
+ .addr0 (mem2_addr_a),
+ .din0 (mem2_din_a),
+ .dout0 (mem2_dout_a),
+// Port 1: R
+ .clk1 (mem_clk_b[2]),
+ .csb1 (mem_cen_b[2]),
+ .addr1 (mem2_addr_b),
+ .dout1 ()
+ );
+
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram3_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1),// User area 1 1.8V supply
+ .vssd1 (vssd1),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[3]),
+ .csb0 (mem_cen_a[3]),
+ .web0 (mem_web_a[3]),
+ .wmask0 (mem3_mask_a),
+ .addr0 (mem3_addr_a),
+ .din0 (mem3_din_a),
+ .dout0 (mem3_dout_a),
+// Port 1: R
+ .clk1 (mem_clk_b[3]),
+ .csb1 (mem_cen_b[3]),
+ .addr1 (mem3_addr_b),
+ .dout1 ()
+ );
+
+
+***/
+
+endmodule
+
diff --git a/verilog/rtl/pinmux/src/gpio_control.sv b/verilog/rtl/pinmux/src/gpio_control.sv
new file mode 100644
index 0000000..4c917dc
--- /dev/null
+++ b/verilog/rtl/pinmux/src/gpio_control.sv
@@ -0,0 +1,44 @@
+
+// GPIO Interrupt Generation
+module gpio_intr (
+ input logic mclk ,// System clk
+ input logic h_reset_n ,// system reset
+ input logic [31:0] gpio_prev_indata ,// previously captured GPIO I/P pins data
+ input logic [31:0] cfg_gpio_data_in ,// GPIO I/P pins data captured into this
+ input logic [31:0] cfg_gpio_out_data ,// GPIO statuc O/P data from config reg
+ input logic [31:0] cfg_gpio_dir_sel ,// decides on GPIO pin is I/P or O/P at pad level
+ input logic [31:0] cfg_gpio_posedge_int_sel ,// select posedge interrupt
+ input logic [31:0] cfg_gpio_negedge_int_sel ,// select negedge interrupt
+
+
+ output logic [31:0] pad_gpio_out ,// GPIO O/P to the gpio cfg reg
+ output logic [31:0] gpio_int_event // to the cfg interrupt status reg
+
+);
+
+
+integer i;
+//-----------------------------------------------------------------------
+// Logic for interrupt detection
+//-----------------------------------------------------------------------
+
+reg [31:0] local_gpio_int_event; // to the cfg interrupt status reg
+always @(cfg_gpio_data_in or cfg_gpio_negedge_int_sel or cfg_gpio_posedge_int_sel
+ or gpio_prev_indata)
+begin
+ for (i=0; i<32; i=i+1)
+ begin
+ // looking for rising edge int
+ local_gpio_int_event[i] = ((cfg_gpio_posedge_int_sel[i] & ~gpio_prev_indata[i]
+ & cfg_gpio_data_in[i]) |
+ (cfg_gpio_negedge_int_sel[i] & gpio_prev_indata[i] &
+ ~cfg_gpio_data_in[i]));
+ // looking for falling edge int
+ end
+end
+
+assign gpio_int_event = local_gpio_int_event[31:0]; // goes as O/P to the cfg reg
+
+assign pad_gpio_out = cfg_gpio_out_data[31:0] ;// O/P on the GPIO bus
+
+endmodule
diff --git a/verilog/rtl/pinmux/src/gpio_intr.sv b/verilog/rtl/pinmux/src/gpio_intr.sv
new file mode 100644
index 0000000..331918d
--- /dev/null
+++ b/verilog/rtl/pinmux/src/gpio_intr.sv
@@ -0,0 +1,43 @@
+
+// GPIO Interrupt Generation
+module gpio_intr (
+ input logic mclk ,// System clk
+ input logic h_reset_n ,// system reset
+ input logic [31:0] gpio_prev_indata ,// previously captured GPIO I/P pins data
+ input logic [31:0] cfg_gpio_data_in ,// GPIO I/P pins data captured into this
+ input logic [31:0] cfg_gpio_out_data ,// GPIO statuc O/P data from config reg
+ input logic [31:0] cfg_gpio_dir_sel ,// decides on GPIO pin is I/P or O/P at pad level
+ input logic [31:0] cfg_gpio_posedge_int_sel ,// select posedge interrupt
+ input logic [31:0] cfg_gpio_negedge_int_sel ,// select negedge interrupt
+
+
+ output logic [31:0] pad_gpio_out ,// GPIO O/P to the gpio cfg reg
+ output logic [31:0] gpio_int_event // to the cfg interrupt status reg
+
+);
+
+
+integer i;
+//-----------------------------------------------------------------------
+// Logic for interrupt detection
+//-----------------------------------------------------------------------
+
+reg [31:0] local_gpio_int_event; // to the cfg interrupt status reg
+always_comb
+begin
+ for (i=0; i<32; i=i+1)
+ begin
+ // looking for rising edge int
+ local_gpio_int_event[i] = ((cfg_gpio_posedge_int_sel[i] & ~gpio_prev_indata[i]
+ & cfg_gpio_data_in[i]) |
+ (cfg_gpio_negedge_int_sel[i] & gpio_prev_indata[i] &
+ ~cfg_gpio_data_in[i]));
+ // looking for falling edge int
+ end
+end
+
+assign gpio_int_event = local_gpio_int_event[31:0]; // goes as O/P to the cfg reg
+
+assign pad_gpio_out = cfg_gpio_out_data[31:0] ;// O/P on the GPIO bus
+
+endmodule
diff --git a/verilog/rtl/pinmux/src/pinmux.sv b/verilog/rtl/pinmux/src/pinmux.sv
new file mode 100755
index 0000000..46a69a4
--- /dev/null
+++ b/verilog/rtl/pinmux/src/pinmux.sv
@@ -0,0 +1,801 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Pinmux ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// PinMux Manages all the pin multiplexing ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 16th Feb 2021, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+
+module pinmux (
+ `ifdef USE_POWER_PINS
+ input logic vccd1,// User area 1 1.8V supply
+ input logic vssd1,// User area 1 digital ground
+ `endif
+ // clock skew adjust
+ input logic [3:0] cfg_cska_pinmux,
+ input logic wbd_clk_int,
+ output logic wbd_clk_pinmux,
+ // System Signals
+ // Inputs
+ input logic mclk,
+ input logic h_reset_n,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [7:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ // Risc configuration
+ output logic [31:0] fuse_mhartid,
+ output logic [15:0] irq_lines,
+ output logic soft_irq,
+ output logic [2:0] user_irq,
+ input logic usb_intr,
+ input logic i2cm_intr,
+
+ // Digital IO
+ output logic [37:0] digital_io_out,
+ output logic [37:0] digital_io_oen,
+ input logic [37:0] digital_io_in,
+
+ // SFLASH I/F
+ input logic sflash_sck,
+ input logic [3:0] sflash_ss,
+ input logic [3:0] sflash_oen,
+ input logic [3:0] sflash_do,
+ output logic [3:0] sflash_di,
+
+ // SSRAM I/F - Temp Masked
+ //input logic ssram_sck,
+ //input logic ssram_ss,
+ //input logic [3:0] ssram_oen,
+ //input logic [3:0] ssram_do,
+ //output logic [3:0] ssram_di,
+
+ // USB I/F
+ input logic usb_dp_o,
+ input logic usb_dn_o,
+ input logic usb_oen,
+ output logic usb_dp_i,
+ output logic usb_dn_i,
+
+ // UART I/F
+ input logic uart_txd,
+ output logic uart_rxd,
+
+ // I2CM I/F
+ input logic i2cm_clk_o,
+ output logic i2cm_clk_i,
+ input logic i2cm_clk_oen,
+ input logic i2cm_data_oen,
+ input logic i2cm_data_o,
+ output logic i2cm_data_i,
+
+ // SPI MASTER
+ input logic spim_sck,
+ input logic spim_ss,
+ input logic spim_miso,
+ output logic spim_mosi,
+
+ // UART MASTER I/F
+ output logic uartm_rxd ,
+ input logic uartm_txd ,
+
+ output logic pulse1m_mclk,
+ output logic [31:0] pinmux_debug,
+
+ // BIST I/F
+ output logic bist_en,
+ output logic bist_run,
+ output logic bist_load,
+
+ output logic bist_sdi,
+ output logic bist_shift,
+ input logic bist_sdo,
+
+ input logic bist_done,
+ input logic [3:0] bist_error,
+ input logic [3:0] bist_correct,
+ input logic [3:0] bist_error_cnt0,
+ input logic [3:0] bist_error_cnt1,
+ input logic [3:0] bist_error_cnt2,
+ input logic [3:0] bist_error_cnt3
+ );
+
+
+
+
+/* clock pulse */
+//********************************************************
+logic pulse1u_mclk ;// 1 UsSecond Pulse for waveform Generator
+logic pulse1s_mclk ;// 1Second Pulse for waveform Generator
+logic [9:0] cfg_pulse_1us ;// 1us pulse generation config
+
+//---------------------------------------------------
+// 6 PWM variabled
+//---------------------------------------------------
+
+logic [5:0] pwm_wfm ;
+logic [5:0] cfg_pwm_enb ;
+logic [15:0] cfg_pwm0_high ;
+logic [15:0] cfg_pwm0_low ;
+logic [15:0] cfg_pwm1_high ;
+logic [15:0] cfg_pwm1_low ;
+logic [15:0] cfg_pwm2_high ;
+logic [15:0] cfg_pwm2_low ;
+logic [15:0] cfg_pwm3_high ;
+logic [15:0] cfg_pwm3_low ;
+logic [15:0] cfg_pwm4_high ;
+logic [15:0] cfg_pwm4_low ;
+logic [15:0] cfg_pwm5_high ;
+logic [15:0] cfg_pwm5_low ;
+
+
+wire [31:0] gpio_prev_indata ;// previously captured GPIO I/P pins data
+wire [31:0] cfg_gpio_out_data ;// GPIO statuc O/P data from config reg
+wire [31:0] cfg_gpio_dir_sel ;// decides on GPIO pin is I/P or O/P at pad level, 0 -> Input, 1 -> Output
+wire [31:0] cfg_gpio_out_type ;// GPIO Type, Unused
+wire [31:0] cfg_multi_func_sel ;// GPIO Multi function type
+wire [31:0] cfg_gpio_posedge_int_sel ;// select posedge interrupt
+wire [31:0] cfg_gpio_negedge_int_sel ;// select negedge interrupt
+wire [31:00] cfg_gpio_data_in ;
+
+
+reg [7:0] port_a_in; // PORT A Data In
+reg [7:0] port_b_in; // PORT B Data In
+reg [7:0] port_c_in; // PORT C Data In
+reg [7:0] port_d_in; // PORT D Data In
+
+wire [7:0] port_a_out; // PORT A Data Out
+wire [7:0] port_b_out; // PORT B Data Out
+wire [7:0] port_c_out; // PORT C Data Out
+wire [7:0] port_d_out; // PORT D Data Out
+wire [31:0] pad_gpio_in; // GPIO data input from PAD
+wire [31:0] pad_gpio_out; // GPIO Data out towards PAD
+wire [31:0] gpio_int_event; // GPIO Interrupt indication
+reg [1:0] ext_intr_in; // External PAD level interrupt
+
+// GPIO to PORT Mapping
+assign pad_gpio_in[7:0] = port_a_in;
+assign pad_gpio_in[15:8] = port_b_in;
+assign pad_gpio_in[23:16] = port_c_in;
+assign pad_gpio_in[31:24] = port_d_in;
+
+assign port_a_out = pad_gpio_out[7:0];
+assign port_b_out = pad_gpio_out[15:8];
+assign port_c_out = pad_gpio_out[23:16];
+assign port_d_out = pad_gpio_out[31:24];
+
+assign pinmux_debug = '0; // Todo: Need to fix
+
+// SSRAM I/F - Temp masked
+//input logic ssram_sck,
+//input logic ssram_ss,
+//input logic [3:0] ssram_oen,
+//input logic [3:0] ssram_do,
+//output logic [3:0] ssram_di,
+
+// pinmux clock skew control
+clk_skew_adjust u_skew_pinmux
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_pinmux ),
+ .clk_out (wbd_clk_pinmux )
+ );
+
+gpio_intr u_gpio_intr (
+ // System Signals
+ // Inputs
+ .mclk (mclk ),
+ .h_reset_n (h_reset_n ),
+
+ // GPIO cfg input pins
+ .gpio_prev_indata (gpio_prev_indata ),
+ .cfg_gpio_data_in (cfg_gpio_data_in ),
+ .cfg_gpio_dir_sel (cfg_gpio_dir_sel ),
+ .cfg_gpio_out_data (cfg_gpio_out_data ),
+ .cfg_gpio_posedge_int_sel(cfg_gpio_posedge_int_sel),
+ .cfg_gpio_negedge_int_sel(cfg_gpio_negedge_int_sel),
+
+
+ // GPIO output pins
+ .pad_gpio_out (pad_gpio_out ),
+ .gpio_int_event (gpio_int_event )
+ );
+
+
+// 1us pulse
+pulse_gen_type2 #(.WD(10)) u_pulse_1us (
+
+ .clk_pulse (pulse1u_mclk),
+ .clk (mclk ),
+ .reset_n (h_reset_n ),
+ .cfg_max_cnt (cfg_pulse_1us)
+
+ );
+
+// 1millisecond pulse
+pulse_gen_type1 u_pulse_1ms (
+
+ .clk_pulse (pulse1m_mclk),
+ .clk (mclk ),
+ .reset_n (h_reset_n ),
+ .trigger (pulse1u_mclk)
+
+ );
+
+// 1 second pulse
+pulse_gen_type2 u_pulse_1s (
+
+ .clk_pulse (pulse1s_mclk),
+ .clk (mclk ),
+ .reset_n (h_reset_n ),
+ .cfg_max_cnt (cfg_pulse_1us)
+
+ );
+
+pinmux_reg u_pinmux_reg(
+ // System Signals
+ // Inputs
+ .mclk (mclk ),
+ .h_reset_n (h_reset_n ),
+
+
+ // Reg read/write Interface Inputs
+ .reg_cs (reg_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ .reg_rdata (reg_rdata ),
+ .reg_ack (reg_ack ),
+
+ .ext_intr_in (ext_intr_in ),
+
+ .fuse_mhartid (fuse_mhartid ),
+ .irq_lines (irq_lines ),
+ .soft_irq (soft_irq ),
+ .user_irq (user_irq ),
+ .usb_intr (usb_intr ),
+ .i2cm_intr (i2cm_intr ),
+
+ .cfg_pulse_1us (cfg_pulse_1us ),
+
+
+ .cfg_pwm0_high (cfg_pwm0_high ),
+ .cfg_pwm0_low (cfg_pwm0_low ),
+ .cfg_pwm1_high (cfg_pwm1_high ),
+ .cfg_pwm1_low (cfg_pwm1_low ),
+ .cfg_pwm2_high (cfg_pwm2_high ),
+ .cfg_pwm2_low (cfg_pwm2_low ),
+ .cfg_pwm3_high (cfg_pwm3_high ),
+ .cfg_pwm3_low (cfg_pwm3_low ),
+ .cfg_pwm4_high (cfg_pwm4_high ),
+ .cfg_pwm4_low (cfg_pwm4_low ),
+ .cfg_pwm5_high (cfg_pwm5_high ),
+ .cfg_pwm5_low (cfg_pwm5_low ),
+
+ // GPIO input pins
+ .gpio_in_data (pad_gpio_in ),
+ .gpio_int_event (gpio_int_event ),
+
+ // GPIO config pins
+ .cfg_gpio_out_data (cfg_gpio_out_data ),
+ .cfg_gpio_dir_sel (cfg_gpio_dir_sel ),
+ .cfg_gpio_out_type (cfg_gpio_out_type ),
+ .cfg_gpio_posedge_int_sel (cfg_gpio_posedge_int_sel),
+ .cfg_gpio_negedge_int_sel (cfg_gpio_negedge_int_sel),
+ .cfg_multi_func_sel (cfg_multi_func_sel ),
+ .cfg_gpio_data_in (cfg_gpio_data_in ),
+
+
+ // Outputs
+ .gpio_prev_indata (gpio_prev_indata ) ,
+
+ // BIST I/F
+ .bist_en (bist_en ),
+ .bist_run (bist_run ),
+ .bist_load (bist_load ),
+
+ .bist_sdi (bist_sdi ),
+ .bist_shift (bist_shift ),
+ .bist_sdo (bist_sdo ),
+
+ .bist_done (bist_done ),
+ .bist_error (bist_error ),
+ .bist_correct (bist_correct ),
+ .bist_error_cnt0 (bist_error_cnt0 ),
+ .bist_error_cnt1 (bist_error_cnt1 ),
+ .bist_error_cnt2 (bist_error_cnt2 ),
+ .bist_error_cnt3 (bist_error_cnt3 )
+
+ );
+
+
+// 6 PWM Waveform Generator
+pwm u_pwm_0 (
+ .waveform (pwm_wfm[0] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse1m_mclk ),
+ .cfg_pwm_enb (cfg_pwm_enb[0] ),
+ .cfg_pwm_high (cfg_pwm0_high ),
+ .cfg_pwm_low (cfg_pwm0_low )
+ );
+
+pwm u_pwm_1 (
+ .waveform (pwm_wfm[1] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse1m_mclk ),
+ .cfg_pwm_enb (cfg_pwm_enb[1] ),
+ .cfg_pwm_high (cfg_pwm1_high ),
+ .cfg_pwm_low (cfg_pwm1_low )
+ );
+
+pwm u_pwm_2 (
+ .waveform (pwm_wfm[2] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse1m_mclk ),
+ .cfg_pwm_enb (cfg_pwm_enb[2] ),
+ .cfg_pwm_high (cfg_pwm2_high ),
+ .cfg_pwm_low (cfg_pwm2_low )
+ );
+
+pwm u_pwm_3 (
+ .waveform (pwm_wfm[3] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse1m_mclk ),
+ .cfg_pwm_enb (cfg_pwm_enb[3] ),
+ .cfg_pwm_high (cfg_pwm3_high ),
+ .cfg_pwm_low (cfg_pwm3_low )
+ );
+pwm u_pwm_4 (
+ .waveform (pwm_wfm[4] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse1m_mclk ),
+ .cfg_pwm_enb (cfg_pwm_enb[4] ),
+ .cfg_pwm_high (cfg_pwm4_high ),
+ .cfg_pwm_low (cfg_pwm4_low )
+ );
+pwm u_pwm_5 (
+ .waveform (pwm_wfm[5] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse1m_mclk ),
+ .cfg_pwm_enb (cfg_pwm_enb[5] ),
+ .cfg_pwm_high (cfg_pwm5_high ),
+ .cfg_pwm_low (cfg_pwm5_low )
+ );
+
+/************************************************
+* Pin Mapping ATMGE CONFIG
+* ATMEGA328 caravel Pin Mapping
+* Pin-1 PC6/RESET* digital_io[0]
+* Pin-2 PD0/RXD digital_io[1]
+* Pin-3 PD1/TXD digital_io[2]
+* Pin-4 PD2/INT0 digital_io[3]
+* Pin-5 PD3/INT1/OC2B(PWM0) digital_io[4]
+* Pin-6 PD4 digital_io[5]
+* Pin-7 VCC -
+* Pin-8 GND -
+* Pin-9 PB6/XTAL1/TOSC1 digital_io[6]
+* Pin-10 PB7/XTAL2/TOSC2 digital_io[7]
+* Pin-11 PD5/OC0B(PWM1)/T1 digital_io[8]
+* Pin-12 PD6/OC0A(PWM2)/AIN0 digital_io[9] /analog_io[2]
+* Pin-13 PD7/A1N1 digital_io[10]/analog_io[3]
+* Pin-14 PB0/CLKO/ICP1 digital_io[11]
+* Pin-15 PB1/OC1A(PWM3) digital_io[12]
+* Pin-16 PB2/SS/OC1B(PWM4) digital_io[13]
+* Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
+* Pin-18 PB4/MISO digital_io[15]
+* Pin-19 PB5/SCK digital_io[16]
+* Pin-20 AVCC -
+* Pin-21 AREF analog_io[10]
+* Pin-22 GND -
+* Pin-23 PC0/ADC0 digital_io[18]/analog_io[11]
+* Pin-24 PC1/ADC1 digital_io[19]/analog_io[12]
+* Pin-25 PC2/ADC2 digital_io[20]/analog_io[13]
+* Pin-26 PC3/ADC3 digital_io[21]/analog_io[14]
+* Pin-27 PC4/ADC4/SDA digital_io[22]/analog_io[15]
+* Pin-28 PC5/ADC5/SCL digital_io[23]/analog_io[16]
+*
+* Additional Pad used for Externam ROM/RAM
+* sflash_sck digital_io[24]
+* sflash_ss[3] digital_io[25]
+* sflash_ss[2] digital_io[26]
+* sflash_ss[1] digital_io[27]
+* sflash_ss[0] digital_io[28]
+* sflash_io0 digital_io[29]
+* sflash_io1 digital_io[30]
+* sflash_io2 digital_io[31]
+* sflash_io3 digital_io[32]
+* reserved digital_io[33]
+* uartm_rxd digital_io[34]
+* uartm_txd digital_io[35]
+* usb_dp digital_io[36]
+* usb_dn digital_io[37]
+****************************************************************
+* Pin-1 RESET is not supported as there is no suppport for fuse config
+**************/
+
+assign cfg_pwm_enb = cfg_multi_func_sel[5:0];
+wire [1:0] cfg_int_enb = cfg_multi_func_sel[7:6];
+wire cfg_uart_enb = cfg_multi_func_sel[8];
+wire cfg_i2cm_enb = cfg_multi_func_sel[9];
+wire cfg_spim_enb = cfg_multi_func_sel[10];
+
+wire [7:0] cfg_port_a_dir_sel = cfg_gpio_dir_sel[7:0];
+wire [7:0] cfg_port_b_dir_sel = cfg_gpio_dir_sel[15:8];
+wire [7:0] cfg_port_c_dir_sel = cfg_gpio_dir_sel[23:16];
+wire [7:0] cfg_port_d_dir_sel = cfg_gpio_dir_sel[31:24];
+
+
+// datain selection
+always_comb begin
+ port_a_in = 'h0;
+ port_b_in = 'h0;
+ port_c_in = 'h0;
+ port_d_in = 'h0;
+ uart_rxd = 'h0;
+ ext_intr_in= 'h0;
+ spim_mosi = 'h0;
+ i2cm_data_i= 'h0;
+ i2cm_clk_i = 'h0;
+
+ //Pin-1 PC6/RESET* digital_io[0]
+ port_c_in[6] = digital_io_in[0];
+
+ //Pin-2 PD0/RXD digital_io[1]
+ port_d_in[0] = digital_io_in[1];
+ if(cfg_uart_enb) uart_rxd = digital_io_in[1];
+
+ //Pin-3 PD1/TXD digital_io[2]
+ port_d_in[1] = digital_io_in[2];
+
+
+ //Pin-4 PD2/INT0 digital_io[3]
+ port_d_in[2] = digital_io_in[3];
+ if(cfg_int_enb[0]) ext_intr_in[0] = digital_io_in[3];
+
+ //Pin-5 PD3/INT1/OC2B(PWM0) digital_io[4]
+ port_d_in[3] = digital_io_in[4];
+ if(cfg_int_enb[1]) ext_intr_in[1] = digital_io_in[4];
+
+ //Pin-6 PD4 digital_io[5]
+ port_d_in[4] = digital_io_in[5];
+
+ //Pin-9 PB6/XTAL1/TOSC1 digital_io[6]
+ port_b_in[6] = digital_io_in[6];
+
+ // Pin-10 PB7/XTAL2/TOSC2 digital_io[7]
+ port_b_in[7] = digital_io_in[7];
+
+ //Pin-11 PD5/OC0B(PWM1)/T1 digital_io[8]
+ port_d_in[5] = digital_io_in[8];
+
+ //Pin-12 PD6/OC0A(PWM2)/AIN0 digital_io[9] /analog_io[2]
+ port_d_in[6] = digital_io_in[9];
+
+ //Pin-13 PD7/A1N1 digital_io[10]/analog_io[3]
+ port_d_in[7] = digital_io_in[10];
+
+ //Pin-14 PB0/CLKO/ICP1 digital_io[11]
+ port_b_in[0] = digital_io_in[11];
+
+ //Pin-15 PB1/OC1A(PWM3) digital_io[12]
+ port_b_in[1] = digital_io_in[12];
+
+ //Pin-16 PB2/SS/OC1B(PWM4) digital_io[13]
+ port_b_in[2] = digital_io_in[13];
+
+ //Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
+ port_b_in[3] = digital_io_in[14];
+ if(cfg_spim_enb) spim_mosi = digital_io_in[14];
+
+ //Pin-18 PB4/MISO digital_io[15]
+ port_b_in[4] = digital_io_in[15];
+
+ //Pin-19 PB5/SCK digital_io[16]
+ port_b_in[5]= digital_io_in[16];
+
+ //Pin-23 PC0/ADC0 digital_io[18]/analog_io[11]
+ port_c_in[0] = digital_io_in[18];
+
+ //Pin-24 PC1/ADC1 digital_io[19]/analog_io[12]
+ port_c_in[1] = digital_io_in[19];
+
+ //Pin-25 PC2/ADC2 digital_io[20]/analog_io[13]
+ port_c_in[2] = digital_io_in[20];
+
+ //Pin-26 PC3/ADC3 digital_io[21]/analog_io[14]
+ port_c_in[3] = digital_io_in[21];
+
+ //Pin-27 PC4/ADC4/SDA digital_io[22]/analog_io[15]
+ port_c_in[4] = digital_io_in[22];
+ if(cfg_i2cm_enb) i2cm_data_i = digital_io_in[22];
+
+ //Pin-28 PC5/ADC5/SCL digital_io[23]/analog_io[16]
+ port_c_in[5] = digital_io_in[23];
+ if(cfg_i2cm_enb) i2cm_clk_i = digital_io_in[23];
+
+ sflash_di[0] = digital_io_in[29];
+ sflash_di[1] = digital_io_in[30];
+ sflash_di[2] = digital_io_in[31];
+ sflash_di[3] = digital_io_in[32];
+
+ // UAR MASTER I/F
+ uartm_rxd = digital_io_in[34];
+
+ usb_dp_i = digital_io_in[36];
+ usb_dn_i = digital_io_in[37];
+end
+
+// dataout selection
+always_comb begin
+ digital_io_out = 'h0;
+ //Pin-1 PC6/RESET* digital_io[0]
+ if(cfg_port_c_dir_sel[6]) digital_io_out[0] = port_c_out[6];
+
+ //Pin-2 PD0/RXD digital_io[1]
+ if(cfg_port_d_dir_sel[0]) digital_io_out[1] = port_d_out[0];
+
+ //Pin-3 PD1/TXD digital_io[2]
+ if (cfg_uart_enb) digital_io_out[2] = uart_txd;
+ else if(cfg_port_d_dir_sel[1]) digital_io_out[2] = port_d_out[1];
+
+
+ //Pin-4 PD2/INT0 digital_io[3]
+ if(cfg_port_d_dir_sel[2]) digital_io_out[3] = port_d_out[2];
+
+ //Pin-5 PD3/INT1/OC2B(PWM0) digital_io[4]
+ if(cfg_pwm_enb[0]) digital_io_out[4] = pwm_wfm[0];
+ if(cfg_port_d_dir_sel[3]) digital_io_out[4] = port_d_out[3];
+
+ //Pin-6 PD4 digital_io[5]
+ if(cfg_port_d_dir_sel[4]) digital_io_out[5] = port_d_out[4];
+
+ //Pin-9 PB6/XTAL1/TOSC1 digital_io[6]
+ if(cfg_port_b_dir_sel[6]) digital_io_out[6] = port_b_out[6];
+
+
+ // Pin-10 PB7/XTAL2/TOSC2 digital_io[7]
+ if(cfg_port_b_dir_sel[7]) digital_io_out[7] = port_b_out[7];
+
+ //Pin-11 PD5/OC0B(PWM1)/T1 digital_io[8]
+ if(cfg_pwm_enb[1]) digital_io_out[8] = pwm_wfm[1];
+ else if(cfg_port_d_dir_sel[5]) digital_io_out[8] = port_d_out[5];
+
+ //Pin-12 PD6/OC0A(PWM2)/AIN0 digital_io[9] /analog_io[2]
+ if(cfg_pwm_enb[2]) digital_io_out[9] = pwm_wfm[2];
+ else if(cfg_port_d_dir_sel[6]) digital_io_out[9] = port_d_out[6];
+
+
+ //Pin-13 PD7/A1N1 digital_io[10]/analog_io[3]
+ if(cfg_port_d_dir_sel[7]) digital_io_out[10] = port_d_out[7];
+
+ //Pin-14 PB0/CLKO/ICP1 digital_io[11]
+ if(cfg_port_b_dir_sel[0]) digital_io_out[11] = port_b_out[0];
+
+ //Pin-15 PB1/OC1A(PWM3) digital_io[12]
+ if(cfg_pwm_enb[3]) digital_io_out[12] = pwm_wfm[3];
+ else if(cfg_port_b_dir_sel[1]) digital_io_out[12] = port_b_out[1];
+
+ //Pin-16 PB2/SS/OC1B(PWM4) digital_io[13]
+ if(cfg_pwm_enb[4]) digital_io_out[13] = pwm_wfm[4];
+ else if(cfg_spim_enb) digital_io_out[13] = spim_ss;
+ else if(cfg_port_b_dir_sel[2]) digital_io_out[13] = port_b_out[2];
+
+ //Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
+ if(cfg_pwm_enb[5]) digital_io_out[14] = pwm_wfm[5];
+ else if(cfg_port_b_dir_sel[3]) digital_io_out[14] = port_b_out[3];
+
+ //Pin-18 PB4/MISO digital_io[15]
+ if(cfg_spim_enb) digital_io_out[15] = spim_miso;
+ else if(cfg_port_b_dir_sel[4]) digital_io_out[15] = port_b_out[4];
+
+ //Pin-19 PB5/SCK digital_io[16]
+ if(cfg_spim_enb) digital_io_out[16] = spim_sck;
+ else if(cfg_port_b_dir_sel[5]) digital_io_out[16] = port_b_out[5];
+
+ //Pin-23 PC0/ADC0 digital_io[18]/analog_io[11]
+ if(cfg_port_c_dir_sel[0]) digital_io_out[18] = port_c_out[0];
+
+ //Pin-24 PC1/ADC1 digital_io[19]/analog_io[12]
+ if(cfg_port_c_dir_sel[1]) digital_io_out[19] = port_c_out[1];
+
+ //Pin-25 PC2/ADC2 digital_io[20]/analog_io[13]
+ if(cfg_port_c_dir_sel[2]) digital_io_out[20] = port_c_out[2];
+
+ //Pin-26 PC3/ADC3 digital_io[21]/analog_io[14]
+ if(cfg_port_c_dir_sel[3]) digital_io_out[21] = port_c_out[3];
+
+ //Pin-27 PC4/ADC4/SDA digital_io[22]/analog_io[15]
+ if(cfg_i2cm_enb) digital_io_out[22] = i2cm_data_o;
+ else if(cfg_port_c_dir_sel[4]) digital_io_out[22] = port_c_out[4];
+
+ //Pin-28 PC5/ADC5/SCL digital_io[23]/analog_io[16]
+ if(cfg_i2cm_enb) digital_io_out[23] = i2cm_clk_o;
+ else if(cfg_port_c_dir_sel[5]) digital_io_out[23] = port_c_out[5];
+
+ // Serial Flash
+ digital_io_out[24] = sflash_sck ;
+ digital_io_out[25] = sflash_ss[3] ;
+ digital_io_out[26] = sflash_ss[2] ;
+ digital_io_out[27] = sflash_ss[1] ;
+ digital_io_out[28] = sflash_ss[0] ;
+ digital_io_out[29] = sflash_do[0] ;
+ digital_io_out[30] = sflash_do[1] ;
+ digital_io_out[31] = sflash_do[2] ;
+ digital_io_out[32] = sflash_do[3] ;
+
+ // Reserved
+ digital_io_out[33] = 1'b0;
+
+ // UART MASTER I/f
+ digital_io_out[34] = 1'b0 ; // RXD
+ digital_io_out[35] = uartm_txd ; // TXD
+
+ // USB 1.1
+ digital_io_out[36] = usb_dp_o ;
+ digital_io_out[37] = usb_dn_o ;
+end
+
+// dataoen selection
+always_comb begin
+ digital_io_oen = 38'h3F_FFFF_FFFF;
+ //Pin-1 PC6/RESET* digital_io[0]
+ if(cfg_port_c_dir_sel[6]) digital_io_oen[0] = 1'b0;
+
+ //Pin-2 PD0/RXD digital_io[1]
+ if (cfg_uart_enb) digital_io_oen[1] = 1'b1;
+ else if(cfg_port_d_dir_sel[0]) digital_io_oen[1] = 1'b0;
+
+ //Pin-3 PD1/TXD digital_io[2]
+ if (cfg_uart_enb) digital_io_oen[2] = 1'b0;
+ else if(cfg_port_d_dir_sel[1]) digital_io_oen[2] = 1'b0;
+
+ //Pin-4 PD2/INT0 digital_io[3]
+ if(cfg_int_enb[0]) digital_io_oen[3] = 1'b1;
+ else if(cfg_port_d_dir_sel[2]) digital_io_oen[3] = 1'b0;
+
+ //Pin-5 PD3/INT1/OC2B(PWM0) digital_io[4]
+ if(cfg_pwm_enb[0]) digital_io_oen[4] = 1'b0;
+ else if(cfg_int_enb[1]) digital_io_oen[4] = 1'b1;
+ else if(cfg_port_d_dir_sel[3]) digital_io_oen[4] = 1'b0;
+
+ //Pin-6 PD4 digital_io[5]
+ if(cfg_port_d_dir_sel[4]) digital_io_oen[5] = 1'b0;
+
+ //Pin-9 PB6/XTAL1/TOSC1 digital_io[6]
+ if(cfg_port_b_dir_sel[6]) digital_io_oen[6] = 1'b0;
+
+ // Pin-10 PB7/XTAL2/TOSC2 digital_io[7]
+ if(cfg_port_b_dir_sel[7]) digital_io_oen[7] = 1'b0;
+
+ //Pin-11 PD5/OC0B(PWM1)/T1 digital_io[8]
+ if(cfg_pwm_enb[1]) digital_io_oen[8] = 1'b0;
+ else if(cfg_port_d_dir_sel[5]) digital_io_oen[8] = 1'b0;
+
+ //Pin-12 PD6/OC0A(PWM2)/AIN0 digital_io[9] /analog_io[2]
+ if(cfg_pwm_enb[2]) digital_io_oen[9] = 1'b0;
+ else if(cfg_port_d_dir_sel[6]) digital_io_oen[9] = 1'b0;
+
+ //Pin-13 PD7/A1N1 digital_io[10]/analog_io[3]
+ if(cfg_port_d_dir_sel[7]) digital_io_oen[10] = 1'b0;
+
+ //Pin-14 PB0/CLKO/ICP1 digital_io[11]
+ if(cfg_port_b_dir_sel[0]) digital_io_oen[11] = 1'b0;
+
+ //Pin-15 PB1/OC1A(PWM3) digital_io[12]
+ if(cfg_pwm_enb[3]) digital_io_oen[12] = 1'b0;
+ else if(cfg_port_b_dir_sel[1]) digital_io_oen[12] = 1'b0;
+
+ //Pin-16 PB2/SS/OC1B(PWM4) digital_io[13]
+ if(cfg_pwm_enb[4]) digital_io_oen[13] = 1'b0;
+ else if(cfg_spim_enb) digital_io_oen[13] = 1'b0;
+ else if(cfg_port_b_dir_sel[2]) digital_io_oen[13] = 1'b0;
+
+ //Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
+ if(cfg_spim_enb) digital_io_oen[14] = 1'b1;
+ else if(cfg_pwm_enb[5]) digital_io_oen[14] = 1'b0;
+ else if(cfg_port_b_dir_sel[3]) digital_io_oen[14] = 1'b0;
+
+ //Pin-18 PB4/MISO digital_io[15]
+ if(cfg_spim_enb) digital_io_oen[15] = 1'b0;
+ else if(cfg_port_b_dir_sel[4]) digital_io_oen[15] = 1'b0;
+
+ //Pin-19 PB5/SCK digital_io[16]
+ if(cfg_spim_enb) digital_io_oen[16] = 1'b0;
+ else if(cfg_port_b_dir_sel[5]) digital_io_oen[16] = 1'b0;
+
+ //Pin-23 PC0/ADC0 digital_io[18]/analog_io[11]
+ if(cfg_port_c_dir_sel[0]) digital_io_oen[18] = 1'b0;
+
+ //Pin-24 PC1/ADC1 digital_io[19]/analog_io[12]
+ if(cfg_port_c_dir_sel[1]) digital_io_oen[19] = 1'b0;
+
+ //Pin-25 PC2/ADC2 digital_io[20]/analog_io[13]
+ if(cfg_port_c_dir_sel[2]) digital_io_oen[20] = 1'b0;
+
+ //Pin-26 PC3/ADC3 digital_io[21]/analog_io[14]
+ if(cfg_port_c_dir_sel[3]) digital_io_oen[21] = 1'b0;
+
+ //Pin-27 PC4/ADC4/SDA digital_io[22]/analog_io[15]
+ if(cfg_i2cm_enb) digital_io_oen[22] = i2cm_data_oen;
+ else if(cfg_port_c_dir_sel[4]) digital_io_oen[22] = 1'b0;
+
+ //Pin-28 PC5/ADC5/SCL digital_io[23]/analog_io[16]
+ if(cfg_i2cm_enb) digital_io_oen[23] = i2cm_clk_oen;
+ else if(cfg_port_c_dir_sel[5]) digital_io_oen[23] = 1'b0;
+
+ // Serial Flash
+ digital_io_oen[24] = 1'b0 ;
+ digital_io_oen[25] = 1'b0 ;
+ digital_io_oen[26] = 1'b0 ;
+ digital_io_oen[27] = 1'b0 ;
+ digital_io_oen[28] = 1'b0 ;
+ digital_io_oen[29] = sflash_oen[0];
+ digital_io_oen[30] = sflash_oen[1];
+ digital_io_oen[31] = sflash_oen[2];
+ digital_io_oen[32] = sflash_oen[3];
+
+ // Reserved
+ digital_io_oen[33] = 1'b0 ;
+ // UART MASTER
+ digital_io_oen[34] = 1'b1; // RXD
+ digital_io_oen[35] = 1'b0; // TXD
+
+ // USB 1.1
+ digital_io_oen[36] = usb_oen;
+ digital_io_oen[37] = usb_oen;
+end
+
+
+endmodule
+
+
diff --git a/verilog/rtl/pinmux/src/pinmux_reg.sv b/verilog/rtl/pinmux/src/pinmux_reg.sv
new file mode 100644
index 0000000..211bd40
--- /dev/null
+++ b/verilog/rtl/pinmux/src/pinmux_reg.sv
@@ -0,0 +1,913 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Pinmux Register ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// Hold all the Global and PinMux Register ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 16th Feb 2021, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+//
+module pinmux_reg (
+ // System Signals
+ // Inputs
+ input logic mclk,
+ input logic h_reset_n,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [7:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ input logic [1:0] ext_intr_in,
+
+ // Risc configuration
+ output logic [31:0] fuse_mhartid,
+ output logic [15:0] irq_lines,
+ output logic soft_irq,
+ output logic [2:0] user_irq,
+ input logic usb_intr,
+ input logic i2cm_intr,
+
+ output logic [9:0] cfg_pulse_1us,
+
+ //---------------------------------------------------
+ // 6 PWM Configuration
+ //---------------------------------------------------
+
+ output logic [15:0] cfg_pwm0_high ,
+ output logic [15:0] cfg_pwm0_low ,
+ output logic [15:0] cfg_pwm1_high ,
+ output logic [15:0] cfg_pwm1_low ,
+ output logic [15:0] cfg_pwm2_high ,
+ output logic [15:0] cfg_pwm2_low ,
+ output logic [15:0] cfg_pwm3_high ,
+ output logic [15:0] cfg_pwm3_low ,
+ output logic [15:0] cfg_pwm4_high ,
+ output logic [15:0] cfg_pwm4_low ,
+ output logic [15:0] cfg_pwm5_high ,
+ output logic [15:0] cfg_pwm5_low ,
+
+ // GPIO input pins
+ input logic [31:0] gpio_in_data ,// GPIO I/P pins
+ input logic [31:0] gpio_int_event ,// from gpio control blk
+
+
+
+ // GPIO config pins
+ output logic [31:0] cfg_gpio_out_data ,// to the GPIO control block
+ output logic [31:0] cfg_gpio_data_in ,// GPIO I/P pins data captured into this
+ output logic [31:0] cfg_gpio_dir_sel ,// decides on GPIO pin is I/P or O/P at pad level
+ output logic [31:0] cfg_gpio_out_type ,// O/P is static , '1' : waveform
+ output logic [31:0] cfg_gpio_posedge_int_sel ,// select posedge interrupt
+ output logic [31:0] cfg_gpio_negedge_int_sel ,// select negedge interrupt
+ output logic [31:0] cfg_multi_func_sel ,// multifunction pins
+
+ // Outputs
+ output logic [31:0] gpio_prev_indata, // prv data from GPIO I/P pins
+
+ // BIST I/F
+ output logic bist_en,
+ output logic bist_run,
+ output logic bist_load,
+
+ output logic bist_sdi,
+ output logic bist_shift,
+ input logic bist_sdo,
+
+ input logic bist_done,
+ input logic [3:0] bist_error,
+ input logic [3:0] bist_correct,
+ input logic [3:0] bist_error_cnt0,
+ input logic [3:0] bist_error_cnt1,
+ input logic [3:0] bist_error_cnt2,
+ input logic [3:0] bist_error_cnt3
+
+ );
+
+
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+logic sw_rd_en ;
+logic sw_wr_en;
+logic [4:0] sw_addr; // addressing 16 registers
+logic [31:0] sw_reg_wdata;
+logic [3:0] wr_be ;
+
+logic [31:0] reg_out;
+logic [31:0] reg_0; // Chip ID
+logic [31:0] reg_1; // Risc Fuse Id
+logic [31:0] reg_2; // GPIO Read Data
+logic [31:0] reg_3; // GPIO Output Data
+logic [31:0] reg_4; // GPIO Dir Sel
+logic [31:0] reg_5; // GPIO Type
+logic [31:0] reg_6; // Interrupt
+logic [31:0] reg_7; //
+logic [31:0] reg_8; //
+logic [31:0] reg_9; // GPIO Interrupt Status
+logic [31:0] reg_10; // GPIO Interrupt Status
+logic [31:0] reg_11; // GPIO Interrupt Mask
+logic [31:0] reg_12; // GPIO Posedge Interrupt Select
+logic [31:0] reg_13; // GPIO Negedge Interrupt Select
+logic [31:0] reg_14; // Software-Reg_14
+logic [31:0] reg_15; // Software-Reg_15
+logic [31:0] reg_16; // PWN-0 Config
+logic [31:0] reg_17; // PWN-1 Config
+logic [31:0] reg_18; // PWN-2 Config
+logic [31:0] reg_19; // PWN-3 Config
+logic [31:0] reg_20; // PWN-4 Config
+logic [31:0] reg_21; // PWN-5 Config
+logic [31:0] reg_22; // Software-Reg1
+logic [31:0] reg_23; // Software-Reg2
+logic [31:0] reg_24; // Software-Reg3
+logic [31:0] reg_25; // Software-Reg4
+logic [31:0] reg_26; // Software-Reg5
+logic [31:0] reg_27; // Software-Reg6
+
+
+logic cs_int;
+logic gpio_intr;
+
+
+assign sw_addr = reg_addr [6:2];
+assign sw_rd_en = reg_cs & !reg_wr;
+assign sw_wr_en = reg_cs & reg_wr;
+assign wr_be = reg_be;
+assign sw_reg_wdata = reg_wdata;
+
+
+//-----------------------------------
+// Edge detection for Logic Bist
+// ----------------------------------
+
+logic wb_req;
+logic wb_req_d;
+logic wb_req_pedge;
+
+always_ff @(negedge h_reset_n or posedge mclk) begin
+ if ( h_reset_n == 1'b0 ) begin
+ wb_req <= '0;
+ wb_req_d <= '0;
+ end else begin
+ wb_req <= reg_cs && (reg_ack == 0) ;
+ wb_req_d <= wb_req;
+ end
+end
+
+// Detect pos edge of request
+assign wb_req_pedge = (wb_req_d ==0) && (wb_req==1'b1);
+
+
+//-----------------------------------------------------------------
+// Reg 4/5 are BIST Serial I/F register and it takes minimum 32
+// cycle to respond ACK back
+// ----------------------------------------------------------------
+wire ser_acc = sw_wr_en_30 | sw_rd_en_31;
+wire non_ser_acc = reg_cs ? !ser_acc : 1'b0;
+wire serial_ack;
+
+always @ (posedge mclk or negedge h_reset_n)
+begin : preg_out_Seq
+ if (h_reset_n == 1'b0) begin
+ reg_rdata <= 'h0;
+ reg_ack <= 1'b0;
+ end else if (ser_acc && serial_ack) begin
+ reg_rdata <= serail_dout ;
+ reg_ack <= 1'b1;
+ end else if (non_ser_acc && !reg_ack) begin
+ reg_rdata <= reg_out ;
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 5'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 5'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 5'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 5'h3);
+wire sw_wr_en_4 = sw_wr_en & (sw_addr == 5'h4);
+wire sw_wr_en_5 = sw_wr_en & (sw_addr == 5'h5);
+wire sw_wr_en_6 = sw_wr_en & (sw_addr == 5'h6);
+wire sw_wr_en_7 = sw_wr_en & (sw_addr == 5'h7);
+wire sw_wr_en_8 = sw_wr_en & (sw_addr == 5'h8);
+wire sw_wr_en_9 = sw_wr_en & (sw_addr == 5'h9);
+wire sw_wr_en_10 = sw_wr_en & (sw_addr == 5'hA);
+wire sw_wr_en_11 = sw_wr_en & (sw_addr == 5'hB);
+wire sw_wr_en_12 = sw_wr_en & (sw_addr == 5'hC);
+wire sw_wr_en_13 = sw_wr_en & (sw_addr == 5'hD);
+wire sw_wr_en_14 = sw_wr_en & (sw_addr == 5'hE);
+wire sw_wr_en_15 = sw_wr_en & (sw_addr == 5'hF);
+wire sw_wr_en_16 = sw_wr_en & (sw_addr == 5'h10);
+wire sw_wr_en_17 = sw_wr_en & (sw_addr == 5'h11);
+wire sw_wr_en_18 = sw_wr_en & (sw_addr == 5'h12);
+wire sw_wr_en_19 = sw_wr_en & (sw_addr == 5'h13);
+wire sw_wr_en_20 = sw_wr_en & (sw_addr == 5'h14);
+wire sw_wr_en_21 = sw_wr_en & (sw_addr == 5'h15);
+
+wire sw_wr_en_22 = sw_wr_en & (sw_addr == 5'h16);
+wire sw_wr_en_23 = sw_wr_en & (sw_addr == 5'h17);
+wire sw_wr_en_24 = sw_wr_en & (sw_addr == 5'h18);
+wire sw_wr_en_25 = sw_wr_en & (sw_addr == 5'h19);
+wire sw_wr_en_26 = sw_wr_en & (sw_addr == 5'h1A);
+wire sw_wr_en_27 = sw_wr_en & (sw_addr == 5'h1B);
+wire sw_wr_en_28 = sw_wr_en & (sw_addr == 5'h1C);
+wire sw_wr_en_29 = sw_wr_en & (sw_addr == 5'h1D);
+wire sw_wr_en_30 = sw_wr_en & (sw_addr == 5'h1E);
+wire sw_wr_en_31 = sw_wr_en & (sw_addr == 5'h1F);
+
+wire sw_rd_en_28 = sw_rd_en & (sw_addr == 5'h1C);
+wire sw_rd_en_29 = sw_rd_en & (sw_addr == 5'h1D);
+wire sw_rd_en_30 = sw_rd_en & (sw_addr == 5'h1E);
+wire sw_rd_en_31 = sw_rd_en & (sw_addr == 5'h1F);
+
+
+//-----------------------------------------------------------------------
+// Individual register assignments
+//-----------------------------------------------------------------------
+
+// Chip ID
+wire [15:0] manu_id = 16'h8949; // Asci value of YI
+wire [7:0] chip_id = 8'h02;
+wire [7:0] chip_rev = 8'h01;
+
+assign reg_0 = {manu_id,chip_id,chip_rev};
+
+
+//-----------------------------------------------------------------------
+// reg-1, reset value = 32'hA55A_A55A
+// -----------------------------------------------------------------
+
+gen_32b_reg #(32'hA55A_A55A) u_reg_1 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_1 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_1 )
+ );
+
+assign fuse_mhartid = reg_1;
+
+//-----------------------------------------------------------------------
+// Logic for gpio_data_in
+//-----------------------------------------------------------------------
+logic [31:0] gpio_in_data_s;
+logic [31:0] gpio_in_data_ss;
+// Double Sync the gpio pin data for edge detection
+always @ (posedge mclk or negedge h_reset_n)
+begin
+ if (h_reset_n == 1'b0) begin
+ reg_2 <= 'h0 ;
+ gpio_in_data_s <= 32'd0;
+ gpio_in_data_ss <= 32'd0;
+ end
+ else begin
+ gpio_in_data_s <= gpio_in_data;
+ gpio_in_data_ss <= gpio_in_data_s;
+ reg_2 <= gpio_in_data_ss;
+ end
+end
+
+
+assign cfg_gpio_data_in = reg_2[31:0]; // to be used for edge interrupt detect
+assign gpio_prev_indata = gpio_in_data_ss;
+
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_out_data
+//-----------------------------------------------------------------------
+assign cfg_gpio_out_data = reg_3[31:0]; // data to the GPIO control blk
+
+gen_32b_reg #(32'h0) u_reg_3 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_3 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_3 )
+ );
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_dir_sel
+//-----------------------------------------------------------------------
+assign cfg_gpio_dir_sel = reg_4[31:0]; // data to the GPIO O/P pins
+
+gen_32b_reg #(32'h0) u_reg_4 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_4 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_4 )
+ );
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_out_type
+//-----------------------------------------------------------------------
+assign cfg_gpio_out_type = reg_5[31:0]; // to be used for read
+
+gen_32b_reg #(32'h0) u_reg_5 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_5 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_5 )
+ );
+
+
+//-----------------------------------------------------------------------
+// reg-6
+//-----------------------------------------------------------------
+assign irq_lines = reg_6[15:0];
+assign soft_irq = reg_6[16];
+assign user_irq = reg_6[19:17];
+
+
+generic_register #(8,0 ) u_reg6_be0 (
+ .we ({8{sw_wr_en_6 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[7:0] )
+ );
+
+generic_register #(3,0 ) u_reg6_be1_1 (
+ .we ({3{sw_wr_en_6 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[10:8] ),
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[10:8] )
+ );
+
+
+assign reg_6[15:11] = {gpio_intr, ext_intr_in[1:0], usb_intr, i2cm_intr};
+
+
+generic_register #(4,0 ) u_reg6_be2 (
+ .we ({4{sw_wr_en_6 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[19:16]),
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_6[19:16] )
+ );
+
+assign reg_6[31:20] = '0;
+
+// Register-7
+gen_32b_reg #(32'h0) u_reg_7 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_7 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_7 )
+ );
+
+assign cfg_pulse_1us = reg_7[9:0];
+
+//-----------------------------------------------------------------------
+// Logic for cfg_int_status
+// Always update int_status, even if no register write is occuring.
+// Interrupt posting is higher priority than int clear by host
+//-----------------------------------------------------------------------
+wire [31:0] cfg_gpio_int_status = reg_9[31:0]; // to be used for read
+
+//--------------------------------------------------------
+// Interrupt Status Generation
+// Note: Reg_9 --> Interrupt Status Register, Writting '1' will clear the
+// corresponding interrupt status bit. Writting '0' has no
+// effect
+// Reg_10 --> Writting one to this register will set the interrupt in
+// interrupt status register (reg_9), Writting '0' does not has any
+// effect.
+/// Always update int_status, even if no register write is occuring.
+// Interrupt posting is higher priority than int clear by host
+//--------------------------------------------------------
+wire [31:0] gpio_int_status = reg_9;
+always @(posedge mclk or negedge h_reset_n)
+begin
+ if(~h_reset_n)
+ begin
+ reg_9[31:0] <= 32'h0;
+ end
+ else
+ begin
+ if(sw_wr_en_9 && wr_be[0])
+ begin
+ reg_9[7:0] <= ((~sw_reg_wdata[7:0] & gpio_int_status[7:0]) | gpio_int_event[7:0]);
+ end
+ else if(sw_wr_en_10 && wr_be[0])
+ begin
+ reg_9[7:0] <= ((sw_reg_wdata[7:0] | gpio_int_status[7:0]) | gpio_int_event[7:0]);
+ end
+ else
+ begin
+ reg_9[7:0] <= (gpio_int_status[7:0] | gpio_int_event[7:0]);
+ end
+
+ if(sw_wr_en_9 && wr_be[1])
+ begin
+ reg_9[15:8] <= ((~sw_reg_wdata[15:8] & gpio_int_status[15:8]) | gpio_int_event[15:8]);
+ end
+ else if(sw_wr_en_10 && wr_be[1])
+ begin
+ reg_9[15:8] <= ((sw_reg_wdata[15:8] | gpio_int_status[15:8]) | gpio_int_event[15:8]);
+ end
+ else
+ begin
+ reg_9[15:8] <= (gpio_int_status[15:8] | gpio_int_event[15:8]);
+ end
+
+ if(sw_wr_en_9 && wr_be[2])
+ begin
+ reg_9[23:16] <= ((~sw_reg_wdata[23:16] & gpio_int_status[23:16]) | gpio_int_event[23:16]);
+ end
+ else if(sw_wr_en_10 && wr_be[2])
+ begin
+ reg_9[23:16] <= ((sw_reg_wdata[23:16] | gpio_int_status[23:16]) | gpio_int_event[23:16]);
+ end
+ else
+ begin
+ reg_9[23:16] <= (gpio_int_status[23:16] | gpio_int_event[23:16]);
+ end
+
+ if(sw_wr_en_9 && wr_be[3])
+ begin
+ reg_9[31:24] <= ((~sw_reg_wdata[31:24] & gpio_int_status[31:24]) | gpio_int_event[31:24]);
+ end
+ else if(sw_wr_en_10 && wr_be[3])
+ begin
+ reg_9[31:24] <= ((sw_reg_wdata[31:24] | gpio_int_status[31:24]) | gpio_int_event[31:24]);
+ end
+ else
+ begin
+ reg_9[31:24] <= (gpio_int_status[31:24] | gpio_int_event[31:24]);
+ end
+ end
+end
+//-------------------------------------------------
+// Returns same value as interrupt status register
+//------------------------------------------------
+
+assign reg_10 = reg_9;
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_int_mask : GPIO interrupt mask
+//-----------------------------------------------------------------------
+wire [31:0] cfg_gpio_int_mask = reg_11[31:0]; // to be used for read
+
+assign gpio_intr = ( | (reg_9 & reg_11) ); // interrupt pin to the RISC
+
+
+// Register-11
+gen_32b_reg #(32'h0) u_reg_11 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_11 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_11 )
+ );
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_posedge_int_sel : Enable posedge GPIO interrupt
+//-----------------------------------------------------------------------
+assign cfg_gpio_posedge_int_sel = reg_12[31:0]; // to be used for read
+gen_32b_reg #(32'h0) u_reg_12 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_12 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_12 )
+ );
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_negedge_int_sel : Enable negedge GPIO interrupt
+//-----------------------------------------------------------------------
+assign cfg_gpio_negedge_int_sel = reg_13[31:0]; // to be used for read
+gen_32b_reg #(32'h0) u_reg_13 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_13 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_13 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for cfg_multi_func_sel :Enable GPIO to act as multi function pins
+//-----------------------------------------------------------------------
+assign cfg_multi_func_sel = reg_14[31:0]; // to be used for read
+
+
+gen_32b_reg #(32'h0) u_reg_14 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_14 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_14 )
+ );
+
+// Reg-15
+gen_32b_reg #(32'h0) u_reg_15 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_15 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_15 )
+ );
+//-----------------------------------------------------------------------
+// Logic for PWM-0 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm0_low = reg_16[15:0]; // low period of w/f
+assign cfg_pwm0_high = reg_16[31:16]; // high period of w/f
+
+gen_32b_reg #(32'h0) u_reg_16 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_16 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_16 )
+ );
+
+
+//-----------------------------------------------------------------------
+// Logic for PWM-1 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm1_low = reg_17[15:0]; // low period of w/f
+assign cfg_pwm1_high = reg_17[31:16]; // high period of w/f
+gen_32b_reg #(32'h0) u_reg_17 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_17 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_17 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for PWM-2 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm2_low = reg_18[15:0]; // low period of w/f
+assign cfg_pwm2_high = reg_18[31:16]; // high period of w/f
+gen_32b_reg #(32'h0) u_reg_18 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_18 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_18 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for PWM-3 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm3_low = reg_19[15:0]; // low period of w/f
+assign cfg_pwm3_high = reg_19[31:16]; // high period of w/f
+gen_32b_reg #(32'h0) u_reg_19 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_19 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_19 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for PWM-4 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm4_low = reg_20[15:0]; // low period of w/f
+assign cfg_pwm4_high = reg_20[31:16]; // high period of w/f
+
+gen_32b_reg #(32'h0) u_reg_20 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_20 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_20 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for PWM-5 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm5_low = reg_21[15:0]; // low period of w/f
+assign cfg_pwm5_high = reg_21[31:16]; // high period of w/f
+
+gen_32b_reg #(32'h0) u_reg_21 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_21 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_21 )
+ );
+
+
+//-----------------------------------------
+// Software Reg-1 : ASCI Representation of RISC = 32'h8273_8343
+// ----------------------------------------
+gen_32b_reg #(32'h8273_8343) u_reg_22 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_22 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_22 )
+ );
+
+//-----------------------------------------
+// Software Reg-2, Release date: <DAY><MONTH><YEAR>
+// ----------------------------------------
+gen_32b_reg #(32'h1402_2022) u_reg_23 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_23 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_23 )
+ );
+
+//-----------------------------------------
+// Software Reg-3: Poject Revison 3.3 = 0003400
+// ----------------------------------------
+gen_32b_reg #(32'h0003_4000) u_reg_24 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_24 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_24 )
+ );
+
+//-----------------------------------------
+// Software Reg-4
+// ----------------------------------------
+gen_32b_reg #(32'h0) u_reg_25 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_25 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_25 )
+ );
+
+//-----------------------------------------
+// Software Reg-5
+// ----------------------------------------
+gen_32b_reg #(32'h0) u_reg_26 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_26 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_26 )
+ );
+
+//-----------------------------------------
+// Software Reg-6
+// ----------------------------------------
+gen_32b_reg #(32'h0) u_reg_27 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_27 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_27 )
+ );
+
+
+//-----------------------------------------------------------------------
+// reg-28
+// -----------------------------------------------------------------
+logic [31:0] cfg_bist_ctrl_1;
+
+gen_32b_reg #(32'h0) u_reg_28 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_28 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (cfg_bist_ctrl_1[31:0] )
+ );
+
+
+
+assign bist_en = cfg_bist_ctrl_1[0];
+assign bist_run = cfg_bist_ctrl_1[1];
+assign bist_load = cfg_bist_ctrl_1[2];
+
+
+//-----------------------------------------------------------------------
+// reg-29
+//-----------------------------------------------------------------
+logic [31:0] cfg_bist_status_1;
+
+assign cfg_bist_status_1 = { bist_error_cnt3, 1'b0, bist_correct[3], bist_error[3], bist_done,
+ bist_error_cnt2, 1'b0, bist_correct[2], bist_error[2], bist_done,
+ bist_error_cnt1, 1'b0, bist_correct[1], bist_error[1], bist_done,
+ bist_error_cnt0, 1'b0, bist_correct[0], bist_error[0], bist_done
+ };
+
+//-----------------------------------------------------------------------
+// reg-30 => Write to Serail I/F
+// reg-31 => READ from Serail I/F
+//-----------------------------------------------------------------
+logic bist_sdi_int;
+logic bist_shift_int;
+logic bist_sdo_int;
+logic [31:0] serail_dout;
+
+assign bist_sdo_int = bist_sdo;
+assign bist_shift = bist_shift_int;
+assign bist_sdi = bist_sdi_int ;
+
+ser_inf_32b u_ser_intf
+ (
+
+ // Master Port
+ .rst_n (h_reset_n), // Regular Reset signal
+ .clk (mclk), // System clock
+ .reg_wr (sw_wr_en_30 & wb_req_pedge), // Write Request
+ .reg_rd (sw_rd_en_31 & wb_req_pedge), // Read Request
+ .reg_wdata (sw_reg_wdata) , // data output
+ .reg_rdata (serail_dout), // data input
+ .reg_ack (serial_ack), // acknowlegement
+
+ // Slave Port
+ .sdi (bist_sdi_int), // Serial SDI
+ .shift (bist_shift_int), // Shift Signal
+ .sdo (bist_sdo_int) // Serial SDO
+
+ );
+
+
+
+
+//-----------------------------------------------------------------------
+// Register Read Path Multiplexer instantiation
+//-----------------------------------------------------------------------
+
+always_comb
+begin
+ reg_out [31:0] = 32'h0;
+
+ case (sw_addr [4:0])
+ 5'b00000 : reg_out [31:0] = reg_0 [31:0];
+ 5'b00001 : reg_out [31:0] = reg_1 [31:0];
+ 5'b00010 : reg_out [31:0] = reg_2 [31:0];
+ 5'b00011 : reg_out [31:0] = reg_3 [31:0];
+ 5'b00100 : reg_out [31:0] = reg_4 [31:0];
+ 5'b00101 : reg_out [31:0] = reg_5 [31:0];
+ 5'b00110 : reg_out [31:0] = reg_6 [31:0];
+ 5'b00111 : reg_out [31:0] = reg_7 [31:0];
+ 5'b01000 : reg_out [31:0] = reg_8 [31:0];
+ 5'b01001 : reg_out [31:0] = reg_9 [31:0];
+ 5'b01010 : reg_out [31:0] = reg_10 [31:0];
+ 5'b01011 : reg_out [31:0] = reg_11 [31:0];
+ 5'b01100 : reg_out [31:0] = reg_12 [31:0];
+ 5'b01101 : reg_out [31:0] = reg_13 [31:0];
+ 5'b01110 : reg_out [31:0] = reg_14 [31:0];
+ 5'b01111 : reg_out [31:0] = reg_15 [31:0];
+ 5'b10000 : reg_out [31:0] = reg_16 [31:0];
+ 5'b10001 : reg_out [31:0] = reg_17 [31:0];
+ 5'b10010 : reg_out [31:0] = reg_18 [31:0];
+ 5'b10011 : reg_out [31:0] = reg_19 [31:0];
+ 5'b10100 : reg_out [31:0] = reg_20 [31:0];
+ 5'b10101 : reg_out [31:0] = reg_21 [31:0];
+ 5'b10110 : reg_out [31:0] = reg_22 [31:0];
+ 5'b10111 : reg_out [31:0] = reg_23 [31:0];
+ 5'b11000 : reg_out [31:0] = reg_24 [31:0];
+ 5'b11001 : reg_out [31:0] = reg_25 [31:0];
+ 5'b11010 : reg_out [31:0] = reg_26 [31:0];
+ 5'b11011 : reg_out [31:0] = reg_27 [31:0];
+ 5'b11100 : reg_out [31:0] = cfg_bist_ctrl_1 [31:0];
+ 5'b11101 : reg_out [31:0] = cfg_bist_status_1 [31:0];
+ 5'b11110 : reg_out [31:0] = serail_dout [31:0]; // Previous Shift Data
+ 5'b11111 : reg_out [31:0] = serail_dout [31:0]; // Latest Shift Data
+ default : reg_out [31:0] = 32'h0;
+ endcase
+end
+
+
+endmodule
diff --git a/verilog/rtl/pinmux/src/pwm.sv b/verilog/rtl/pinmux/src/pwm.sv
new file mode 100644
index 0000000..7a30772
--- /dev/null
+++ b/verilog/rtl/pinmux/src/pwm.sv
@@ -0,0 +1,44 @@
+
+//-------------------------------------------------------------------
+// PWM waveform period: 1000/((cfg_pwm_high+1) + (cfg_pwm_low+1))
+// For 1 Second with Duty cycle 50 = 1000/((499+1) + (499+1))
+// For 1 Second with 1ms On and 999ms Off = 1000/((0+1) + (998+1))
+// Timing Run's with 1 Milisecond pulse
+//-------------------------------------------------------------------
+
+module pwm(
+ output logic waveform,
+
+ input logic h_reset_n,
+ input logic mclk,
+ input logic pulse1m_mclk,
+ input logic cfg_pwm_enb,
+ input logic [15:0] cfg_pwm_high,
+ input logic [15:0] cfg_pwm_low
+);
+
+logic [15:0] pwm_cnt ; // PWM on/off counter
+
+
+always @(posedge mclk or negedge h_reset_n)
+begin
+ if ( ~h_reset_n )
+ begin
+ pwm_cnt <= 16'h0;
+ waveform <= 1'b0;
+ end
+ else if ( pulse1m_mclk && cfg_pwm_enb)
+ begin
+ if ( pwm_cnt == 16'h0 && waveform == 1'b0) begin
+ pwm_cnt <= cfg_pwm_high;
+ waveform <= ~waveform;
+ end else if ( pwm_cnt == 16'h0 && waveform == 1'b1) begin
+ pwm_cnt <= cfg_pwm_low;
+ waveform <= ~waveform;
+ end else begin
+ pwm_cnt <= pwm_cnt - 1;
+ end
+ end
+end
+
+endmodule
diff --git a/verilog/rtl/sar_adc/ACMP.sv b/verilog/rtl/sar_adc/ACMP.sv
new file mode 100644
index 0000000..7f58f42
--- /dev/null
+++ b/verilog/rtl/sar_adc/ACMP.sv
@@ -0,0 +1,103 @@
+module ACMP(
+`ifdef USE_POWER_PINS
+ input wire vccd2,
+ input wire vssd2,
+`endif
+ input wire clk,
+ input wire INP,
+ input wire INN,
+ input wire VDD,
+ input wire VSS,
+ output wire Q
+);
+
+`ifdef ACMP_FUNCTIONAL
+
+ assign Q = INP > INN ;
+`else
+
+ wire clkb;
+ wire net1,
+ net2,
+ net3,
+ net4,
+ net5,
+ net6,
+ net7;
+
+ sky130_fd_sc_hd__inv_1 x15 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A(clk), .Y(clkb));
+ sky130_fd_sc_hd__a221oi_1 x7 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A1(INP), .A2(INP), .B1(clkb), .B2(VDD), .C1(net2), .Y(net1));
+ sky130_fd_sc_hd__a221oi_1 x8 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A1(INN), .A2(INN), .B1(clkb), .B2(VDD), .C1(net1), .Y(net2));
+ sky130_fd_sc_hd__inv_1 x2 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A(net3), .Y(net6));
+ sky130_fd_sc_hd__inv_1 x3 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A(net4), .Y(net5));
+ sky130_fd_sc_hd__o221ai_1 x6 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A1(INP), .A2(INP), .B1(clk), .B2(VSS), .C1(net4), .Y(net3));
+ sky130_fd_sc_hd__o221ai_1 x9 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A1(INN), .A2(INN), .B1(clk), .B2(VSS), .C1(net3), .Y(net4));
+ sky130_fd_sc_hd__nor3_1 x10 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A(net5), .B(net1), .C(net7), .Y(Q));
+ sky130_fd_sc_hd__nor3_1 x11 (
+ `ifdef USE_POWER_PINS
+ .VPWR(VPWR),
+ .VGND(VGND),
+ .VPB(VPWR),
+ .VNB(VGND),
+ `endif
+ .A(Q), .B(net6), .C(net2), .Y(net7));
+
+`endif
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/sar_adc/ACMP_HVL.v b/verilog/rtl/sar_adc/ACMP_HVL.v
new file mode 100644
index 0000000..543cd6e
--- /dev/null
+++ b/verilog/rtl/sar_adc/ACMP_HVL.v
@@ -0,0 +1,112 @@
+/*
+ An analog comparator using HVL cells
+*/
+
+module ACMP_HVL(
+`ifdef USE_POWER_PINS
+ input wire vccd2,
+ input wire vssd2,
+`endif
+ input wire clk,
+ input wire INP,
+ input wire INN,
+ output wire Q
+);
+ wire clkb;
+ wire Q1b, Q1;
+ wire Q2b, Q2;
+ wire Qb;
+
+ sky130_fd_sc_hvl__inv_1 x0 (
+ .Y(clkb),
+ .A(clk)
+ );
+
+ sky130_fd_sc_hvl__nor3_1 x5(
+ .Y(Q),
+ .A(Q1b),
+ .B(Q2b),
+ .C(Qb)
+ );
+
+ sky130_fd_sc_hvl__nor3_1 x6(
+ .Y(Qb),
+ .A(Q1),
+ .B(Q2),
+ .C(Q)
+ );
+
+ latch_nand3 x1 (
+ .CLK(clk),
+ .VP(INP),
+ .VN(INN),
+ .Q(Q1),
+ .Qb(Q1b)
+ );
+
+ latch_nor3 x2 (
+ .CLK(clkb),
+ .VP(INP),
+ .VN(INN),
+ .Q(Q2),
+ .Qb(Q2b)
+ );
+
+endmodule
+
+module latch_nor3 (
+ input wire CLK,
+ input wire VP,
+ input wire VN,
+ output wire Q,
+ output wire Qb
+);
+
+ sky130_fd_sc_hvl__nor3_1 x1(
+ .Y(Qb),
+ .A(CLK),
+ .B(VP),
+ .C(Q)
+ );
+ sky130_fd_sc_hvl__nor3_1 x2(
+ .Y(Q),
+ .A(CLK),
+ .B(VN),
+ .C(Qb)
+ );
+
+endmodule
+
+module latch_nand3 (
+ input wire CLK,
+ input wire VP,
+ input wire VN,
+ output wire Q,
+ output wire Qb
+);
+ wire Q0, Q0b;
+
+ sky130_fd_sc_hvl__nand3_1 x1(
+ .Y(Q0b),
+ .A(CLK),
+ .B(VP),
+ .C(Q0)
+ );
+ sky130_fd_sc_hvl__nand3_1 x2(
+ .Y(Q0),
+ .A(CLK),
+ .B(VN),
+ .C(Q0b)
+ );
+
+ sky130_fd_sc_hvl__inv_4 x3 (
+ .Y(Qb),
+ .A(Q0)
+ );
+
+ sky130_fd_sc_hvl__inv_4 x4 (
+ .Y(Q),
+ .A(Q0b)
+ );
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/sar_adc/DAC_8BIT.v b/verilog/rtl/sar_adc/DAC_8BIT.v
new file mode 100644
index 0000000..8030e18
--- /dev/null
+++ b/verilog/rtl/sar_adc/DAC_8BIT.v
@@ -0,0 +1,24 @@
+module DAC_8BIT (
+`ifdef USE_POWER_PINS
+ input wire vdd, // User area 1 1.8V supply
+ input wire gnd, // User area 1 digital ground
+`endif
+ input wire d0,
+ input wire d1,
+ input wire d2,
+ input wire d3,
+ input wire d4,
+ input wire d5,
+ input wire d6,
+ input wire d7,
+
+ input wire inp1,
+ input wire inp2,
+
+ output wire out_v
+);
+
+// Dummy behavirol model to verify the DAC connection with the user_project_wrapper
+assign out_v = d0 | d1 | d2 | d3 | d4 | d5 | d6 | d7 ;
+
+endmodule
\ No newline at end of file
diff --git a/verilog/rtl/sar_adc/SAR.sv b/verilog/rtl/sar_adc/SAR.sv
new file mode 100644
index 0000000..9931483
--- /dev/null
+++ b/verilog/rtl/sar_adc/SAR.sv
@@ -0,0 +1,65 @@
+// file: SAR.v
+// A parametrized Successive Approximation Register (SAR)
+// The module is so compact; it is only 110 cells for
+// 8-bit SAR using SKY130 HD library
+//
+// author: Mohamed Shalan (mshalan@aucegypt.edu)
+
+`timescale 1ns/1ns
+
+module SAR #(parameter SIZE = 8) (
+ input wire clk, // The clock
+ input wire reset_n, // Active low reset
+ input wire start, // Conversion start
+ input wire cmp, // Analog comparator output
+ output wire [SIZE-1:0] out, // The output sample
+ output wire [SIZE-1:0] outn, // Inverted output for active low DAC
+ output wire done, // Conversion is done
+ output wire clkn // Inverted clock to be used by the clocked analog comparator
+);
+
+ reg [SIZE-1:0] result;
+ reg [SIZE-1:0] shift;
+
+ // FSM to handle the SAR operation
+ reg [1:0] state, nstate;
+ localparam IDLE=0, CONV=1, DONE=2;
+
+ always @*
+ case (state)
+ IDLE: if(start) nstate = CONV;
+ else nstate = IDLE;
+ CONV: if(shift == 1'b1) nstate = DONE;
+ else nstate = CONV;
+ DONE: nstate = IDLE;
+ default: nstate = IDLE;
+ endcase
+
+ always @(posedge clk or negedge reset_n)
+ if(!reset_n)
+ state <= IDLE;
+ else
+ state <= nstate;
+
+ // Shift Register
+ always @(posedge clk)
+ if(state == IDLE)
+ shift <= 1'b1 << (SIZE-1);
+ else if(state == CONV)
+ shift<= shift >> 1;
+
+ // The SAR
+ wire [SIZE-1:0] current = (cmp == 1'b0) ? ~shift : {SIZE{1'b1}} ;
+ wire [SIZE-1:0] next = shift >> 1;
+ always @(posedge clk)
+ if(state == IDLE)
+ result <= 1'b1 << (SIZE-1);
+ else if(state == CONV)
+ result <= (result | next) & current;
+
+ assign out = result;
+ assign outn = ~result;
+ assign clkn = ~clk;
+ assign done = (state==DONE);
+
+endmodule
diff --git a/verilog/rtl/sar_adc/adc_reg.sv b/verilog/rtl/sar_adc/adc_reg.sv
new file mode 100644
index 0000000..24dcf0f
--- /dev/null
+++ b/verilog/rtl/sar_adc/adc_reg.sv
@@ -0,0 +1,262 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// ADC register ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// This block generate all the ADC config and status ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 26 Sept 2021 Dinesh A ////
+//// Initial version ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module adc_reg (
+
+ input logic mclk,
+ input logic reset_n,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [7:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ input logic pulse1m_mclk,
+ // ADC I/F
+ output logic start_conv,
+ output logic [2:0] adc_ch_no,
+ input logic conv_done,
+ input logic [7:0] adc_result
+
+
+ );
+
+
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+logic sw_rd_en;
+logic sw_wr_en;
+logic [3:0] sw_addr ; // addressing 16 registers
+logic [3:0] wr_be ;
+logic [31:0] sw_reg_wdata;
+
+logic reg_cs_l ;
+logic reg_cs_2l ;
+
+
+logic [31:0] reg_0; // ADC Config
+logic [31:0] reg_1; // ADC Ch-1 Result
+logic [31:0] reg_2; // ADC Ch-2 Result
+logic [31:0] reg_3; // ADC Ch-3 Result
+logic [31:0] reg_4; // ADC Ch-4 Result
+logic [31:0] reg_5; // ADC Ch-5 Result
+logic [31:0] reg_6; // ADC Ch-6 Result
+logic [31:0] reg_7; // Software-Reg_7
+logic [31:0] reg_out;
+
+//-----------------------------------------------------------------------
+// Main code starts here
+//-----------------------------------------------------------------------
+
+//-----------------------------------------------------------------------
+// To avoid interface timing, all the content are registered
+//-----------------------------------------------------------------------
+always @ (posedge mclk or negedge reset_n)
+begin
+ if (reset_n == 1'b0)
+ begin
+ sw_addr <= '0;
+ sw_rd_en <= '0;
+ sw_wr_en <= '0;
+ sw_reg_wdata <= '0;
+ wr_be <= '0;
+ reg_cs_l <= '0;
+ reg_cs_2l <= '0;
+ end else begin
+ sw_addr <= reg_addr [5:2];
+ sw_rd_en <= reg_cs & !reg_wr;
+ sw_wr_en <= reg_cs & reg_wr;
+ sw_reg_wdata <= reg_wdata;
+ wr_be <= reg_be;
+ reg_cs_l <= reg_cs;
+ reg_cs_2l <= reg_cs_l;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// Read path mux
+//-----------------------------------------------------------------------
+
+always @ (posedge mclk or negedge reset_n)
+begin : preg_out_Seq
+ if (reset_n == 1'b0) begin
+ reg_rdata [31:0] <= 32'h0000_0000;
+ reg_ack <= 1'b0;
+ end else if (sw_rd_en && !reg_ack && !reg_cs_2l) begin
+ reg_rdata [31:0] <= reg_out [31:0];
+ reg_ack <= 1'b1;
+ end else if (sw_wr_en && !reg_ack && !reg_cs_2l) begin
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 4'h0);
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 4'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 4'h1);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 4'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 4'h2);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 4'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 4'h3);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 4'h3);
+wire sw_wr_en_4 = sw_wr_en & (sw_addr == 4'h4);
+wire sw_rd_en_4 = sw_rd_en & (sw_addr == 4'h4);
+wire sw_wr_en_5 = sw_wr_en & (sw_addr == 4'h5);
+wire sw_rd_en_5 = sw_rd_en & (sw_addr == 4'h5);
+wire sw_wr_en_6 = sw_wr_en & (sw_addr == 4'h6);
+wire sw_rd_en_6 = sw_rd_en & (sw_addr == 4'h6);
+wire sw_wr_en_7 = sw_wr_en & (sw_addr == 4'h7);
+wire sw_rd_en_7 = sw_rd_en & (sw_addr == 4'h7);
+
+always @( *)
+begin : preg_sel_Com
+
+ reg_out [31:0] = 32'd0;
+
+ case (sw_addr [3:0])
+ 4'b0000 : reg_out [31:0] = reg_0 [31:0];
+ 4'b0001 : reg_out [31:0] = {24'h0,reg_1 [7:0]};
+ 4'b0010 : reg_out [31:0] = {24'h0,reg_2 [7:0]};
+ 4'b0011 : reg_out [31:0] = {24'h0,reg_3 [7:0]};
+ 4'b0100 : reg_out [31:0] = {24'h0,reg_4 [7:0]};
+ 4'b0101 : reg_out [31:0] = {24'h0,reg_5 [7:0]};
+ 4'b0110 : reg_out [31:0] = {24'h0,reg_6 [7:0]};
+ default : reg_out [31:0] = 'h0;
+ endcase
+end
+
+
+
+//-----------------------------------------------------------------------
+// Individual register assignments
+//-----------------------------------------------------------------------
+logic [5:0] cfg_adc_enb = reg_0[5:0];
+
+gen_32b_reg #(32'h0) u_reg_0 (
+ //List of Inputs
+ .reset_n (reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_0 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_0 )
+ );
+
+
+always @(posedge mclk or negedge reset_n)
+begin
+ if(~reset_n) begin
+ reg_1[7:0] <= 8'h0;
+ reg_2[7:0] <= 8'h0;
+ reg_3[7:0] <= 8'h0;
+ reg_4[7:0] <= 8'h0;
+ reg_5[7:0] <= 8'h0;
+ reg_6[7:0] <= 8'h0;
+ start_conv <= '0;
+ adc_ch_no <= '0;
+ end else begin
+ if(cfg_adc_enb[0] && pulse1m_mclk) begin
+ if(start_conv && conv_done) begin
+ start_conv <= 0;
+ case(adc_ch_no)
+ 3'b000: reg_1[7:0] <= adc_result;
+ 3'b001: reg_2[7:0] <= adc_result;
+ 3'b010: reg_3[7:0] <= adc_result;
+ 3'b011: reg_4[7:0] <= adc_result;
+ 3'b100: reg_5[7:0] <= adc_result;
+ 3'b101: reg_6[7:0] <= adc_result;
+ endcase
+ end
+ end else begin
+ start_conv <= 1;
+ if(adc_ch_no == 5) begin
+ adc_ch_no <= 0;
+ end else begin
+ adc_ch_no <= adc_ch_no+1;
+ end
+ end
+ end
+end
+
+
+
+
+endmodule
diff --git a/verilog/rtl/sar_adc/sar_adc.sv b/verilog/rtl/sar_adc/sar_adc.sv
new file mode 100644
index 0000000..45b7dbd
--- /dev/null
+++ b/verilog/rtl/sar_adc/sar_adc.sv
@@ -0,0 +1,170 @@
+module sar_adc(
+`ifdef USE_POWER_PINS
+ input logic vccd1 ,// User area 1 1.8V supply
+ input logic vssd1 ,// User area 1 digital ground
+ input logic vccd2 ,// User area 2 1.8V supply (analog)
+ input logic vssd2 ,// User area 2 ground (analog)
+`endif
+
+
+ input logic clk ,// The clock (digital)
+ input logic reset_n ,// Active low reset (digital)
+
+ // Reg Bus Interface Signal
+ input logic reg_cs ,
+ input logic reg_wr ,
+ input logic [7:0] reg_addr ,
+ input logic [31:0] reg_wdata ,
+ input logic [3:0] reg_be ,
+
+ // Outputs
+ output logic [31:0] reg_rdata ,
+ output logic reg_ack ,
+
+ input logic pulse1m_mclk ,
+ output logic [7:0] sar2dac ,// SAR O/P towards DAC
+
+ input logic analog_dac_out, // DAC analog o/p for compare
+
+ // ACMP (HD) Ports
+ input logic [5:0] analog_din // (Analog)
+
+);
+
+ logic clkn;
+ logic [5:0] sar_cmp; // SAR compare signal
+ logic sar_cmp_int;
+ logic [2:0] adc_ch_no;
+ logic start_conv ;// Conversion start (digital)
+ logic conv_done ;// Conversion is done (digital)
+ logic [7:0] adc_result ;// SAR o/p (digital)
+
+always_comb
+begin
+ sar_cmp_int = 0;
+ case(adc_ch_no)
+ 3'b000 : sar_cmp_int = sar_cmp[0];
+ 3'b001 : sar_cmp_int = sar_cmp[1];
+ 3'b010 : sar_cmp_int = sar_cmp[2];
+ 3'b011 : sar_cmp_int = sar_cmp[3];
+ 3'b100 : sar_cmp_int = sar_cmp[4];
+ 3'b101 : sar_cmp_int = sar_cmp[5];
+ endcase
+
+
+end
+
+adc_reg u_adc_reg (
+ .mclk (mclk),
+ .reset_n (reset_n),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_cs),
+ .reg_wr (reg_wr),
+ .reg_addr (reg_addr),
+ .reg_wdata (reg_wdata),
+ .reg_be (reg_be),
+
+ // Outputs
+ .reg_rdata (reg_rdata),
+ .reg_ack (reg_ack),
+
+ .pulse1m_mclk (pulse1m_mclk),
+ // ADC I/F
+ .start_conv (start_conv),
+ .adc_ch_no (adc_ch_no),
+ .conv_done (conv_done),
+ .adc_result (adc_result)
+
+ );
+
+
+ ACMP COMP_0 (
+ `ifdef USE_POWER_PINS
+ .vccd2 (vccd2 ),
+ .vssd2 (vssd2 ),
+ .VDD (vccd2 ),
+ .VSS (vssd2 ),
+ `endif
+ .clk (clk ),
+ .INP (analog_din[0] ),
+ .INN (analog_dac_out ),
+ .Q (sar_cmp[0] )
+ );
+
+ ACMP COMP_1 (
+ `ifdef USE_POWER_PINS
+ .vccd2 (vccd2 ),
+ .vssd2 (vssd2 ),
+ .VDD (vccd2 ),
+ .VSS (vssd2 ),
+ `endif
+ .clk (clk ),
+ .INP (analog_din[1] ),
+ .INN (analog_dac_out ),
+ .Q (sar_cmp[1] )
+ );
+
+ ACMP COMP_2 (
+ `ifdef USE_POWER_PINS
+ .vccd2 (vccd2 ),
+ .vssd2 (vssd2 ),
+ .VDD (vccd2 ),
+ .VSS (vssd2 ),
+ `endif
+ .clk (clk ),
+ .INP (analog_din[2] ),
+ .INN (analog_dac_out ),
+ .Q (sar_cmp[2] )
+ );
+
+ ACMP COMP_3 (
+ `ifdef USE_POWER_PINS
+ .vccd2 (vccd2 ),
+ .vssd2 (vssd2 ),
+ .VDD (vccd2 ),
+ .VSS (vssd2 ),
+ `endif
+ .clk (clk ),
+ .INP (analog_din[3] ),
+ .INN (analog_dac_out ),
+ .Q (sar_cmp[3] )
+ );
+ ACMP COMP_4 (
+ `ifdef USE_POWER_PINS
+ .vccd2 (vccd2 ),
+ .vssd2 (vssd2 ),
+ .VDD (vccd2 ),
+ .VSS (vssd2 ),
+ `endif
+ .clk (clk ),
+ .INP (analog_din[4] ),
+ .INN (analog_dac_out ),
+ .Q (sar_cmp[4] )
+ );
+ ACMP COMP_5 (
+ `ifdef USE_POWER_PINS
+ .vccd2 (vccd2 ),
+ .vssd2 (vssd2 ),
+ .VDD (vccd2 ),
+ .VSS (vssd2 ),
+ `endif
+ .clk (clk ),
+ .INP (analog_din[5] ),
+ .INN (analog_dac_out ),
+ .Q (sar_cmp[5] )
+ );
+
+ SAR CTRL (
+ .clk (clk ),
+ .reset_n (reset_n ),
+ .start (start_conv ),
+ .cmp (sar_cmp_int ),
+ .out (adc_result ),
+ .done (conv_done ),
+ .outn (sar2dac ),
+ .clkn (clkn )
+ );
+
+
+endmodule
diff --git a/verilog/rtl/sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v b/verilog/rtl/sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v
new file mode 100644
index 0000000..289a770
--- /dev/null
+++ b/verilog/rtl/sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v
@@ -0,0 +1,114 @@
+// OpenRAM SRAM model
+// Words: 512
+// Word size: 32
+// Write size: 8
+
+module sky130_sram_2kbyte_1rw1r_32x512_8(
+`ifdef USE_POWER_PINS
+ vccd1,
+ vssd1,
+`endif
+// Port 0: RW
+ clk0,csb0,web0,wmask0,addr0,din0,dout0,
+// Port 1: R
+ clk1,csb1,addr1,dout1
+ );
+
+ parameter NUM_WMASKS = 4 ;
+ parameter DATA_WIDTH = 32 ;
+ parameter ADDR_WIDTH = 9 ;
+ parameter RAM_DEPTH = 1 << ADDR_WIDTH;
+ // FIXME: This delay is arbitrary.
+ parameter DELAY = 3 ;
+ parameter VERBOSE = 0 ; //Set to 0 to only display warnings
+ parameter T_HOLD = 1 ; //Delay to hold dout value after posedge. Value is arbitrary
+
+`ifdef USE_POWER_PINS
+ inout vccd1;
+ inout vssd1;
+`endif
+ input clk0; // clock
+ input csb0; // active low chip select
+ input web0; // active low write control
+ input [NUM_WMASKS-1:0] wmask0; // write mask
+ input [ADDR_WIDTH-1:0] addr0;
+ input [DATA_WIDTH-1:0] din0;
+ output [DATA_WIDTH-1:0] dout0;
+ input clk1; // clock
+ input csb1; // active low chip select
+ input [ADDR_WIDTH-1:0] addr1;
+ output [DATA_WIDTH-1:0] dout1;
+
+ reg csb0_reg;
+ reg web0_reg;
+ reg [NUM_WMASKS-1:0] wmask0_reg;
+ reg [ADDR_WIDTH-1:0] addr0_reg;
+ reg [DATA_WIDTH-1:0] din0_reg;
+ reg [DATA_WIDTH-1:0] dout0;
+
+ // All inputs are registers
+ always @(posedge clk0)
+ begin
+ csb0_reg = csb0;
+ web0_reg = web0;
+ wmask0_reg = wmask0;
+ addr0_reg = addr0;
+ din0_reg = din0;
+ #(T_HOLD) dout0 = 32'bx;
+ if ( !csb0_reg && web0_reg && VERBOSE )
+ $display($time," Reading %m addr0=%b dout0=%b",addr0_reg,mem[addr0_reg]);
+ if ( !csb0_reg && !web0_reg && VERBOSE )
+ $display($time," Writing %m addr0=%b din0=%b wmask0=%b",addr0_reg,din0_reg,wmask0_reg);
+ end
+
+ reg csb1_reg;
+ reg [ADDR_WIDTH-1:0] addr1_reg;
+ reg [DATA_WIDTH-1:0] dout1;
+
+ // All inputs are registers
+ always @(posedge clk1)
+ begin
+ csb1_reg = csb1;
+ addr1_reg = addr1;
+ if (!csb0 && !web0 && !csb1 && (addr0 == addr1))
+ $display($time," WARNING: Writing and reading addr0=%b and addr1=%b simultaneously!",addr0,addr1);
+ #(T_HOLD) dout1 = 32'bx;
+ if ( !csb1_reg && VERBOSE )
+ $display($time," Reading %m addr1=%b dout1=%b",addr1_reg,mem[addr1_reg]);
+ end
+
+reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
+
+ // Memory Write Block Port 0
+ // Write Operation : When web0 = 0, csb0 = 0
+ always @ (negedge clk0)
+ begin : MEM_WRITE0
+ if ( !csb0_reg && !web0_reg ) begin
+ if (wmask0_reg[0])
+ mem[addr0_reg][7:0] = din0_reg[7:0];
+ if (wmask0_reg[1])
+ mem[addr0_reg][15:8] = din0_reg[15:8];
+ if (wmask0_reg[2])
+ mem[addr0_reg][23:16] = din0_reg[23:16];
+ if (wmask0_reg[3])
+ mem[addr0_reg][31:24] = din0_reg[31:24];
+ end
+ end
+
+ // Memory Read Block Port 0
+ // Read Operation : When web0 = 1, csb0 = 0
+ always @ (negedge clk0)
+ begin : MEM_READ0
+ if (!csb0_reg && web0_reg)
+ dout0 <= #(DELAY) mem[addr0_reg];
+ end
+
+ // Memory Read Block Port 1
+ // Read Operation : When web1 = 1, csb1 = 0
+ always @ (negedge clk1)
+ begin : MEM_READ1
+ if (!csb1_reg)
+ dout1 <= #(DELAY) mem[addr1_reg];
+ end
+
+endmodule
diff --git a/verilog/rtl/sspim/src/filelist_spi.f b/verilog/rtl/sspim/src/filelist_spi.f
new file mode 100755
index 0000000..23a2ad5
--- /dev/null
+++ b/verilog/rtl/sspim/src/filelist_spi.f
@@ -0,0 +1,5 @@
+sspim_top.sv
+sspim_ctl.sv
+sspim_if.sv
+sspim_cfg.sv
+-v ../../lib/registers.v
diff --git a/verilog/rtl/sspim/src/sspim_cfg.sv b/verilog/rtl/sspim/src/sspim_cfg.sv
new file mode 100755
index 0000000..cd39e1f
--- /dev/null
+++ b/verilog/rtl/sspim/src/sspim_cfg.sv
@@ -0,0 +1,298 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Single SPI Master Interface Module ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// Subbport Single Bit SPI Master ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// V.0 - 06 Oct 2021 ////
+//// Initial SpI Module picked from ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+
+module sspim_cfg (
+ input logic mclk ,
+ input logic reset_n ,
+
+ output logic [1:0] cfg_tgt_sel ,
+
+ output logic cfg_op_req , // SPI operation request
+ output logic [1:0] cfg_op_type , // SPI operation type
+ output logic [1:0] cfg_transfer_size , // SPI transfer size
+ output logic [5:0] cfg_sck_period , // sck clock period
+ output logic [4:0] cfg_sck_cs_period , // cs setup/hold period
+ output logic [7:0] cfg_cs_byte , // cs bit information
+ output logic [31:0] cfg_datain , // data for transfer
+ input logic [31:0] cfg_dataout , // data for received
+ input logic hware_op_done , // operation done
+
+ //---------------------------------
+ // Reg Bus Interface Signal
+ //---------------------------------
+ input logic reg_cs ,
+ input logic reg_wr ,
+ input logic [7:0] reg_addr ,
+ input logic [31:0] reg_wdata ,
+ input logic [3:0] reg_be ,
+
+ // Outputs
+ output logic [31:0] reg_rdata ,
+ output logic reg_ack
+
+
+ );
+
+
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+logic sw_rd_en ;
+logic sw_wr_en;
+logic [1:0] sw_addr; // addressing 16 registers
+logic [31:0] sw_reg_wdata;
+logic [3:0] wr_be ;
+logic reg_cs_l;
+logic reg_cs_2l;
+
+logic [31:0] reg_0; // Software_Reg_0
+logic [31:0] reg_1; // Software-Reg_1
+logic [31:0] reg_2; // Software-Reg_2
+logic [31:0] reg_out;
+
+//-----------------------------------------------------------------------
+// Main code starts here
+//-----------------------------------------------------------------------
+
+//-----------------------------------------------------------------------
+// To avoid interface timing, all the content are registered
+//-----------------------------------------------------------------------
+always @ (posedge mclk or negedge reset_n)
+begin
+ if (reset_n == 1'b0)
+ begin
+ sw_addr <= '0;
+ sw_rd_en <= '0;
+ sw_wr_en <= '0;
+ sw_reg_wdata <= '0;
+ wr_be <= '0;
+ reg_cs_l <= '0;
+ reg_cs_2l <= '0;
+ end else begin
+ sw_addr <= reg_addr [3:2];
+ sw_rd_en <= reg_cs & !reg_wr;
+ sw_wr_en <= reg_cs & reg_wr;
+ sw_reg_wdata <= reg_wdata;
+ wr_be <= reg_be;
+ reg_cs_l <= reg_cs;
+ reg_cs_2l <= reg_cs_l;
+ end
+end
+
+//-----------------------------------------------------------------------
+// Read path mux
+//-----------------------------------------------------------------------
+
+always @ (posedge mclk or negedge reset_n)
+begin : preg_out_Seq
+ if (reset_n == 1'b0) begin
+ reg_rdata [31:0] <= 32'h0000_0000;
+ reg_ack <= 1'b0;
+ end else if (sw_rd_en && !reg_ack && !reg_cs_2l) begin
+ reg_rdata [31:0] <= reg_out [31:0];
+ reg_ack <= 1'b1;
+ end else if (sw_wr_en && !reg_ack && !reg_cs_2l) begin
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 2'h0);
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 2'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 2'h1);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 2'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 2'h2);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 2'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 2'h3);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 2'h3);
+
+
+always @( *)
+begin : preg_sel_Com
+
+ reg_out [31:0] = 32'd0;
+
+ case (sw_addr [3:0])
+ 4'b0000 : reg_out [31:0] = reg_0 [31:0];
+ 4'b0001 : reg_out [31:0] = reg_1 [31:0];
+ 4'b0010 : reg_out [31:0] = reg_2 [31:0];
+ default : reg_out [31:0] = 32'h0;
+ endcase
+end
+
+
+
+//-----------------------------------------------------------------------
+// Individual register assignments
+//-----------------------------------------------------------------------
+// Logic for Register 0 : SPI Control Register
+//-----------------------------------------------------------------------
+assign cfg_op_req = reg_0[31]; // cpu request
+assign cfg_tgt_sel = reg_0[24:23]; // target chip select
+assign cfg_op_type = reg_0[22:21]; // SPI operation type
+assign cfg_transfer_size = reg_0[20:19]; // SPI transfer size
+assign cfg_sck_period = reg_0[18:13]; // sck clock period
+assign cfg_sck_cs_period = reg_0[12:8]; // cs setup/hold period
+assign cfg_cs_byte = reg_0[7:0]; // cs bit information
+
+generic_register #(8,0 ) u_spi_ctrl_be0 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[7:0] )
+ );
+
+generic_register #(8,0 ) u_spi_ctrl_be1 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[15:8] )
+ );
+
+generic_register #(8,0 ) u_spi_ctrl_be2 (
+ .we ({8{sw_wr_en_0 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[23:16] )
+ );
+
+assign reg_0[30:24] = 7'h0;
+
+req_register #(0 ) u_spi_ctrl_req (
+ .cpu_we ({sw_wr_en_0 &
+ wr_be[3] } ),
+ .cpu_req (sw_reg_wdata[31] ),
+ .hware_ack (hware_op_done ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[31] )
+ );
+
+
+
+
+//-----------------------------------------------------------------------
+// Logic for Register 1 : SPI Data In Register
+//-----------------------------------------------------------------------
+assign cfg_datain = reg_1[31:0];
+
+generic_register #(8,0 ) u_spi_din_be0 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[7:0] )
+ );
+
+generic_register #(8,0 ) u_spi_din_be1 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[1] }} ),
+ .data_in (sw_reg_wdata[15:8] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[15:8] )
+ );
+
+generic_register #(8,0 ) u_spi_din_be2 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[23:16] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[23:16] )
+ );
+
+
+generic_register #(8,0 ) u_spi_din_be3 (
+ .we ({8{sw_wr_en_1 &
+ wr_be[3] }} ),
+ .data_in (sw_reg_wdata[31:24] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_1[31:24] )
+ );
+
+
+//-----------------------------------------------------------------------
+// Logic for Register 2 : SPI Data output Register
+//-----------------------------------------------------------------------
+assign reg_2 = cfg_dataout;
+
+
+
+endmodule
diff --git a/verilog/rtl/sspim/src/sspim_ctl.sv b/verilog/rtl/sspim/src/sspim_ctl.sv
new file mode 100755
index 0000000..f65c0c2
--- /dev/null
+++ b/verilog/rtl/sspim/src/sspim_ctl.sv
@@ -0,0 +1,286 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Single SPI Master Interface Module ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// SPI Control module ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// V.0 - 06 Oct 2021 ////
+//// Initial SpI Module picked from ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+
+module sspim_ctl
+ (
+ input logic clk,
+ input logic reset_n,
+ input logic cfg_op_req,
+ input logic [1:0] cfg_op_type,
+ input logic [1:0] cfg_transfer_size,
+
+ input logic [5:0] cfg_sck_period,
+ input logic [4:0] cfg_sck_cs_period, // cs setup & hold period
+ input logic [7:0] cfg_cs_byte,
+ input logic [31:0] cfg_datain,
+ output logic [31:0] cfg_dataout,
+
+ output logic [7:0] byte_out, // Byte out for Serial Shifting out
+ input logic [7:0] byte_in, // Serial Received Byte
+ output logic sck_int,
+ output logic cs_int_n,
+ output logic sck_pe,
+ output logic sck_ne,
+ output logic shift_out,
+ output logic shift_in,
+ output logic load_byte,
+ output logic op_done
+
+ );
+
+ //*************************************************************************
+
+
+ logic [5:0] clk_cnt;
+ logic [5:0] sck_cnt;
+
+ logic [3:0] spiif_cs;
+ logic shift_enb;
+ logic clr_sck_cnt ;
+ logic sck_out_en;
+
+ logic [5:0] sck_half_period;
+ logic [2:0] byte_cnt;
+
+
+ `define SPI_IDLE 4'b0000
+ `define SPI_CS_SU 4'b0001
+ `define SPI_WRITE 4'b0010
+ `define SPI_READ 4'b0011
+ `define SPI_CS_HLD 4'b0100
+ `define SPI_WAIT 4'b0101
+
+
+ assign sck_half_period = {1'b0, cfg_sck_period[5:1]};
+ // The first transition on the sck_toggle happens one SCK period
+ // after op_en or boot_en is asserted
+ always @(posedge clk or negedge reset_n) begin
+ if(!reset_n) begin
+ sck_ne <= 1'b0;
+ clk_cnt <= 6'h1;
+ sck_pe <= 1'b0;
+ sck_int <= 1'b0;
+ end // if (!reset_n)
+ else
+ begin
+ if(cfg_op_req)
+ begin
+ if(clk_cnt == sck_half_period)
+ begin
+ sck_ne <= 1'b1;
+ sck_pe <= 1'b0;
+ if(sck_out_en) sck_int <= 0;
+ clk_cnt <= clk_cnt + 1'b1;
+ end // if (clk_cnt == sck_half_period)
+ else
+ begin
+ if(clk_cnt == cfg_sck_period)
+ begin
+ sck_ne <= 1'b0;
+ sck_pe <= 1'b1;
+ if(sck_out_en) sck_int <= 1;
+ clk_cnt <= 6'h1;
+ end // if (clk_cnt == cfg_sck_period)
+ else
+ begin
+ clk_cnt <= clk_cnt + 1'b1;
+ sck_pe <= 1'b0;
+ sck_ne <= 1'b0;
+ end // else: !if(clk_cnt == cfg_sck_period)
+ end // else: !if(clk_cnt == sck_half_period)
+ end // if (op_en)
+ else
+ begin
+ clk_cnt <= 6'h1;
+ sck_pe <= 1'b0;
+ sck_ne <= 1'b0;
+ end // else: !if(op_en)
+ end // else: !if(!reset_n)
+ end // always @ (posedge clk or negedge reset_n)
+
+
+wire [1:0] cs_data = (byte_cnt == 2'b00) ? cfg_cs_byte[7:6] :
+ (byte_cnt == 2'b01) ? cfg_cs_byte[5:4] :
+ (byte_cnt == 2'b10) ? cfg_cs_byte[3:2] : cfg_cs_byte[1:0] ;
+
+assign byte_out = (byte_cnt == 2'b00) ? cfg_datain[31:24] :
+ (byte_cnt == 2'b01) ? cfg_datain[23:16] :
+ (byte_cnt == 2'b10) ? cfg_datain[15:8] : cfg_datain[7:0] ;
+
+assign shift_out = shift_enb && sck_ne;
+
+always @(posedge clk or negedge reset_n) begin
+ if(!reset_n) begin
+ spiif_cs <= `SPI_IDLE;
+ sck_cnt <= 6'h0;
+ shift_in <= 1'b0;
+ clr_sck_cnt <= 1'b1;
+ byte_cnt <= 2'b00;
+ cs_int_n <= 1'b1;
+ sck_out_en <= 1'b0;
+ shift_enb <= 1'b0;
+ cfg_dataout <= 32'h0;
+ load_byte <= 1'b0;
+ end
+ else begin
+ if(sck_ne)
+ sck_cnt <= clr_sck_cnt ? 6'h0 : sck_cnt + 1 ;
+
+ case(spiif_cs)
+ `SPI_IDLE :
+ begin
+ op_done <= 0;
+ clr_sck_cnt <= 1'b1;
+ sck_out_en <= 1'b0;
+ shift_enb <= 1'b0;
+ if(cfg_op_req)
+ begin
+ cfg_dataout <= 32'h0;
+ spiif_cs <= `SPI_CS_SU;
+ end
+ else begin
+ spiif_cs <= `SPI_IDLE;
+ end
+ end
+
+ `SPI_CS_SU :
+ begin
+ if(sck_ne) begin
+ cs_int_n <= cs_data[1];
+ if(sck_cnt == cfg_sck_cs_period) begin
+ clr_sck_cnt <= 1'b1;
+ if(cfg_op_type == 0) begin // Write Mode
+ load_byte <= 1'b1;
+ spiif_cs <= `SPI_WRITE;
+ shift_enb <= 1'b0;
+ end else begin
+ shift_in <= 1;
+ spiif_cs <= `SPI_READ;
+ end
+ end
+ else begin
+ clr_sck_cnt <= 1'b0;
+ end
+ end
+ end
+
+ `SPI_WRITE :
+ begin
+ load_byte <= 1'b0;
+ if(sck_ne) begin
+ if(sck_cnt == 3'h7 )begin
+ clr_sck_cnt <= 1'b1;
+ spiif_cs <= `SPI_CS_HLD;
+ shift_enb <= 1'b0;
+ sck_out_en <= 1'b0; // Disable clock output
+ end
+ else begin
+ shift_enb <= 1'b1;
+ sck_out_en <= 1'b1;
+ clr_sck_cnt <= 1'b0;
+ end
+ end else begin
+ shift_enb <= 1'b1;
+ end
+ end
+
+ `SPI_READ :
+ begin
+ if(sck_ne) begin
+ if( sck_cnt == 3'h7 ) begin
+ clr_sck_cnt <= 1'b1;
+ shift_in <= 0;
+ spiif_cs <= `SPI_CS_HLD;
+ sck_out_en <= 1'b0; // Disable clock output
+ end
+ else begin
+ sck_out_en <= 1'b1; // Disable clock output
+ clr_sck_cnt <= 1'b0;
+ end
+ end
+ end
+
+ `SPI_CS_HLD : begin
+ if(sck_ne) begin
+ cs_int_n <= cs_data[0];
+ if(sck_cnt == cfg_sck_cs_period) begin
+ if(cfg_op_type == 1) begin // Read Mode
+ cfg_dataout <= (byte_cnt[1:0] == 2'b00) ? { byte_in, cfg_dataout[23:0] } :
+ (byte_cnt[1:0] == 2'b01) ? { cfg_dataout[31:24] ,
+ byte_in, cfg_dataout[15:0] } :
+ (byte_cnt[1:0] == 2'b10) ? { cfg_dataout[31:16] ,
+ byte_in, cfg_dataout[7:0] } :
+ { cfg_dataout[31:8] ,
+ byte_in } ;
+ end
+ clr_sck_cnt <= 1'b1;
+ if(byte_cnt == cfg_transfer_size) begin
+ spiif_cs <= `SPI_WAIT;
+ byte_cnt <= 0;
+ op_done <= 1;
+ end else begin
+ byte_cnt <= byte_cnt +1;
+ spiif_cs <= `SPI_CS_SU;
+ end
+ end
+ else begin
+ clr_sck_cnt <= 1'b0;
+ end
+ end
+ end // case: `SPI_CS_HLD
+ `SPI_WAIT : begin
+ if(!cfg_op_req) // Wait for Request de-assertion
+ spiif_cs <= `SPI_IDLE;
+ end
+ endcase // casex(spiif_cs)
+ end
+end // always @(sck_ne
+
+endmodule
diff --git a/verilog/rtl/sspim/src/sspim_if.sv b/verilog/rtl/sspim/src/sspim_if.sv
new file mode 100755
index 0000000..42b18f2
--- /dev/null
+++ b/verilog/rtl/sspim/src/sspim_if.sv
@@ -0,0 +1,122 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Single SPI Master Interface Module ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// V.0 - 06 Oct 2021 ////
+//// Initial SpI Module picked from ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module sspim_if
+ (
+ input logic clk,
+ input logic reset_n,
+ input logic sck_pe,
+ input logic sck_int,
+ input logic cs_int_n,
+
+ input logic load_byte,
+ input logic [1:0] cfg_tgt_sel,
+
+ input logic [7:0] byte_out,
+ input logic shift_out,
+ input logic shift_in,
+
+ output logic [7:0] byte_in,
+ output logic sck,
+ output logic so,
+ output logic [3:0] cs_n,
+ input logic si
+ );
+
+
+
+ logic [7:0] so_reg;
+ logic [7:0] si_reg;
+
+
+ //Output Shift Register
+
+ always @(posedge clk or negedge reset_n) begin
+ if(!reset_n) begin
+ so_reg <= 8'h00;
+ so <= 1'b0;
+ end
+ else begin
+ if(load_byte) begin
+ so_reg <= byte_out;
+ if(shift_out) begin
+ // Handling backto back case :
+ // Last Transfer bit + New Trasfer Load
+ so <= so_reg[7];
+ end
+ end // if (load_byte)
+ else begin
+ if(shift_out) begin
+ so <= so_reg[7];
+ so_reg <= {so_reg[6:0],1'b0};
+ end // if (shift_out)
+ end // else: !if(load_byte)
+ end // else: !if(!reset_n)
+ end // always @ (posedge clk or negedge reset_n)
+
+
+// Input shift register
+ always @(posedge clk or negedge reset_n) begin
+ if(!reset_n) begin
+ si_reg <= 8'h0;
+ end
+ else begin
+ if(sck_pe & shift_in) begin
+ si_reg[7:0] <= {si_reg[6:0],si};
+ end // if (sck_pe & shift_in)
+ end // else: !if(!reset_n)
+ end // always @ (posedge clk or negedge reset_n)
+
+
+ assign byte_in[7:0] = si_reg[7:0];
+ assign cs_n[0] = (cfg_tgt_sel[1:0] == 2'b00) ? cs_int_n : 1'b1;
+ assign cs_n[1] = (cfg_tgt_sel[1:0] == 2'b01) ? cs_int_n : 1'b1;
+ assign cs_n[2] = (cfg_tgt_sel[1:0] == 2'b10) ? cs_int_n : 1'b1;
+ assign cs_n[3] = (cfg_tgt_sel[1:0] == 2'b11) ? cs_int_n : 1'b1;
+ assign sck = sck_int;
+
+endmodule
diff --git a/verilog/rtl/sspim/src/sspim_top.sv b/verilog/rtl/sspim/src/sspim_top.sv
new file mode 100755
index 0000000..0c740d6
--- /dev/null
+++ b/verilog/rtl/sspim/src/sspim_top.sv
@@ -0,0 +1,208 @@
+
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// SPI Master Top Module ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// This block integrate the SPI Master related module ////
+//// - sspim_if ////
+//// - sspim_ctl ////
+//// - sspim_cfg ////
+//// ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 03 Oct 2021, Dinesh A ////
+//// Initial SpI Module picked from ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module sspim_top (
+ input logic clk ,
+ input logic reset_n ,
+
+
+ //---------------------------------
+ // Reg Bus Interface Signal
+ //---------------------------------
+ input logic reg_cs ,
+ input logic reg_wr ,
+ input logic [7:0] reg_addr ,
+ input logic [31:0] reg_wdata ,
+ input logic [3:0] reg_be ,
+
+ // Outputs
+ output logic [31:0] reg_rdata ,
+ output logic reg_ack ,
+
+ //-------------------------------------------
+ // Line Interface
+ //-------------------------------------------
+
+ output logic sck , // clock out
+ output logic so , // serial data out
+ input logic si , // serial data in
+ output logic ssn // cs_n
+
+ );
+
+
+//------------------------------------
+// Local declration
+//------------------------------------
+
+logic [7:0] byte_in ;
+logic [7:0] byte_out ;
+
+
+logic [1:0] cfg_tgt_sel ;
+
+logic cfg_op_req ; // SPI operation request
+logic [1:0] cfg_op_type ; // SPI operation type
+logic [1:0] cfg_transfer_size ; // SPI transfer size
+logic [5:0] cfg_sck_period ; // sck clock period
+logic [4:0] cfg_sck_cs_period ; // cs setup/hold period
+logic [7:0] cfg_cs_byte ; // cs bit information
+logic [31:0] cfg_datain ; // data for transfer
+logic [31:0] cfg_dataout ; // data for received
+logic hware_op_done ; // operation done
+logic [3:0] cs_n ; // cs_n
+
+assign ssn = cs_n[0]; // Only 1 chip select supported in riscdunio
+
+sspim_if u_spi_if
+ (
+ . clk (clk ),
+ . reset_n (reset_n ),
+
+ // towards ctrl i/f
+ . sck_pe (sck_pe ),
+ . sck_int (sck_int ),
+ . cs_int_n (cs_int_n ),
+ . byte_in (byte_in ),
+ . load_byte (load_byte ),
+ . byte_out (byte_out ),
+ . shift_out (shift_out ),
+ . shift_in (shift_in ),
+
+ . cfg_tgt_sel (cfg_tgt_sel ),
+
+ . sck (sck ),
+ . so (so ),
+ . si (si ),
+ . cs_n (cs_n )
+ );
+
+
+sspim_ctl u_spi_ctrl
+ (
+ . clk (clk ),
+ . reset_n (reset_n ),
+
+ . cfg_op_req (cfg_op_req ),
+ . cfg_op_type (cfg_op_type ),
+ . cfg_transfer_size (cfg_transfer_size ),
+ . cfg_sck_period (cfg_sck_period ),
+ . cfg_sck_cs_period (cfg_sck_cs_period ),
+ . cfg_cs_byte (cfg_cs_byte ),
+ . cfg_datain (cfg_datain ),
+ . cfg_dataout (cfg_dataout ),
+ . op_done (hware_op_done ),
+
+ . sck_int (sck_int ),
+ . cs_int_n (cs_int_n ),
+ . sck_pe (sck_pe ),
+ . sck_ne (sck_ne ),
+ . shift_out (shift_out ),
+ . shift_in (shift_in ),
+ . load_byte (load_byte ),
+ . byte_out (byte_out ),
+ . byte_in (byte_in )
+
+ );
+
+
+
+
+sspim_cfg u_cfg (
+
+ . mclk (clk ),
+ . reset_n (reset_n ),
+
+ // Reg Bus Interface Signal
+ . reg_cs (reg_cs ),
+ . reg_wr (reg_wr ),
+ . reg_addr (reg_addr ),
+ . reg_wdata (reg_wdata ),
+ . reg_be (reg_be ),
+
+ // Outputs
+ . reg_rdata (reg_rdata ),
+ . reg_ack (reg_ack ),
+
+
+ // configuration signal
+ . cfg_tgt_sel (cfg_tgt_sel ),
+ . cfg_op_req (cfg_op_req ), // SPI operation request
+ . cfg_op_type (cfg_op_type ), // SPI operation type
+ . cfg_transfer_size (cfg_transfer_size ), // SPI transfer size
+ . cfg_sck_period (cfg_sck_period ), // sck clock period
+ . cfg_sck_cs_period (cfg_sck_cs_period ), // cs setup/hold period
+ . cfg_cs_byte (cfg_cs_byte ), // cs bit information
+ . cfg_datain (cfg_datain ), // data for transfer
+ . cfg_dataout (cfg_dataout ), // data for received
+ . hware_op_done (hware_op_done ) // operation done
+
+ );
+
+endmodule
diff --git a/verilog/rtl/uart/src/uart_cfg.sv b/verilog/rtl/uart/src/uart_cfg.sv
new file mode 100644
index 0000000..ca4dea6
--- /dev/null
+++ b/verilog/rtl/uart/src/uart_cfg.sv
@@ -0,0 +1,405 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART Configuration ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th June 2021, Dinesh A ////
+//// 1. initial version picked from ////
+//// http://www.opencores.org/cores/oms8051mini ////
+//// 0.2 - 20th June 2021, Dinesh A ////
+//// tx and rx buffer status added into reg7 and reg8 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_cfg (
+
+ mclk,
+ reset_n,
+
+ // Reg Bus Interface Signal
+ reg_cs,
+ reg_wr,
+ reg_addr,
+ reg_wdata,
+ reg_be,
+
+ // Outputs
+ reg_rdata,
+ reg_ack,
+
+ // Uart Tx fifo interface
+ tx_fifo_full,
+ tx_fifo_fspace,
+ tx_fifo_wr_en,
+ tx_fifo_data,
+
+ // Uart Rx fifo interface
+ rx_fifo_empty,
+ rx_fifo_dval ,
+ rx_fifo_rd_en,
+ rx_fifo_data ,
+
+ // configuration
+ cfg_tx_enable,
+ cfg_rx_enable,
+ cfg_stop_bit ,
+ cfg_pri_mod ,
+ cfg_baud_16x ,
+
+ frm_error_o,
+ par_error_o,
+ rx_fifo_full_err_o
+
+ );
+
+
+
+input mclk;
+input reset_n;
+
+//--------------------------------
+// Uart Tx fifo interface
+//--------------------------------
+input tx_fifo_full;
+input [4:0] tx_fifo_fspace ; // Total Tx fifo Free Space
+output tx_fifo_wr_en;
+output [7:0] tx_fifo_data;
+
+//--------------------------------
+// Uart Rx fifo interface
+//--------------------------------
+input rx_fifo_empty;
+input [4:0] rx_fifo_dval ; // Total Rx fifo Data Available
+output rx_fifo_rd_en;
+input [7:0] rx_fifo_data;
+
+//----------------------------------
+// configuration
+//----------------------------------
+output cfg_tx_enable ; // Tx Enable
+output cfg_rx_enable ; // Rx Enable
+output cfg_stop_bit ; // 0 -> 1 Stop, 1 -> 2 Stop
+output [1:0] cfg_pri_mod ; // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+output [11:0] cfg_baud_16x ; // 16x Baud clock config
+
+input frm_error_o ; // framing error
+input par_error_o ; // par error
+input rx_fifo_full_err_o ; // rx fifo full error
+
+//---------------------------------
+// Reg Bus Interface Signal
+//---------------------------------
+input reg_cs ;
+input reg_wr ;
+input [3:0] reg_addr ;
+input [7:0] reg_wdata ;
+input reg_be ;
+
+// Outputs
+output [7:0] reg_rdata ;
+output reg_ack ;
+
+
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+wire sw_rd_en;
+wire sw_wr_en;
+wire [3:0] sw_addr ; // addressing 16 registers
+wire wr_be ;
+
+reg [7:0] reg_rdata ;
+reg reg_ack ;
+
+wire [7:0] reg_0; // Software_Reg_0
+wire [7:0] reg_1; // Software-Reg_1
+wire [7:0] reg_2; // Software-Reg_2
+wire [7:0] reg_3; // Software-Reg_3
+wire [7:0] reg_4; // Software-Reg_4
+wire [7:0] reg_5; // Software-Reg_5
+wire [7:0] reg_6; // Software-Reg_6
+wire [7:0] reg_7; // Software-Reg_7
+wire [7:0] reg_8; // Software-Reg_8
+wire [7:0] reg_9; // Software-Reg_9
+wire [7:0] reg_10; // Software-Reg_10
+wire [7:0] reg_11; // Software-Reg_11
+wire [7:0] reg_12; // Software-Reg_12
+wire [7:0] reg_13; // Software-Reg_13
+wire [7:0] reg_14; // Software-Reg_14
+wire [7:0] reg_15; // Software-Reg_15
+reg [7:0] reg_out;
+
+//-----------------------------------------------------------------------
+// Main code starts here
+//-----------------------------------------------------------------------
+
+//-----------------------------------------------------------------------
+// Internal Logic Starts here
+//-----------------------------------------------------------------------
+ assign sw_addr = reg_addr [3:0];
+ assign sw_rd_en = reg_cs & !reg_wr;
+ assign sw_wr_en = reg_cs & reg_wr;
+ assign wr_be = reg_be;
+
+
+//-----------------------------------------------------------------------
+// Read path mux
+//-----------------------------------------------------------------------
+
+always @ (posedge mclk or negedge reset_n)
+begin : preg_out_Seq
+ if (reset_n == 1'b0)
+ begin
+ reg_rdata [7:0] <= 8'h00;
+ reg_ack <= 1'b0;
+ end
+ else if (sw_rd_en && !reg_ack)
+ begin
+ reg_rdata [7:0] <= reg_out [7:0];
+ reg_ack <= 1'b1;
+ end
+ else if (sw_wr_en && !reg_ack)
+ reg_ack <= 1'b1;
+ else
+ begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 4'h0);
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 4'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 4'h1);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 4'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 4'h2);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 4'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 4'h3);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 4'h3);
+wire sw_wr_en_4 = sw_wr_en & (sw_addr == 4'h4);
+wire sw_rd_en_4 = sw_rd_en & (sw_addr == 4'h4);
+wire sw_wr_en_5 = sw_wr_en & (sw_addr == 4'h5);
+wire sw_rd_en_5 = sw_rd_en & (sw_addr == 4'h5);
+wire sw_wr_en_6 = sw_wr_en & (sw_addr == 4'h6);
+wire sw_rd_en_6 = sw_rd_en & (sw_addr == 4'h6);
+wire sw_wr_en_7 = sw_wr_en & (sw_addr == 4'h7);
+wire sw_rd_en_7 = sw_rd_en & (sw_addr == 4'h7);
+wire sw_wr_en_8 = sw_wr_en & (sw_addr == 4'h8);
+wire sw_rd_en_8 = sw_rd_en & (sw_addr == 4'h8);
+wire sw_wr_en_9 = sw_wr_en & (sw_addr == 4'h9);
+wire sw_rd_en_9 = sw_rd_en & (sw_addr == 4'h9);
+wire sw_wr_en_10 = sw_wr_en & (sw_addr == 4'hA);
+wire sw_rd_en_10 = sw_rd_en & (sw_addr == 4'hA);
+wire sw_wr_en_11 = sw_wr_en & (sw_addr == 4'hB);
+wire sw_rd_en_11 = sw_rd_en & (sw_addr == 4'hB);
+wire sw_wr_en_12 = sw_wr_en & (sw_addr == 4'hC);
+wire sw_rd_en_12 = sw_rd_en & (sw_addr == 4'hC);
+wire sw_wr_en_13 = sw_wr_en & (sw_addr == 4'hD);
+wire sw_rd_en_13 = sw_rd_en & (sw_addr == 4'hD);
+wire sw_wr_en_14 = sw_wr_en & (sw_addr == 4'hE);
+wire sw_rd_en_14 = sw_rd_en & (sw_addr == 4'hE);
+wire sw_wr_en_15 = sw_wr_en & (sw_addr == 4'hF);
+wire sw_rd_en_15 = sw_rd_en & (sw_addr == 4'hF);
+
+
+always @( *)
+begin : preg_sel_Com
+
+ reg_out [7:0] = 8'd0;
+
+ case (sw_addr [3:0])
+ 4'b0000 : reg_out [7:0] = reg_0 [7:0];
+ 4'b0001 : reg_out [7:0] = reg_1 [7:0];
+ 4'b0010 : reg_out [7:0] = reg_2 [7:0];
+ 4'b0011 : reg_out [7:0] = reg_3 [7:0];
+ 4'b0100 : reg_out [7:0] = reg_4 [7:0];
+ 4'b0101 : reg_out [7:0] = reg_5 [7:0];
+ 4'b0110 : reg_out [7:0] = reg_6 [7:0];
+ 4'b0111 : reg_out [7:0] = reg_7 [7:0];
+ 4'b1000 : reg_out [7:0] = reg_8 [7:0];
+ 4'b1001 : reg_out [7:0] = reg_9 [7:0];
+ 4'b1010 : reg_out [7:0] = reg_10 [7:0];
+ 4'b1011 : reg_out [7:0] = reg_11 [7:0];
+ 4'b1100 : reg_out [7:0] = reg_12 [7:0];
+ 4'b1101 : reg_out [7:0] = reg_13 [7:0];
+ 4'b1110 : reg_out [7:0] = reg_14 [7:0];
+ 4'b1111 : reg_out [7:0] = reg_15 [7:0];
+ endcase
+end
+
+
+
+//-----------------------------------------------------------------------
+// Individual register assignments
+//-----------------------------------------------------------------------
+// Logic for Register 0 : uart Control Register
+//-----------------------------------------------------------------------
+wire [1:0] cfg_pri_mod = reg_0[4:3]; // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+wire cfg_stop_bit = reg_0[2]; // 0 -> 1 Stop, 1 -> 2 Stop
+wire cfg_rx_enable = reg_0[1]; // Rx Enable
+wire cfg_tx_enable = reg_0[0]; // Tx Enable
+
+generic_register #(5,0 ) u_uart_ctrl_be0 (
+ .we ({5{sw_wr_en_0 &
+ wr_be }} ),
+ .data_in (reg_wdata[4:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[4:0] )
+ );
+
+
+assign reg_0[7:5] = 3'h0;
+
+//-----------------------------------------------------------------------
+// Logic for Register 1 : uart interrupt status
+//-----------------------------------------------------------------------
+stat_register u_intr_bit0 (
+ //inputs
+ . clk (mclk ),
+ . reset_n (reset_n ),
+ . cpu_we (sw_wr_en_1 &
+ wr_be ),
+ . cpu_ack (reg_wdata[0] ),
+ . hware_req (frm_error_o ),
+
+ //outputs
+ . data_out (reg_1[0] )
+ );
+
+stat_register u_intr_bit1 (
+ //inputs
+ . clk (mclk ),
+ . reset_n (reset_n ),
+ . cpu_we (sw_wr_en_1 &
+ wr_be ),
+ . cpu_ack (reg_wdata[1] ),
+ . hware_req (par_error_o ),
+
+ //outputs
+ . data_out (reg_1[1] )
+ );
+
+stat_register u_intr_bit2 (
+ //inputs
+ . clk (mclk ),
+ . reset_n (reset_n ),
+ . cpu_we (sw_wr_en_1 &
+ wr_be ),
+ . cpu_ack (reg_wdata[2] ),
+ . hware_req (rx_fifo_full_err_o ),
+
+ //outputs
+ . data_out (reg_1[2] )
+ );
+
+assign reg_1[7:3] = 5'h0;
+
+
+//-----------------------------------------------------------------------
+// Logic for Register 2 : Baud Rate Control
+//-----------------------------------------------------------------------
+wire [11:0] cfg_baud_16x = {reg_3[3:0],reg_2[7:0]};
+
+generic_register #(8,0 ) u_uart_ctrl_reg2 (
+ .we ({8{sw_wr_en_2 &
+ wr_be }} ),
+ .data_in (reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[7:0] )
+ );
+
+generic_register #(4,0 ) u_uart_ctrl_reg3 (
+ .we ({4{sw_wr_en_3 &
+ wr_be }} ),
+ .data_in (reg_wdata[3:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_3[3:0] )
+ );
+
+assign reg_3[7:4] = 4'h0;
+
+
+// reg-4 status
+//
+assign reg_4[7:0] = {6'h0,rx_fifo_empty,tx_fifo_full};
+
+// reg_5 is tx_fifo wr
+assign tx_fifo_wr_en = sw_wr_en_5 & reg_ack & !tx_fifo_full;
+assign tx_fifo_data = reg_wdata[7:0];
+
+// reg_6 is rx_fifo read
+// rx_fifo read data
+assign reg_6[7:0] = {rx_fifo_data};
+assign rx_fifo_rd_en = sw_rd_en_6 & reg_ack & !rx_fifo_empty;
+
+assign reg_7[7:0] = {3'h0,tx_fifo_fspace}; // tx fifo free space
+assign reg_8[7:0] = {3'h0,rx_fifo_dval}; // rx fifo data available
+
+endmodule
diff --git a/verilog/rtl/uart/src/uart_core.sv b/verilog/rtl/uart/src/uart_core.sv
new file mode 100644
index 0000000..948cd35
--- /dev/null
+++ b/verilog/rtl/uart/src/uart_core.sv
@@ -0,0 +1,334 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART CORE with TX/RX 16 Byte Buffer ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th June 2021, Dinesh A ////
+//// 1. initial version picked from ////
+//// http://www.opencores.org/cores/oms8051mini ////
+//// 0.2 - 25th June 2021, Dinesh A ////
+//// Pad logic moved inside core to avoid combo logic at ////
+//// soc digital core level ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_core
+
+ (
+
+ input logic arst_n , // async reset
+ input logic app_clk ,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [3:0] reg_addr,
+ input logic [7:0] reg_wdata,
+ input logic reg_be,
+
+ // Outputs
+ output logic [7:0] reg_rdata,
+ output logic reg_ack,
+
+ // Pad Control
+ input logic rxd,
+ output logic txd
+
+ );
+
+
+
+
+parameter W = 8'd8;
+parameter DP = 8'd16;
+parameter AW = (DP == 2) ? 1 :
+ (DP == 4) ? 2 :
+ (DP == 8) ? 3 :
+ (DP == 16) ? 4 :
+ (DP == 32) ? 5 :
+ (DP == 64) ? 6 :
+ (DP == 128) ? 7 :
+ (DP == 256) ? 8 : 0;
+
+
+
+// Wire Declaration
+wire app_reset_n ;
+wire line_reset_n ;
+
+wire [W-1: 0] tx_fifo_rd_data;
+wire [W-1: 0] rx_fifo_wr_data;
+wire [W-1: 0] app_rxfifo_data;
+wire [W-1: 0] app_txfifo_data;
+wire [1 : 0] error_ind;
+
+// Wire
+wire cfg_tx_enable ; // Tx Enable
+wire cfg_rx_enable ; // Rx Enable
+wire cfg_stop_bit ; // 0 -> 1 Stop, 1 -> 2 Stop
+wire [1:0] cfg_pri_mod ; // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+
+wire frm_error_o ; // framing error
+wire par_error_o ; // par error
+wire rx_fifo_full_err_o ; // rx fifo full error
+
+wire [11:0] cfg_baud_16x ; // 16x Baud clock generation
+wire rx_fifo_wr_full ;
+wire tx_fifo_rd_empty ;
+wire tx_fifo_rd ;
+wire app_rxfifo_empty ;
+wire app_rxfifo_rd_en ;
+wire app_tx_fifo_full ;
+wire rx_fifo_wr ;
+wire tx_fifo_wr_en ;
+wire [AW:0] tx_fifo_fspace ; // Total Tx fifo Free Space
+wire [AW:0] rx_fifo_dval ; // Total Rx fifo Data Available
+wire si_ss ;
+
+
+
+uart_cfg u_cfg (
+
+ . mclk (app_clk),
+ . reset_n (app_reset_n),
+
+ // Reg Bus Interface Signal
+ . reg_cs (reg_cs),
+ . reg_wr (reg_wr),
+ . reg_addr (reg_addr),
+ . reg_wdata (reg_wdata),
+ . reg_be (reg_be),
+
+ // Outputs
+ . reg_rdata (reg_rdata),
+ . reg_ack (reg_ack),
+
+
+ // configuration
+ . cfg_tx_enable (cfg_tx_enable),
+ . cfg_rx_enable (cfg_rx_enable),
+ . cfg_stop_bit (cfg_stop_bit),
+ . cfg_pri_mod (cfg_pri_mod),
+
+ . cfg_baud_16x (cfg_baud_16x),
+
+ . tx_fifo_full (app_tx_fifo_full),
+ .tx_fifo_fspace (tx_fifo_fspace ),
+ . tx_fifo_wr_en (tx_fifo_wr_en),
+ . tx_fifo_data (app_txfifo_data),
+
+ . rx_fifo_empty (app_rxfifo_empty),
+ .rx_fifo_dval (rx_fifo_dval ),
+ . rx_fifo_rd_en (app_rxfifo_rd_en),
+ . rx_fifo_data (app_rxfifo_data) ,
+
+ . frm_error_o (frm_error_o),
+ . par_error_o (par_error_o),
+ . rx_fifo_full_err_o (rx_fifo_full_err_o)
+
+ );
+
+
+//##############################################################
+// 16x Baud clock generation
+// Example: to generate 19200 Baud clock from 50Mhz Link clock
+// 50 * 1000 * 1000 / (2 + cfg_baud_16x) = 19200 * 16
+// cfg_baud_16x = 0xA0 (160)
+//###############################################################
+
+wire line_clk_16x_in;
+
+// OpenSource CTS tool does not work with buffer as source point
+// changed buf to max with select tied=0
+//ctech_clk_buf u_lineclk_buf (.A(line_clk_16x_in), .X(line_clk_16x));
+ctech_mux2x1 u_lineclk_buf (.A0(line_clk_16x_in), .A1(1'b0), .S(1'b0), .X(line_clk_16x));
+
+clk_ctl #(11) u_clk_ctl (
+ // Outputs
+ .clk_o (line_clk_16x_in),
+
+ // Inputs
+ .mclk (app_clk),
+ .reset_n (app_reset_n),
+ .clk_div_ratio (cfg_baud_16x)
+ );
+
+//###################################
+// Application Reset Synchronization
+//###################################
+reset_sync u_app_rst (
+ .scan_mode (1'b0 ),
+ .dclk (app_clk ), // Destination clock domain
+ .arst_n (arst_n ), // active low async reset
+ .srst_n (app_reset_n )
+ );
+
+//###################################
+// Line Reset Synchronization
+//###################################
+reset_sync u_line_rst (
+ .scan_mode (1'b0 ),
+ .dclk (line_clk_16x ), // Destination clock domain
+ .arst_n (arst_n ), // active low async reset
+ .srst_n (line_reset_n )
+ );
+
+
+uart_txfsm u_txfsm (
+ .reset_n ( line_reset_n ),
+ .baud_clk_16x ( line_clk_16x ),
+
+ .cfg_tx_enable ( cfg_tx_enable ),
+ .cfg_stop_bit ( cfg_stop_bit ),
+ .cfg_pri_mod ( cfg_pri_mod ),
+
+ // FIFO control signal
+ .fifo_empty ( tx_fifo_rd_empty ),
+ .fifo_rd ( tx_fifo_rd ),
+ .fifo_data ( tx_fifo_rd_data ),
+
+ // Line Interface
+ .so ( txd )
+ );
+
+
+uart_rxfsm u_rxfsm (
+ .reset_n ( line_reset_n ),
+ .baud_clk_16x ( line_clk_16x ) ,
+
+ .cfg_rx_enable ( cfg_rx_enable ),
+ .cfg_stop_bit ( cfg_stop_bit ),
+ .cfg_pri_mod ( cfg_pri_mod ),
+
+ .error_ind ( error_ind ),
+
+ // FIFO control signal
+ .fifo_aval ( !rx_fifo_wr_full ),
+ .fifo_wr ( rx_fifo_wr ),
+ .fifo_data ( rx_fifo_wr_data ),
+
+ // Line Interface
+ .si (si_ss )
+ );
+
+async_fifo_th #(W,DP,0,0) u_rxfifo (
+ .wr_clk (line_clk_16x ),
+ .wr_reset_n (line_reset_n ),
+ .wr_en (rx_fifo_wr ),
+ .wr_data (rx_fifo_wr_data ),
+ .full (rx_fifo_wr_full ), // sync'ed to wr_clk
+ .wr_total_free_space( ),
+
+ .rd_clk (app_clk ),
+ .rd_reset_n (app_reset_n ),
+ .rd_en (app_rxfifo_rd_en ),
+ .empty (app_rxfifo_empty ), // sync'ed to rd_clk
+ .rd_total_aval (rx_fifo_dval ),
+ .rd_data (app_rxfifo_data )
+ );
+
+async_fifo_th #(W,DP,0,0) u_txfifo (
+ .wr_clk (app_clk ),
+ .wr_reset_n (app_reset_n ),
+ .wr_en (tx_fifo_wr_en ),
+ .wr_data (app_txfifo_data ),
+ .full (app_tx_fifo_full ), // sync'ed to wr_clk
+ .wr_total_free_space(tx_fifo_fspace ),
+
+ .rd_clk (line_clk_16x ),
+ .rd_reset_n (line_reset_n ),
+ .rd_en (tx_fifo_rd ),
+ .empty (tx_fifo_rd_empty ), // sync'ed to rd_clk
+ .rd_total_aval ( ),
+ .rd_data (tx_fifo_rd_data )
+ );
+
+
+double_sync_low u_si_sync (
+ .in_data (rxd ),
+ .out_clk (line_clk_16x ),
+ .out_rst_n (line_reset_n ),
+ .out_data (si_ss )
+ );
+
+wire frm_error = (error_ind == 2'b01);
+wire par_error = (error_ind == 2'b10);
+wire rx_fifo_full_err = (error_ind == 2'b11);
+
+double_sync_low u_frm_err (
+ .in_data ( frm_error ),
+ .out_clk ( app_clk ),
+ .out_rst_n ( app_reset_n ),
+ .out_data ( frm_error_o )
+ );
+
+double_sync_low u_par_err (
+ .in_data ( par_error ),
+ .out_clk ( app_clk ),
+ .out_rst_n ( app_reset_n ),
+ .out_data ( par_error_o )
+ );
+
+double_sync_low u_rxfifo_err (
+ .in_data ( rx_fifo_full_err ),
+ .out_clk ( app_clk ),
+ .out_rst_n ( app_reset_n ),
+ .out_data ( rx_fifo_full_err_o )
+ );
+
+
+endmodule
diff --git a/verilog/rtl/uart/src/uart_rxfsm.sv b/verilog/rtl/uart/src/uart_rxfsm.sv
new file mode 100644
index 0000000..58916e6
--- /dev/null
+++ b/verilog/rtl/uart/src/uart_rxfsm.sv
@@ -0,0 +1,221 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART RX FSM ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th June 2021, Dinesh A ////
+//// 1. initial version picked from ////
+//// http://www.opencores.org/cores/oms8051mini ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_rxfsm (
+ reset_n ,
+ baud_clk_16x ,
+
+ cfg_rx_enable ,
+ cfg_stop_bit ,
+ cfg_pri_mod ,
+
+ error_ind ,
+
+ // FIFO control signal
+ fifo_aval ,
+ fifo_wr ,
+ fifo_data ,
+
+ // Line Interface
+ si
+ );
+
+
+input reset_n ; // active low reset signal
+input baud_clk_16x ; // baud clock-16x
+
+input cfg_rx_enable ; // transmit interface enable
+input cfg_stop_bit ; // stop bit
+ // 0 --> 1 stop, 1 --> 2 Stop
+input [1:0] cfg_pri_mod ;// Priority Mode
+ // 2'b00 --> None
+ // 2'b10 --> Even priority
+ // 2'b11 --> Odd priority
+
+output [1:0] error_ind ; // 2'b00 --> Normal
+ // 2'b01 --> framing error
+ // 2'b10 --> parity error
+ // 2'b11 --> fifo full
+//--------------------------------------
+// FIFO control signal
+//--------------------------------------
+input fifo_aval ; // fifo empty
+output fifo_wr ; // fifo write, assumed no back to back write
+output [7:0] fifo_data ; // fifo write data
+
+// Line Interface
+input si ; // rxd pin
+
+
+
+reg [7:0] fifo_data ; // fifo write data
+reg fifo_wr ; // fifo write
+reg [1:0] error_ind ;
+reg [2:0] cnt ;
+reg [3:0] offset ; // free-running counter from 0 - 15
+reg [3:0] rxpos ; // stable rx position
+reg [2:0] rxstate ;
+
+parameter idle_st = 3'b000;
+parameter xfr_start = 3'b001;
+parameter xfr_data_st = 3'b010;
+parameter xfr_pri_st = 3'b011;
+parameter xfr_stop_st1 = 3'b100;
+parameter xfr_stop_st2 = 3'b101;
+
+
+always @(negedge reset_n or posedge baud_clk_16x) begin
+ if(reset_n == 0) begin
+ rxstate <= 3'b0;
+ offset <= 4'b0;
+ rxpos <= 4'b0;
+ cnt <= 3'b0;
+ error_ind <= 2'b0;
+ fifo_wr <= 1'b0;
+ fifo_data <= 8'h0;
+ end
+ else begin
+ offset <= offset + 1;
+ case(rxstate)
+ idle_st : begin
+ if(!si) begin // Start indication
+ if(fifo_aval && cfg_rx_enable) begin
+ rxstate <= xfr_start;
+ cnt <= 0;
+ rxpos <= offset + 8; // Assign center rxoffset
+ error_ind <= 2'b00;
+ end
+ else begin
+ error_ind <= 2'b11; // fifo full error indication
+ end
+ end else begin
+ error_ind <= 2'b00; // Reset Error
+ end
+ end
+ xfr_start : begin
+ // Make Sure that minimum 8 cycle low is detected
+ if(cnt < 7 && si) begin // Start indication
+ rxstate <= idle_st;
+ end
+ else if(cnt == 7 && !si) begin // Start indication
+ rxstate <= xfr_data_st;
+ cnt <= 0;
+ end else begin
+ cnt <= cnt +1;
+ end
+ end
+ xfr_data_st : begin
+ if(rxpos == offset) begin
+ fifo_data[cnt] <= si;
+ cnt <= cnt+1;
+ if(cnt == 7) begin
+ fifo_wr <= 1;
+ if(cfg_pri_mod == 2'b00) // No Priority
+ rxstate <= xfr_stop_st1;
+ else rxstate <= xfr_pri_st;
+ end
+ end
+ end
+ xfr_pri_st : begin
+ fifo_wr <= 0;
+ if(rxpos == offset) begin
+ if(cfg_pri_mod == 2'b10) // even priority
+ if( si != ^fifo_data) error_ind <= 2'b10;
+ else // Odd Priority
+ if( si != ~(^fifo_data)) error_ind <= 2'b10;
+ rxstate <= xfr_stop_st1;
+ end
+ end
+ xfr_stop_st1 : begin
+ fifo_wr <= 0;
+ if(rxpos == offset) begin
+ if(si) begin
+ if(cfg_stop_bit) // Two Stop bit
+ rxstate <= xfr_stop_st2;
+ else
+ rxstate <= idle_st;
+ end else begin // Framing error
+ error_ind <= 2'b01;
+ rxstate <= idle_st;
+ end
+ end
+ end
+ xfr_stop_st2 : begin
+ if(rxpos == offset) begin
+ if(si) begin
+ rxstate <= idle_st;
+ end else begin // Framing error
+ error_ind <= 2'b01;
+ rxstate <= idle_st;
+ end
+ end
+ end
+ default: rxstate <= idle_st;
+ endcase
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/uart/src/uart_txfsm.sv b/verilog/rtl/uart/src/uart_txfsm.sv
new file mode 100644
index 0000000..ad6507e
--- /dev/null
+++ b/verilog/rtl/uart/src/uart_txfsm.sv
@@ -0,0 +1,190 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART TX FSM ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th June 2021, Dinesh A ////
+//// 1. initial version picked from ////
+//// http://www.opencores.org/cores/oms8051mini ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module uart_txfsm (
+ reset_n ,
+ baud_clk_16x ,
+
+ cfg_tx_enable ,
+ cfg_stop_bit ,
+ cfg_pri_mod ,
+
+ // FIFO control signal
+ fifo_empty ,
+ fifo_rd ,
+ fifo_data ,
+
+ // Line Interface
+ so
+ );
+
+
+input reset_n ; // active low reset signal
+input baud_clk_16x ; // baud clock-16x
+
+input cfg_tx_enable ; // transmit interface enable
+input cfg_stop_bit ; // stop bit
+ // 0 --> 1 stop, 1 --> 2 Stop
+input [1:0] cfg_pri_mod ;// Priority Mode
+ // 2'b00 --> None
+ // 2'b10 --> Even priority
+ // 2'b11 --> Odd priority
+
+//--------------------------------------
+// FIFO control signal
+//--------------------------------------
+input fifo_empty ; // fifo empty
+output fifo_rd ; // fifo read, assumed no back to back read
+input [7:0] fifo_data ; // fifo read data
+
+// Line Interface
+output so ; // txd pin
+
+
+reg [2:0] txstate ; // tx state
+reg so ; // txd pin
+reg [7:0] txdata ; // local txdata
+reg fifo_rd ; // Fifo read enable
+reg [2:0] cnt ; // local data cont
+reg [3:0] divcnt ; // clock div count
+
+parameter idle_st = 3'b000;
+parameter xfr_data_st = 3'b001;
+parameter xfr_pri_st = 3'b010;
+parameter xfr_stop_st1 = 3'b011;
+parameter xfr_stop_st2 = 3'b100;
+
+
+always @(negedge reset_n or posedge baud_clk_16x)
+begin
+ if(reset_n == 1'b0) begin
+ txstate <= idle_st;
+ so <= 1'b1;
+ cnt <= 3'b0;
+ txdata <= 8'h0;
+ fifo_rd <= 1'b0;
+ divcnt <= 4'b0;
+ end
+ else begin
+ divcnt <= divcnt+1;
+ if(divcnt == 4'b0000) begin // Do at once in 16 clock
+ case(txstate)
+ idle_st : begin
+ if(!fifo_empty && cfg_tx_enable) begin
+ so <= 1'b0 ; // Start bit
+ cnt <= 3'b0;
+ fifo_rd <= 1'b1;
+ txdata <= fifo_data;
+ txstate <= xfr_data_st;
+ end
+ end
+
+ xfr_data_st : begin
+ fifo_rd <= 1'b0;
+ so <= txdata[cnt];
+ cnt <= cnt+1;
+ if(cnt == 7) begin
+ if(cfg_pri_mod == 2'b00) begin // No Priority
+ txstate <= xfr_stop_st1;
+ end
+ else begin
+ txstate <= xfr_pri_st;
+ end
+ end
+ end
+
+ xfr_pri_st : begin
+ if(cfg_pri_mod == 2'b10) // even priority
+ so <= ^txdata;
+ else begin // Odd Priority
+ so <= ~(^txdata);
+ end
+ txstate <= xfr_stop_st1;
+ end
+
+ xfr_stop_st1 : begin // First Stop Bit
+ so <= 1;
+ if(cfg_stop_bit == 0) // 1 Stop Bit
+ txstate <= idle_st;
+ else // 2 Stop Bit
+ txstate <= xfr_stop_st2;
+ end
+
+ xfr_stop_st2 : begin // Second Stop Bit
+ so <= 1;
+ txstate <= idle_st;
+ end
+ default: txstate <= idle_st;
+ endcase
+ end
+ else begin
+ fifo_rd <= 1'b0;
+ end
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/uart2wb/src/run_verilog b/verilog/rtl/uart2wb/src/run_verilog
new file mode 100644
index 0000000..c689827
--- /dev/null
+++ b/verilog/rtl/uart2wb/src/run_verilog
@@ -0,0 +1 @@
+iverilog uart2wb.sv uart2_core.sv uart_msg_handler.v ../../uart/src/uart_rxfsm.sv ../../uart/src/uart_txfsm.sv ../../lib/double_sync_low.v ../../lib/clk_ctl.v ../../lib/reset_sync.sv
diff --git a/verilog/rtl/uart2wb/src/uart2_core.sv b/verilog/rtl/uart2wb/src/uart2_core.sv
new file mode 100755
index 0000000..78daa1a
--- /dev/null
+++ b/verilog/rtl/uart2wb/src/uart2_core.sv
@@ -0,0 +1,192 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Tubo 8051 cores UART Interface Module ////
+//// ////
+//// This file is part of the Turbo 8051 cores project ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//// Description ////
+//// Turbo 8051 definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+module uart2_core (
+ input wire arst_n , // Async reset
+ input wire app_clk , // Application clock
+
+
+ // configuration control
+ input wire cfg_tx_enable , // Enable Transmit Path
+ input wire cfg_rx_enable , // Enable Received Path
+ input wire cfg_stop_bit , // 0 -> 1 Start , 1 -> 2 Stop Bits
+ input wire [1:0] cfg_pri_mod , // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+ input wire [11:0]cfg_baud_16x , // 16x baud rate control
+
+ // TX PATH Information
+ input wire tx_data_avail , // Indicate valid TXD Data
+ output wire tx_rd , // Indicate TXD Data Been Read
+ input wire [7:0]tx_data , // Indicate TXD Data Been
+
+
+ // RXD Information
+ input wire rx_ready , // Indicate Ready to accept the Read Data
+ output wire rx_wr , // Valid RXD Data
+ output wire [7:0]rx_data , // RXD Data
+
+ // Status information
+ output wire frm_error , // framing error
+ output wire par_error , // par error
+
+ output wire baud_clk_16x , // 16x Baud clock
+ output wire line_reset_n , // Reset sync to 16x Baud clock
+
+ // Line Interface
+ input wire rxd , // uart rxd
+ output wire txd // uart txd
+
+ );
+
+
+
+//---------------------------------
+// Global Dec
+// ---------------------------------
+
+// Wire Declaration
+
+wire [1 : 0] error_ind ;
+wire si_ss ;
+
+// OpenSource CTS tool does not work with buffer as source point
+// changed buf to max with select tied=0
+//ctech_clk_buf u_lineclk_buf (.A(line_clk_16x_in), .X(line_clk_16x));
+wire line_clk_16x;
+ctech_mux2x1 u_uart_clk (.A0(line_clk_16x), .A1(1'b0), .S(1'b0), .X(baud_clk_16x));
+
+// 16x Baud clock generation
+// Example: to generate 19200 Baud clock from 50Mhz Link clock
+// 50 * 1000 * 1000 / (2 + cfg_baud_16x) = 19200 * 16
+// cfg_baud_16x = 0xA0 (160)
+
+clk_ctl #(11) u_clk_ctl (
+ // Outputs
+ .clk_o (line_clk_16x),
+
+ // Inputs
+ .mclk (app_clk),
+ .reset_n (arst_n),
+ .clk_div_ratio (cfg_baud_16x)
+ );
+
+
+//###################################
+// Line Reset Synchronization
+//###################################
+reset_sync u_line_rst (
+ .scan_mode (1'b0 ),
+ .dclk (baud_clk_16x ), // Destination clock domain
+ .arst_n (arst_n ), // active low async reset
+ .srst_n (line_reset_n )
+ );
+
+
+
+uart_txfsm u_txfsm (
+ . reset_n ( line_reset_n ),
+ . baud_clk_16x ( baud_clk_16x ),
+
+ . cfg_tx_enable ( cfg_tx_enable ),
+ . cfg_stop_bit ( cfg_stop_bit ),
+ . cfg_pri_mod ( cfg_pri_mod ),
+
+ // FIFO control signal
+ . fifo_empty ( !tx_data_avail ),
+ . fifo_rd ( tx_rd ),
+ . fifo_data ( tx_data ),
+
+ // Line Interface
+ . so ( txd )
+ );
+
+
+uart_rxfsm u_rxfsm (
+ . reset_n ( line_reset_n ),
+ . baud_clk_16x ( baud_clk_16x ) ,
+
+ . cfg_rx_enable ( cfg_rx_enable ),
+ . cfg_stop_bit ( cfg_stop_bit ),
+ . cfg_pri_mod ( cfg_pri_mod ),
+
+ . error_ind ( error_ind ),
+
+ // FIFO control signal
+ . fifo_aval ( rx_ready ),
+ . fifo_wr ( rx_wr ),
+ . fifo_data ( rx_data ),
+
+ // Line Interface
+ . si (si_ss )
+ );
+
+// Double Sync RXD
+double_sync_low u_rxd_sync (
+ .in_data (rxd ),
+ .out_clk (baud_clk_16x ),
+ .out_rst_n (line_reset_n ),
+ .out_data (si_ss )
+ );
+
+
+assign frm_error = (error_ind == 2'b01);
+assign par_error = (error_ind == 2'b10);
+
+
+
+endmodule
diff --git a/verilog/rtl/uart2wb/src/uart2wb.sv b/verilog/rtl/uart2wb/src/uart2wb.sv
new file mode 100755
index 0000000..0bf50b3
--- /dev/null
+++ b/verilog/rtl/uart2wb/src/uart2wb.sv
@@ -0,0 +1,229 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART2WB Top Module ////
+//// ////
+//// Description ////
+//// 1. uart_core ////
+//// 2. uart_msg_handler ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart2wb (
+ input wire arst_n , // sync reset
+ input wire app_clk , // sys clock
+
+ // configuration control
+ input wire cfg_tx_enable , // Enable Transmit Path
+ input wire cfg_rx_enable , // Enable Received Path
+ input wire cfg_stop_bit , // 0 -> 1 Start , 1 -> 2 Stop Bits
+ input wire [1:0] cfg_pri_mod , // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+ input wire [11:0] cfg_baud_16x , // 16x Baud clock generation
+
+ // Master Port
+ output wire wbm_cyc_o , // strobe/request
+ output wire wbm_stb_o , // strobe/request
+ output wire [31:0] wbm_adr_o , // address
+ output wire wbm_we_o , // write
+ output wire [31:0] wbm_dat_o , // data output
+ output wire [3:0] wbm_sel_o , // byte enable
+ input wire [31:0] wbm_dat_i , // data input
+ input wire wbm_ack_i , // acknowlegement
+ input wire wbm_err_i , // error
+
+ // Status information
+ output wire frm_error , // framing error
+ output wire par_error , // par error
+
+ output wire baud_clk_16x , // 16x Baud clock
+
+ // Line Interface
+ input wire rxd , // uart rxd
+ output wire txd // uart txd
+
+ );
+
+
+
+
+
+
+//-------------------------------------
+//---------------------------------------
+// Control Unit interface
+// --------------------------------------
+
+wire [31:0] reg_addr ; // Register Address
+wire [31:0] reg_wdata ; // Register Wdata
+wire reg_req ; // Register Request
+wire reg_wr ; // 1 -> write; 0 -> read
+wire reg_ack ; // Register Ack
+wire [31:0] reg_rdata ;
+//--------------------------------------
+// TXD Path
+// -------------------------------------
+wire tx_data_avail ; // Indicate valid TXD Data
+wire [7:0] tx_data ; // TXD Data to be transmited
+wire tx_rd ; // Indicate TXD Data Been Read
+
+
+//--------------------------------------
+// RXD Path
+// -------------------------------------
+wire rx_ready ; // Indicate Ready to accept the Read Data
+wire [7:0] rx_data ; // RXD Data
+wire rx_wr ; // Valid RXD Data
+
+wire line_reset_n ;
+
+assign wbm_cyc_o = wbm_stb_o;
+
+
+// Async App clock to Uart clock handling
+
+async_reg_bus #(.AW(32), .DW(32),.BEW(4))
+ u_async_reg_bus (
+ // Initiator declartion
+ .in_clk (baud_clk_16x),
+ .in_reset_n (line_reset_n),
+ // Reg Bus Master
+ // outputs
+ .in_reg_rdata (reg_rdata),
+ .in_reg_ack (reg_ack),
+ .in_reg_timeout (),
+
+ // Inputs
+ .in_reg_cs (reg_req),
+ .in_reg_addr (reg_addr),
+ .in_reg_wdata (reg_wdata),
+ .in_reg_wr (reg_wr),
+ .in_reg_be (4'hF), // No byte enable based support
+
+ // Target Declaration
+ .out_clk (app_clk),
+ .out_reset_n (arst_n),
+ // Reg Bus Slave
+ // output
+ .out_reg_cs (wbm_stb_o),
+ .out_reg_addr (wbm_adr_o),
+ .out_reg_wdata (wbm_dat_o),
+ .out_reg_wr (wbm_we_o),
+ .out_reg_be (wbm_sel_o),
+
+ // Inputs
+ .out_reg_rdata (wbm_dat_i),
+ .out_reg_ack (wbm_ack_i)
+ );
+
+
+uart2_core u_core (
+ .arst_n (arst_n) ,
+ .app_clk (app_clk) ,
+
+ // configuration control
+ .cfg_tx_enable (cfg_tx_enable) ,
+ .cfg_rx_enable (cfg_rx_enable) ,
+ .cfg_stop_bit (cfg_stop_bit) ,
+ .cfg_pri_mod (cfg_pri_mod) ,
+ .cfg_baud_16x (cfg_baud_16x) ,
+
+ // TXD Information
+ .tx_data_avail (tx_data_avail) ,
+ .tx_rd (tx_rd) ,
+ .tx_data (tx_data) ,
+
+
+ // RXD Information
+ .rx_ready (rx_ready) ,
+ .rx_wr (rx_wr) ,
+ .rx_data (rx_data) ,
+
+ // Status information
+ .frm_error (frm_error) ,
+ .par_error (par_error) ,
+
+ .baud_clk_16x (baud_clk_16x) ,
+ .line_reset_n (line_reset_n),
+
+ // Line Interface
+ .rxd (rxd) ,
+ .txd (txd)
+
+ );
+
+
+
+uart_msg_handler u_msg (
+ .reset_n (arst_n ) ,
+ .sys_clk (baud_clk_16x ) ,
+
+
+ // UART-TX Information
+ .tx_data_avail (tx_data_avail) ,
+ .tx_rd (tx_rd) ,
+ .tx_data (tx_data) ,
+
+
+ // UART-RX Information
+ .rx_ready (rx_ready) ,
+ .rx_wr (rx_wr) ,
+ .rx_data (rx_data) ,
+
+ // Towards Control Unit
+ .reg_addr (reg_addr),
+ .reg_wr (reg_wr),
+ .reg_wdata (reg_wdata),
+ .reg_req (reg_req),
+ .reg_ack (reg_ack),
+ .reg_rdata (reg_rdata)
+
+ );
+
+endmodule
diff --git a/verilog/rtl/uart2wb/src/uart_msg_handler.v b/verilog/rtl/uart2wb/src/uart_msg_handler.v
new file mode 100755
index 0000000..471ff88
--- /dev/null
+++ b/verilog/rtl/uart2wb/src/uart_msg_handler.v
@@ -0,0 +1,376 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART Message Handler Module ////
+//// ////
+//// This file is part of the uart2spi cores project ////
+//// http://www.opencores.org/cores/uart2spi/ ////
+//// ////
+//// Description ////
+//// Uart Message Handler definitions. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_msg_handler (
+ reset_n ,
+ sys_clk ,
+
+
+ // UART-TX Information
+ tx_data_avail,
+ tx_rd,
+ tx_data,
+
+
+ // UART-RX Information
+ rx_ready,
+ rx_wr,
+ rx_data,
+
+ // Towards Register Interface
+ reg_addr,
+ reg_wr,
+ reg_wdata,
+ reg_req,
+ reg_ack,
+ reg_rdata
+
+ );
+
+
+// Define the Message Hanlde States
+`define IDLE 4'h0
+`define IDLE_TX_MSG1 4'h1
+`define IDLE_TX_MSG2 4'h2
+`define RX_CMD_PHASE 4'h3
+`define ADR_PHASE 4'h4
+`define WR_DATA_PHASE 4'h5
+`define SEND_WR_REQ 4'h6
+`define SEND_RD_REQ 4'h7
+`define SEND_RD_DATA 4'h8
+`define TX_MSG 4'h9
+
+`define BREAK_CHAR 8'h0A
+
+//---------------------------------
+// Global Dec
+// ---------------------------------
+
+input reset_n ; // line reset
+input sys_clk ; // line clock
+
+
+//--------------------------------------
+// UART TXD Path
+// -------------------------------------
+output tx_data_avail ; // Indicate valid TXD Data available
+output [7:0] tx_data ; // TXD Data to be transmited
+input tx_rd ; // Indicate TXD Data Been Read
+
+
+//--------------------------------------
+// UART RXD Path
+// -------------------------------------
+output rx_ready ; // Indicate Ready to accept the Read Data
+input [7:0] rx_data ; // RXD Data
+input rx_wr ; // Valid RXD Data
+
+//---------------------------------------
+// Control Unit interface
+// --------------------------------------
+
+output [31:0] reg_addr ; // Operend-1
+output [31:0] reg_wdata ; // Operend-2
+output reg_req ; // Register Request
+output reg_wr ; // 1 -> write; 0 -> read
+input reg_ack ; // Register Ack
+input [31:0] reg_rdata ;
+
+// Local Wire/Register Decleration
+//
+//
+reg tx_data_avail ;
+reg [7:0] tx_data ;
+reg [16*8-1:0] TxMsgBuf ; // 16 Byte Tx Message Buffer
+reg [4:0] TxMsgSize ;
+reg [4:0] RxMsgCnt ; // Count the Receive Message Count
+reg [3:0] State ;
+reg [3:0] NextState ;
+reg [15:0] cmd ; // command
+reg [31:0] reg_addr ; // reg_addr
+reg [31:0] reg_wdata ; // reg_addr
+reg reg_wr ; // 1 -> Reg Write request, 0 -> Read Requestion
+reg reg_req ; // 1 -> Register request
+
+
+wire rx_ready = 1;
+/****************************************************************
+* UART Message Hanlding Steps
+*
+* 1. On Reset Or Unknown command, Send the Default Message
+* Select Option:
+* wr <addr> <data>
+* rd <addr>
+* 2. Wait for User command <wr/rd>
+* 3. On <wr> command move to write address phase;
+* phase
+* A. After write address phase move to write data phase
+* B. After write data phase, once user press \r command ; send register req
+* and write request and address + data
+* C. On receiving register ack response; send <success> message back and move
+* to state-2
+* 3. On <rd> command move to read address phase;
+* A. After read address phase , once user press '\r' command; send
+* register req , read request
+* C. On receiving register ack response; send <response + read_data> message and move
+* to state-2
+* *****************************************************************/
+
+always @(negedge reset_n or posedge sys_clk)
+begin
+ if(reset_n == 1'b0) begin
+ tx_data_avail <= 0;
+ reg_req <= 0;
+ reg_addr <= 0;
+ reg_wr <= 1'b0; // Read request
+ reg_wdata <= 0;
+ State <= `IDLE;
+ NextState <= `IDLE;
+ end else begin
+ case(State)
+ // Send Default Message
+ `IDLE: begin
+ TxMsgBuf <= "Command Format:\n"; // Align to 16 character format by appending space character
+ TxMsgSize <= 16;
+ tx_data_avail <= 0;
+ State <= `TX_MSG;
+ NextState <= `IDLE_TX_MSG1;
+ end
+
+ // Send Default Message (Contd..)
+ `IDLE_TX_MSG1: begin
+ TxMsgBuf <= "wm <ad> <data>\n "; // Align to 16 character format by appending space character
+ TxMsgSize <= 15;
+ tx_data_avail <= 0;
+ State <= `TX_MSG;
+ NextState <= `IDLE_TX_MSG2;
+ end
+
+ // Send Default Message (Contd..)
+ `IDLE_TX_MSG2: begin
+ TxMsgBuf <= "rm <ad>\n>> "; // Align to 16 character format by appending space character
+ TxMsgSize <= 10;
+ tx_data_avail <= 0;
+ RxMsgCnt <= 0;
+ State <= `TX_MSG;
+ NextState <= `RX_CMD_PHASE;
+ end
+
+ // Wait for Response
+ `RX_CMD_PHASE: begin
+ if(rx_wr == 1) begin
+ //if(RxMsgCnt == 0 && rx_data == " ") begin // Ignore the same
+ if(RxMsgCnt == 0 && rx_data == 8'h20) begin // Ignore the same
+ //end else if(RxMsgCnt > 0 && rx_data == " ") begin // Check the command
+ end else if(RxMsgCnt > 0 && rx_data == 8'h20) begin // Check the command
+ reg_addr <= 0;
+ RxMsgCnt <= 0;
+ //if(cmd == "wm") begin
+ if(cmd == 16'h776D) begin
+ State <= `ADR_PHASE;
+ //end else if(cmd == "rm") begin
+ end else if(cmd == 16'h726D) begin
+
+ State <= `ADR_PHASE;
+ end else begin // Unknow command
+ State <= `IDLE;
+ end
+ //end else if(rx_data == "\n") begin // Error State
+ end else if(rx_data == `BREAK_CHAR) begin // Error State
+ State <= `IDLE;
+ end
+ else begin
+ cmd <= (cmd << 8) | rx_data ;
+ RxMsgCnt <= RxMsgCnt+1;
+ end
+ end
+ end
+ // Write Address Phase
+ `ADR_PHASE: begin
+ if(rx_wr == 1) begin
+ //if(RxMsgCnt == 0 && rx_data == " ") begin // Ignore the Space character
+ if(RxMsgCnt == 0 && rx_data == 8'h20) begin // Ignore the Space character
+ end else if(RxMsgCnt > 0 && (rx_data == 8'h20 || rx_data == `BREAK_CHAR)) begin // Move to write data phase
+ //if(RxMsgCnt > 0 && "wm" && rx_data == " ") begin // Move to write data phase
+ if(cmd == 16'h776D && rx_data == 8'h20) begin // Move to write data phase
+ reg_wdata <= 0;
+ State <= `WR_DATA_PHASE;
+ // end else if(RxMsgCnt > 0 && "rm" && rx_data == "\n") begin // Move to read data phase
+ end else if(cmd == 16'h726D && rx_data == `BREAK_CHAR) begin // Move to read data phase
+ reg_wr <= 1'b0; // Read request
+ reg_req <= 1'b1; // Reg Request
+ State <= `SEND_RD_REQ;
+ end else begin // Unknow command
+ State <= `IDLE;
+ end
+ //end else if(rx_data == "\n") begin // Error State
+ end else if(rx_data == `BREAK_CHAR) begin // Error State
+ State <= `IDLE;
+ end else begin
+ reg_addr <= (reg_addr << 4) | char2hex(rx_data);
+ RxMsgCnt <= RxMsgCnt+1;
+ end
+ end
+ end
+ // Write Data Phase
+ `WR_DATA_PHASE: begin
+ if(rx_wr == 1) begin
+ //if(rx_data == " ") begin // Ignore the Space character
+ if(rx_data == 8'h20) begin // Ignore the Space character
+ //end else if(rx_data == "\n") begin // Error State
+ end else if(rx_data == `BREAK_CHAR) begin // Error State
+ State <= `SEND_WR_REQ;
+ reg_wr <= 1'b1; // Write request
+ reg_req <= 1'b1;
+ end else begin // A to F
+ reg_wdata <= (reg_wdata << 4) | char2hex(rx_data);
+ end
+ end
+ end
+ `SEND_WR_REQ: begin
+ if(reg_ack) begin
+ reg_req <= 1'b0;
+ TxMsgBuf <= "cmd success\n>> "; // Align to 16 character format by appending space character
+ TxMsgSize <= 14;
+ tx_data_avail <= 0;
+ State <= `TX_MSG;
+ NextState <= `RX_CMD_PHASE;
+ end
+ end
+
+ `SEND_RD_REQ: begin
+ if(reg_ack) begin
+ reg_req <= 1'b0;
+ TxMsgBuf <= "Response: "; // Align to 16 character format by appending space character
+ TxMsgSize <= 10;
+ tx_data_avail <= 0;
+ State <= `TX_MSG;
+ NextState <= `SEND_RD_DATA;
+ end
+ end
+ `SEND_RD_DATA: begin // Wait for Operation Completion
+ TxMsgBuf[16*8-1:15*8] <= hex2char(reg_rdata[31:28]);
+ TxMsgBuf[15*8-1:14*8] <= hex2char(reg_rdata[27:24]);
+ TxMsgBuf[14*8-1:13*8] <= hex2char(reg_rdata[23:20]);
+ TxMsgBuf[13*8-1:12*8] <= hex2char(reg_rdata[19:16]);
+ TxMsgBuf[12*8-1:11*8] <= hex2char(reg_rdata[15:12]);
+ TxMsgBuf[11*8-1:10*8] <= hex2char(reg_rdata[11:8]);
+ TxMsgBuf[10*8-1:9*8] <= hex2char(reg_rdata[7:4]);
+ TxMsgBuf[9*8-1:8*8] <= hex2char(reg_rdata[3:0]);
+ TxMsgBuf[8*8-1:7*8] <= "\n";
+ TxMsgSize <= 9;
+ tx_data_avail <= 0;
+ State <= `TX_MSG;
+ NextState <= `RX_CMD_PHASE;
+ end
+
+ // Send Default Message (Contd..)
+ `TX_MSG: begin
+ tx_data_avail <= 1;
+ tx_data <= TxMsgBuf[16*8-1:15*8];
+ if(TxMsgSize == 0) begin
+ tx_data_avail <= 0;
+ State <= NextState;
+ end else if(tx_rd) begin
+ TxMsgBuf <= TxMsgBuf << 8;
+ TxMsgSize <= TxMsgSize -1;
+ end
+ end
+ endcase
+ end
+end
+
+
+// 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
+endmodule
diff --git a/verilog/rtl/uart_i2c/src/uart_i2c_top.sv b/verilog/rtl/uart_i2c/src/uart_i2c_top.sv
new file mode 100644
index 0000000..c0b68c5
--- /dev/null
+++ b/verilog/rtl/uart_i2c/src/uart_i2c_top.sv
@@ -0,0 +1,179 @@
+
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART CORE with TX/RX 16 Byte Buffer ////
+//// I2C Master ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// ////
+//// Description: This module integarte Uart and I2C Master ////
+//// Both these block share common two pins, effectly only ////
+//// one block active at time. This is due to top-level pin ////
+//// restriction. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_i2c_top
+
+ (
+
+ input logic uart_rstn , // async reset
+ input logic i2c_rstn , // async reset
+ input logic app_clk ,
+ input logic uart_i2c_sel, // Uart Or I2C Interface Select
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [3:0] reg_addr,
+ input logic [7:0] reg_wdata,
+ input logic reg_be,
+
+ // Outputs
+ output logic [7:0] reg_rdata,
+ output logic reg_ack,
+
+ // Pad Control
+ input logic [1:0] io_in,
+ output logic [1:0] io_out,
+ output logic [1:0] io_oeb
+
+ );
+
+/////////////////////////////////////////////////////////
+// uart interface
+///////////////////////////////////////////////////////
+
+logic uart_rxd ;
+logic uart_txd ;
+/////////////////////////////////////////////////////////
+// i2c interface
+///////////////////////////////////////////////////////
+logic scl_pad_i ; // SCL-line input
+logic scl_pad_o ; // SCL-line output (always 1'b0)
+logic scl_pad_oen_o ; // SCL-line output enable (active low)
+
+logic sda_pad_i ; // SDA-line input
+logic sda_pad_o ; // SDA-line output (always 1'b0)
+logic sda_padoen_o ; // SDA-line output enable (active low)
+
+
+
+assign io_oeb[0] = (uart_i2c_sel == 0) ? 1'b1 : scl_pad_oen_o ; // Uart RX
+assign uart_rxd = (uart_i2c_sel == 0) ? io_in[0]: 1'b0;
+assign scl_pad_i = (uart_i2c_sel == 1) ? io_in[0]: 1'b0;
+assign io_out[0] = (uart_i2c_sel == 0) ? 1'b0 : scl_pad_o ;
+
+assign io_oeb[1] = (uart_i2c_sel == 0) ? 1'b0 : sda_padoen_o ; // Uart TX & I2C Clock
+assign io_out[1] = (uart_i2c_sel == 0) ? uart_txd: sda_pad_o ;
+assign sda_pad_i = (uart_i2c_sel == 1) ? io_in[1] : 1'b0;
+
+logic [7:0] reg_uart_rdata;
+logic [7:0] reg_i2c_rdata;
+logic reg_uart_ack;
+logic reg_i2c_ack;
+
+
+assign reg_rdata = (uart_i2c_sel == 0) ? reg_uart_rdata : reg_i2c_rdata;
+assign reg_ack = (uart_i2c_sel == 0) ? reg_uart_ack : reg_i2c_ack;
+
+uart_core u_uart_core (
+
+ .arst_n (uart_rstn ), // async reset
+ .app_clk (app_clk ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr[3:0] ),
+ .reg_wdata (reg_wdata[7:0] ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_uart_rdata[7:0]),
+ .reg_ack (reg_uart_ack ),
+
+ // Pad Control
+ .rxd (uart_rxd ),
+ .txd (uart_txd )
+ );
+
+i2cm_top u_i2cm (
+ // wishbone signals
+ .wb_clk_i (app_clk ), // master clock input
+ .sresetn (1'b1 ), // synchronous reset
+ .aresetn (i2c_rstn ), // asynchronous reset
+ .wb_adr_i (reg_addr[2:0] ), // lower address bits
+ .wb_dat_i (reg_wdata ), // databus input
+ .wb_dat_o (reg_i2c_rdata ), // databus output
+ .wb_we_i (reg_wr ), // write enable input
+ .wb_stb_i (reg_cs ), // stobe/core select signal
+ .wb_cyc_i (reg_cs ), // valid bus cycle input
+ .wb_ack_o (reg_i2c_ack ), // bus cycle acknowledge output
+ .wb_inta_o ( ), // interrupt request signal output
+
+ // I2C signals
+ // i2c clock line
+ .scl_pad_i (scl_pad_i ), // SCL-line input
+ .scl_pad_o (scl_pad_o ), // SCL-line output (always 1'b0)
+ .scl_padoen_o (scl_pad_oen_o ), // SCL-line output enable (active low)
+
+ // i2c data line
+ .sda_pad_i (sda_pad_i ), // SDA-line input
+ .sda_pad_o (sda_pad_o ), // SDA-line output (always 1'b0)
+ .sda_padoen_o (sda_padoen_o ) // SDA-line output enable (active low)
+
+ );
+
+endmodule
diff --git a/verilog/rtl/uart_i2c_usb/src/uart_i2c_usb.sv b/verilog/rtl/uart_i2c_usb/src/uart_i2c_usb.sv
new file mode 100644
index 0000000..f1e7af6
--- /dev/null
+++ b/verilog/rtl/uart_i2c_usb/src/uart_i2c_usb.sv
@@ -0,0 +1,218 @@
+
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// integrated UART/I2C Master & USB1.1 Host ////
+//// ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// ////
+//// Description: This module integarte Uart and I2C Master ////
+//// and USB 1.1 Host. Both these block share common two pins, ////
+//// effectly only one block active at time. This is due to ////
+//// top-level pin restriction. ////
+//// ////
+//// Pin Maping UART I2C USB ////
+//// IO[1] - TXD SDA DP ////
+//// IO[0] - RXD SCL DN ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_i2c_usb_top
+
+ (
+
+ input logic uart_rstn , // async reset
+ input logic i2c_rstn , // async reset
+ input logic usb_rstn , // async reset
+ input logic app_clk ,
+ input logic usb_clk , // 48Mhz usb clock
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [7:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+ /////////////////////////////////////////////////////////
+ // i2c interface
+ ///////////////////////////////////////////////////////
+ input logic scl_pad_i , // SCL-line input
+ output logic scl_pad_o , // SCL-line output (always 1'b0)
+ output logic scl_pad_oen_o , // SCL-line output enable (active low)
+
+ input logic sda_pad_i , // SDA-line input
+ output logic sda_pad_o , // SDA-line output (always 1'b0)
+ output logic sda_padoen_o , // SDA-line output enable (active low)
+
+ // UART I/F
+ input logic uart_rxd ,
+ output logic uart_txd ,
+
+ input logic usb_in_dp ,
+ input logic usb_in_dn ,
+
+ output logic usb_out_dp ,
+ output logic usb_out_dn ,
+ output logic usb_out_tx_oen
+
+ );
+
+
+`define SEL_UART 2'b00
+`define SEL_I2C 2'b01
+`define SEL_USB 2'b10
+
+
+
+//----------------------------------------
+// Register Response Path Mux
+// --------------------------------------
+logic [7:0] reg_uart_rdata;
+logic [7:0] reg_i2c_rdata;
+logic [31:0] reg_usb_rdata;
+logic reg_uart_ack;
+logic reg_i2c_ack;
+logic reg_usb_ack;
+
+
+assign reg_rdata = (reg_addr[7:6] == `SEL_UART) ? {24'h0,reg_uart_rdata} :
+ (reg_addr[7:6] == `SEL_I2C) ? {24'h0,reg_i2c_rdata} : reg_usb_rdata;
+assign reg_ack = (reg_addr[7:6] == `SEL_UART) ? reg_uart_ack :
+ (reg_addr[7:6] == `SEL_I2C) ? reg_i2c_ack : reg_usb_ack;
+
+uart_core u_uart_core (
+
+ .arst_n (uart_rstn ), // async reset
+ .app_clk (app_clk ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr[5:2] ),
+ .reg_wdata (reg_wdata[7:0] ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_uart_rdata[7:0]),
+ .reg_ack (reg_uart_ack ),
+
+ // Pad Control
+ .rxd (uart_rxd ),
+ .txd (uart_txd )
+ );
+
+i2cm_top u_i2cm (
+ // wishbone signals
+ .wb_clk_i (app_clk ), // master clock input
+ .sresetn (i2c_rstn ), // synchronous reset
+ .aresetn (1'b1 ), // asynchronous reset
+ .wb_adr_i (reg_addr[4:2] ), // lower address bits
+ .wb_dat_i (reg_wdata[7:0] ), // databus input
+ .wb_dat_o (reg_i2c_rdata ), // databus output
+ .wb_we_i (reg_wr ), // write enable input
+ .wb_stb_i (reg_cs ), // stobe/core select signal
+ .wb_cyc_i (reg_cs ), // valid bus cycle input
+ .wb_ack_o (reg_i2c_ack ), // bus cycle acknowledge output
+ .wb_inta_o ( ), // interrupt request signal output
+
+ // I2C signals
+ // i2c clock line
+ .scl_pad_i (scl_pad_i ), // SCL-line input
+ .scl_pad_o (scl_pad_o ), // SCL-line output (always 1'b0)
+ .scl_padoen_o (scl_pad_oen_o ), // SCL-line output enable (active low)
+
+ // i2c data line
+ .sda_pad_i (sda_pad_i ), // SDA-line input
+ .sda_pad_o (sda_pad_o ), // SDA-line output (always 1'b0)
+ .sda_padoen_o (sda_padoen_o ) // SDA-line output enable (active low)
+
+ );
+
+
+usb1_host u_usb_host (
+ .usb_clk_i (usb_clk ),
+ .usb_rstn_i (usb_rstn ),
+
+ // USB D+/D-
+ .in_dp (usb_in_dp ),
+ .in_dn (usb_in_dn ),
+
+ .out_dp (usb_out_dp ),
+ .out_dn (usb_out_dn ),
+ .out_tx_oen (usb_out_tx_oen),
+
+ // Master Port
+ .wbm_rst_n (usb_rstn ), // Regular Reset signal
+ .wbm_clk_i (app_clk ), // System clock
+ .wbm_stb_i (reg_cs ), // strobe/request
+ .wbm_adr_i (reg_addr[5:0]), // address
+ .wbm_we_i (reg_wr ), // write
+ .wbm_dat_i (reg_wdata ), // data output
+ .wbm_sel_i (reg_be ), // byte enable
+ .wbm_dat_o (reg_usb_rdata ), // data input
+ .wbm_ack_o (reg_usb_ack ), // acknowlegement
+ .wbm_err_o ( ), // error
+
+ // Outputs
+ .usb_intr_o ( )
+
+
+ );
+
+
+endmodule
diff --git a/verilog/rtl/uart_i2c_usb_spi/src/uart_i2c_usb_spi.sv b/verilog/rtl/uart_i2c_usb_spi/src/uart_i2c_usb_spi.sv
new file mode 100644
index 0000000..d3378e0
--- /dev/null
+++ b/verilog/rtl/uart_i2c_usb_spi/src/uart_i2c_usb_spi.sv
@@ -0,0 +1,281 @@
+
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// integrated UART,I2C Master, SPU Master & USB1.1 Host ////
+//// ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description: This module integarte Uart , I2C Master ////
+//// SPI Master and USB 1.1 Host. ////
+//// ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_i2c_usb_spi_top
+
+ (
+`ifdef USE_POWER_PINS
+ input logic vccd1,// User area 1 1.8V supply
+ input logic vssd1,// User area 1 digital ground
+`endif
+ // clock skew adjust
+ input logic [3:0] cfg_cska_uart,
+ input logic wbd_clk_int,
+ output logic wbd_clk_uart,
+
+ input logic uart_rstn , // async reset
+ input logic i2c_rstn , // async reset
+ input logic usb_rstn , // async reset
+ input logic spi_rstn , // async reset
+ input logic app_clk ,
+ input logic usb_clk , // 48Mhz usb clock
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [7:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+ /////////////////////////////////////////////////////////
+ // i2c interface
+ ///////////////////////////////////////////////////////
+ input logic scl_pad_i , // SCL-line input
+ output logic scl_pad_o , // SCL-line output (always 1'b0)
+ output logic scl_pad_oen_o , // SCL-line output enable (active low)
+
+ input logic sda_pad_i , // SDA-line input
+ output logic sda_pad_o , // SDA-line output (always 1'b0)
+ output logic sda_padoen_o , // SDA-line output enable (active low)
+
+ output logic i2cm_intr_o ,
+
+ // UART I/F
+ input logic uart_rxd ,
+ output logic uart_txd ,
+
+ // USB 1.1 HOST I/F
+ input logic usb_in_dp ,
+ input logic usb_in_dn ,
+
+ output logic usb_out_dp ,
+ output logic usb_out_dn ,
+ output logic usb_out_tx_oen ,
+
+ output logic usb_intr_o ,
+
+ // SPIM I/F
+ output logic sspim_sck, // clock out
+ output logic sspim_so, // serial data out
+ input logic sspim_si, // serial data in
+ output logic sspim_ssn // cs_n
+
+ );
+
+// uart clock skew control
+clk_skew_adjust u_skew_uart
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_uart ),
+ .clk_out (wbd_clk_uart )
+ );
+
+`define SEL_UART 2'b00
+`define SEL_I2C 2'b01
+`define SEL_USB 2'b10
+`define SEL_SPI 2'b11
+
+
+
+//----------------------------------------
+// Register Response Path Mux
+// --------------------------------------
+logic [7:0] reg_uart_rdata;
+logic [7:0] reg_i2c_rdata;
+logic [31:0] reg_usb_rdata;
+logic [31:0] reg_spim_rdata;
+logic reg_uart_ack;
+logic reg_i2c_ack;
+logic reg_usb_ack;
+logic reg_spim_ack;
+
+
+assign reg_rdata = (reg_addr[7:6] == `SEL_UART) ? {24'h0,reg_uart_rdata} :
+ (reg_addr[7:6] == `SEL_I2C) ? {24'h0,reg_i2c_rdata} :
+ (reg_addr[7:6] == `SEL_USB) ? reg_usb_rdata : reg_spim_rdata;
+assign reg_ack = (reg_addr[7:6] == `SEL_UART) ? reg_uart_ack :
+ (reg_addr[7:6] == `SEL_I2C) ? reg_i2c_ack :
+ (reg_addr[7:6] == `SEL_USB) ? reg_usb_ack : reg_spim_ack;
+
+wire reg_uart_cs = (reg_addr[7:6] == `SEL_UART) ? reg_cs : 1'b0;
+wire reg_i2cm_cs = (reg_addr[7:6] == `SEL_I2C) ? reg_cs : 1'b0;
+wire reg_usb_cs = (reg_addr[7:6] == `SEL_UART) ? reg_cs : 1'b0;
+wire reg_spim_cs = (reg_addr[7:6] == `SEL_SPI) ? reg_cs : 1'b0;
+
+uart_core u_uart_core (
+
+ .arst_n (uart_rstn ), // async reset
+ .app_clk (app_clk ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_uart_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr[5:2] ),
+ .reg_wdata (reg_wdata[7:0] ),
+ .reg_be (reg_be[0] ),
+
+ // Outputs
+ .reg_rdata (reg_uart_rdata[7:0]),
+ .reg_ack (reg_uart_ack ),
+
+ // Pad Control
+ .rxd (uart_rxd ),
+ .txd (uart_txd )
+ );
+
+i2cm_top u_i2cm (
+ // wishbone signals
+ .wb_clk_i (app_clk ), // master clock input
+ .sresetn (1'b1 ), // synchronous reset
+ .aresetn (i2c_rstn ), // asynchronous reset
+ .wb_adr_i (reg_addr[4:2] ), // lower address bits
+ .wb_dat_i (reg_wdata[7:0] ), // databus input
+ .wb_dat_o (reg_i2c_rdata ), // databus output
+ .wb_we_i (reg_wr ), // write enable input
+ .wb_stb_i (reg_i2cm_cs ), // stobe/core select signal
+ .wb_cyc_i (reg_i2cm_cs ), // valid bus cycle input
+ .wb_ack_o (reg_i2c_ack ), // bus cycle acknowledge output
+ .wb_inta_o (i2cm_intr_o ), // interrupt request signal output
+
+ // I2C signals
+ // i2c clock line
+ .scl_pad_i (scl_pad_i ), // SCL-line input
+ .scl_pad_o (scl_pad_o ), // SCL-line output (always 1'b0)
+ .scl_padoen_o (scl_pad_oen_o ), // SCL-line output enable (active low)
+
+ // i2c data line
+ .sda_pad_i (sda_pad_i ), // SDA-line input
+ .sda_pad_o (sda_pad_o ), // SDA-line output (always 1'b0)
+ .sda_padoen_o (sda_padoen_o ) // SDA-line output enable (active low)
+
+ );
+
+
+usb1_host u_usb_host (
+ .usb_clk_i (usb_clk ),
+ .usb_rstn_i (usb_rstn ),
+
+ // USB D+/D-
+ .in_dp (usb_in_dp ),
+ .in_dn (usb_in_dn ),
+
+ .out_dp (usb_out_dp ),
+ .out_dn (usb_out_dn ),
+ .out_tx_oen (usb_out_tx_oen),
+
+ // Master Port
+ .wbm_rst_n (usb_rstn ), // Regular Reset signal
+ .wbm_clk_i (app_clk ), // System clock
+ .wbm_stb_i (reg_usb_cs ), // strobe/request
+ .wbm_adr_i (reg_addr[5:0]), // address
+ .wbm_we_i (reg_wr ), // write
+ .wbm_dat_i (reg_wdata ), // data output
+ .wbm_sel_i (reg_be ), // byte enable
+ .wbm_dat_o (reg_usb_rdata ), // data input
+ .wbm_ack_o (reg_usb_ack ), // acknowlegement
+ .wbm_err_o ( ), // error
+
+ // Outputs
+ .usb_intr_o ( usb_intr_o )
+
+ );
+
+sspim_top u_sspim (
+ .clk (app_clk ),
+ .reset_n (spi_rstn ),
+
+
+ //---------------------------------
+ // Reg Bus Interface Signal
+ //---------------------------------
+ .reg_cs (reg_spim_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_spim_rdata ),
+ .reg_ack (reg_spim_ack ),
+
+ //-------------------------------------------
+ // Line Interface
+ //-------------------------------------------
+
+ .sck (sspim_sck), // clock out
+ .so (sspim_so), // serial data out
+ .si (sspim_si), // serial data in
+ .ssn (sspim_ssn) // cs_n
+
+ );
+
+endmodule
diff --git a/verilog/rtl/uprj_netlists.v b/verilog/rtl/uprj_netlists.v
new file mode 100644
index 0000000..b81ad7e
--- /dev/null
+++ b/verilog/rtl/uprj_netlists.v
@@ -0,0 +1,183 @@
+// SPDX-FileCopyrightText: 2020 Efabless Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+
+// Include caravel global defines for the number of the user project IO pads
+`include "defines.v"
+`define USE_POWER_PINS
+`define UNIT_DELAY #0.1
+
+`ifdef GL
+ `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v"
+ `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v"
+ `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v"
+ `include "libs.ref/sky130_fd_sc_hvl/verilog/sky130_fd_sc_hvl.v"
+ `include "libs.ref//sky130_fd_sc_hd/verilog/sky130_ef_sc_hd__fakediode_2.v"
+
+ `include "glbl_cfg.v"
+ `include "spi_master.v"
+ `include "uart_i2cm.v"
+ `include "wb_interconnect.v"
+ `include "user_project_wrapper.v"
+ `include "yifive.v"
+ `include "wb_host.v"
+ `include "clk_skew_adjust.v"
+ `include "clk_buf.v"
+
+`else
+ `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v"
+ `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v"
+ `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v"
+ `include "libs.ref/sky130_fd_sc_hvl/verilog/sky130_fd_sc_hvl.v"
+
+ `include"sar_adc/SAR.sv"
+ `include"sar_adc/ACMP.sv"
+ `include"sar_adc/sar_adc.sv"
+ `include"sar_adc/adc_reg.sv"
+ `include"sar_adc/DAC_8BIT.v"
+
+
+ `include "sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v"
+ `include "pinmux/src/pinmux.sv"
+ `include "pinmux/src/pinmux_reg.sv"
+ `include "pinmux/src/gpio_intr.sv"
+ `include "pinmux/src/pwm.sv"
+ `include "lib/pulse_gen_type1.sv"
+ `include "lib/pulse_gen_type2.sv"
+
+ `include "qspim/src/qspim_top.sv"
+ `include "qspim/src/qspim_if.sv"
+ `include "qspim/src/qspim_fifo.sv"
+ `include "qspim/src/qspim_regs.sv"
+ `include "qspim/src/qspim_clkgen.sv"
+ `include "qspim/src/qspim_ctrl.sv"
+ `include "qspim/src/qspim_rx.sv"
+ `include "qspim/src/qspim_tx.sv"
+
+ `include "uart/src/uart_core.sv"
+ `include "uart/src/uart_cfg.sv"
+ `include "uart/src/uart_rxfsm.sv"
+ `include "uart/src/uart_txfsm.sv"
+ `include "lib/async_fifo_th.sv"
+ `include "lib/reset_sync.sv"
+ `include "lib/double_sync_low.v"
+ `include "lib/clk_buf.v"
+
+ `include "i2cm/src/core/i2cm_bit_ctrl.v"
+ `include "i2cm/src/core/i2cm_byte_ctrl.v"
+ `include "i2cm/src/core/i2cm_top.v"
+
+ `include "usb1_host/src/core/usbh_core.sv"
+ `include "usb1_host/src/core/usbh_crc16.sv"
+ `include "usb1_host/src/core/usbh_crc5.sv"
+ `include "usb1_host/src/core/usbh_fifo.sv"
+ `include "usb1_host/src/core/usbh_sie.sv"
+ `include "usb1_host/src/phy/usb_fs_phy.v"
+ `include "usb1_host/src/phy/usb_transceiver.v"
+ `include "usb1_host/src/top/usb1_host.sv"
+
+ `include "sspim/src/sspim_top.sv"
+ `include "sspim/src/sspim_ctl.sv"
+ `include "sspim/src/sspim_if.sv"
+ `include "sspim/src/sspim_cfg.sv"
+
+
+ `include "uart_i2c_usb_spi/src/uart_i2c_usb_spi.sv"
+
+ `include "lib/async_fifo.sv"
+ `include "lib/registers.v"
+ `include "lib/clk_ctl.v"
+ `include "lib/ser_inf_32b.sv"
+ `include "lib/ser_shift.sv"
+ `include "digital_core/src/glbl_cfg.sv"
+
+ `include "wb_host/src/wb_host.sv"
+ `include "lib/async_wb.sv"
+
+ `include "lib/sync_wbb.sv"
+ `include "lib/sync_fifo2.sv"
+ `include "wb_interconnect/src/wb_arb.sv"
+ `include "wb_interconnect/src/wb_interconnect.sv"
+
+
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_hdu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_tdu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_ipic.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_csr.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_exu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_ialu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_idu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_ifu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_lsu.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_mprf.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_mul.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_div.sv"
+ `include "yifive/ycr1c/src/core/pipeline/ycr1_pipe_top.sv"
+ `include "yifive/ycr1c/src/core/primitives/ycr1_reset_cells.sv"
+ `include "yifive/ycr1c/src/core/primitives/ycr1_cg.sv"
+ `include "yifive/ycr1c/src/core/ycr1_clk_ctrl.sv"
+ `include "yifive/ycr1c/src/core/ycr1_tapc_shift_reg.sv"
+ `include "yifive/ycr1c/src/core/ycr1_tapc.sv"
+ `include "yifive/ycr1c/src/core/ycr1_tapc_synchronizer.sv"
+ `include "yifive/ycr1c/src/core/ycr1_core_top.sv"
+ `include "yifive/ycr1c/src/core/ycr1_dm.sv"
+ `include "yifive/ycr1c/src/core/ycr1_dmi.sv"
+ `include "yifive/ycr1c/src/core/ycr1_scu.sv"
+ `include "yifive/ycr1c/src/top/ycr1_imem_router.sv"
+ `include "yifive/ycr1c/src/top/ycr1_dmem_router.sv"
+ `include "yifive/ycr1c/src/top/ycr1_dp_memory.sv"
+ `include "yifive/ycr1c/src/top/ycr1_tcm.sv"
+ `include "yifive/ycr1c/src/top/ycr1_timer.sv"
+ `include "yifive/ycr1c/src/top/ycr1_dmem_wb.sv"
+ `include "yifive/ycr1c/src/top/ycr1_imem_wb.sv"
+ `include "yifive/ycr1c/src/top/ycr1_intf.sv"
+ `include "yifive/ycr1c/src/top/ycr1_top_wb.sv"
+ `include "yifive/ycr1c/src/top/ycr1_icache_router.sv"
+ `include "yifive/ycr1c/src/top/ycr1_dcache_router.sv"
+ `include "yifive/ycr1c/src/cache/src/core/icache_top.sv"
+ `include "yifive/ycr1c/src/cache/src/core/icache_app_fsm.sv"
+ `include "yifive/ycr1c/src/cache/src/core/icache_tag_fifo.sv"
+ `include "yifive/ycr1c/src/cache/src/core/dcache_tag_fifo.sv"
+ `include "yifive/ycr1c/src/cache/src/core/dcache_top.sv"
+ `include "yifive/ycr1c/src/lib/ycr1_async_wbb.sv"
+ `include "yifive/ycr1c/src/lib/ycr1_arb.sv"
+
+ `include "lib/sync_fifo.sv"
+
+ `include "mbist/src/core/mbist_addr_gen.sv"
+ `include "mbist/src/core/mbist_fsm.sv"
+ `include "mbist/src/core/mbist_op_sel.sv"
+ `include "mbist/src/core/mbist_repair_addr.sv"
+ `include "mbist/src/core/mbist_sti_sel.sv"
+ `include "mbist/src/core/mbist_pat_sel.sv"
+ `include "mbist/src/core/mbist_mux.sv"
+ `include "mbist/src/core/mbist_data_cmp.sv"
+ `include "mbist/src/core/mbist_mem_wrapper.sv"
+
+ `include "mbist/src/top/mbist_top.sv"
+ `include "mbist_wrapper/src/mbist_wb.sv"
+ `include "mbist_wrapper/src/mbist_wrapper.sv"
+
+
+ `include "uart2wb/src/uart2wb.sv"
+ `include "uart2wb/src/uart2_core.sv"
+ `include "uart2wb/src/uart_msg_handler.v"
+ `include "lib/async_reg_bus.sv"
+
+ `include "user_project_wrapper.v"
+ // we are using netlist file for clk_skew_adjust as it has
+ // standard cell + power pin
+ `include "clk_skew_adjust/src/clk_skew_adjust.v"
+ `include "lib/ctech_cells.sv"
+`endif
diff --git a/verilog/rtl/usb1_host/src/core/usbh_core.sv b/verilog/rtl/usb1_host/src/core/usbh_core.sv
new file mode 100644
index 0000000..adffecb
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_core.sv
@@ -0,0 +1,1019 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+`include "usbh_host_defs.v"
+
+//-----------------------------------------------------------------
+// Module: USB Host IP
+//-----------------------------------------------------------------
+module usbh_core
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+#(
+ parameter USB_CLK_FREQ = 48000000
+)
+//-----------------------------------------------------------------
+// Ports
+//-----------------------------------------------------------------
+(
+ // Inputs
+ input logic clk_i,
+ input logic rstn_i,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [5:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ // UTMI Input
+ input logic [7:0] utmi_data_in_i,
+ input logic utmi_txready_i,
+ input logic utmi_rxvalid_i,
+ input logic utmi_rxactive_i,
+ input logic utmi_rxerror_i,
+ input logic [1:0] utmi_linestate_i,
+
+ // UTMI Outputs
+ output logic intr_o,
+ output logic [7:0] utmi_data_out_o,
+ output logic utmi_txvalid_o,
+ output logic [1:0] utmi_op_mode_o,
+ output logic [1:0] utmi_xcvrselect_o,
+ output logic utmi_termselect_o,
+ output logic utmi_dppulldown_o,
+ output logic utmi_dmpulldown_o
+);
+
+
+reg [31:0] reg_rdata_r;
+wire [15:0] usb_status_sof_time_in_w;
+wire usb_status_rx_error_in_w;
+wire [1:0] usb_status_linestate_bits_in_w;
+wire usb_irq_sts_device_detect_in_w;
+wire usb_irq_sts_err_in_w;
+wire usb_irq_sts_done_in_w;
+wire usb_irq_sts_sof_in_w;
+wire usb_rx_stat_start_pend_in_w;
+wire usb_rx_stat_crc_err_in_w;
+wire usb_rx_stat_resp_timeout_in_w;
+wire usb_rx_stat_idle_in_w;
+wire [7:0] usb_rx_stat_resp_bits_in_w;
+wire [15:0] usb_rx_stat_count_bits_in_w;
+wire [7:0] usb_rd_data_data_in_w;
+
+//-----------------------------------------------------------------------
+// Read path mux
+//-----------------------------------------------------------------------
+
+logic cfg_wr;
+
+always @ (posedge clk_i or negedge rstn_i)
+begin : preg_out_Seq
+ if (rstn_i == 1'b0) begin
+ reg_rdata [31:0] <= 32'h0000_0000;
+ reg_ack <= 1'b0;
+ cfg_wr <= 1'b0;
+ end else if (reg_cs && (reg_wr == 0) && !reg_ack) begin
+ reg_rdata [31:0] <= reg_rdata_r [31:0];
+ reg_ack <= 1'b1;
+ end else if (reg_cs && (reg_wr == 1) && !reg_ack) begin
+ reg_ack <= 1'b1;
+ cfg_wr <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ cfg_wr <= 1'b0;
+ end
+end
+
+
+//-----------------------------------------------------------------
+// Register usb_ctrl
+//-----------------------------------------------------------------
+reg usb_ctrl_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_wr_q <= 1'b1;
+else
+ usb_ctrl_wr_q <= 1'b0;
+
+// usb_ctrl_tx_flush [auto_clr]
+reg usb_ctrl_tx_flush_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_tx_flush_q <= 1'd`USB_CTRL_TX_FLUSH_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_tx_flush_q <= reg_wdata[`USB_CTRL_TX_FLUSH_R];
+else
+ usb_ctrl_tx_flush_q <= 1'd`USB_CTRL_TX_FLUSH_DEFAULT;
+
+wire usb_ctrl_tx_flush_out_w = usb_ctrl_tx_flush_q;
+
+
+// usb_ctrl_phy_dmpulldown [internal]
+reg usb_ctrl_phy_dmpulldown_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_dmpulldown_q <= 1'd`USB_CTRL_PHY_DMPULLDOWN_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_dmpulldown_q <= reg_wdata[`USB_CTRL_PHY_DMPULLDOWN_R];
+
+wire usb_ctrl_phy_dmpulldown_out_w = usb_ctrl_phy_dmpulldown_q;
+
+
+// usb_ctrl_phy_dppulldown [internal]
+reg usb_ctrl_phy_dppulldown_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_dppulldown_q <= 1'd`USB_CTRL_PHY_DPPULLDOWN_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_dppulldown_q <= reg_wdata[`USB_CTRL_PHY_DPPULLDOWN_R];
+
+wire usb_ctrl_phy_dppulldown_out_w = usb_ctrl_phy_dppulldown_q;
+
+
+// usb_ctrl_phy_termselect [internal]
+reg usb_ctrl_phy_termselect_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_termselect_q <= 1'd`USB_CTRL_PHY_TERMSELECT_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_termselect_q <= reg_wdata[`USB_CTRL_PHY_TERMSELECT_R];
+
+wire usb_ctrl_phy_termselect_out_w = usb_ctrl_phy_termselect_q;
+
+
+// usb_ctrl_phy_xcvrselect [internal]
+reg [1:0] usb_ctrl_phy_xcvrselect_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_xcvrselect_q <= 2'd`USB_CTRL_PHY_XCVRSELECT_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_xcvrselect_q <= reg_wdata[`USB_CTRL_PHY_XCVRSELECT_R];
+
+wire [1:0] usb_ctrl_phy_xcvrselect_out_w = usb_ctrl_phy_xcvrselect_q;
+
+
+// usb_ctrl_phy_opmode [internal]
+reg [1:0] usb_ctrl_phy_opmode_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_opmode_q <= 2'd`USB_CTRL_PHY_OPMODE_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_opmode_q <= reg_wdata[`USB_CTRL_PHY_OPMODE_R];
+
+wire [1:0] usb_ctrl_phy_opmode_out_w = usb_ctrl_phy_opmode_q;
+
+
+// usb_ctrl_enable_sof [internal]
+reg usb_ctrl_enable_sof_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_enable_sof_q <= 1'd`USB_CTRL_ENABLE_SOF_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_enable_sof_q <= reg_wdata[`USB_CTRL_ENABLE_SOF_R];
+
+wire usb_ctrl_enable_sof_out_w = usb_ctrl_enable_sof_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_status
+//-----------------------------------------------------------------
+reg usb_status_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_status_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_STATUS))
+ usb_status_wr_q <= 1'b1;
+else
+ usb_status_wr_q <= 1'b0;
+
+
+
+
+//-----------------------------------------------------------------
+// Register usb_irq_ack
+//-----------------------------------------------------------------
+reg usb_irq_ack_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_wr_q <= 1'b1;
+else
+ usb_irq_ack_wr_q <= 1'b0;
+
+// usb_irq_ack_device_detect [auto_clr]
+reg usb_irq_ack_device_detect_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_device_detect_q <= 1'd`USB_IRQ_ACK_DEVICE_DETECT_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_device_detect_q <= reg_wdata[`USB_IRQ_ACK_DEVICE_DETECT_R];
+else
+ usb_irq_ack_device_detect_q <= 1'd`USB_IRQ_ACK_DEVICE_DETECT_DEFAULT;
+
+wire usb_irq_ack_device_detect_out_w = usb_irq_ack_device_detect_q;
+
+
+// usb_irq_ack_err [auto_clr]
+reg usb_irq_ack_err_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_err_q <= 1'd`USB_IRQ_ACK_ERR_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_err_q <= reg_wdata[`USB_IRQ_ACK_ERR_R];
+else
+ usb_irq_ack_err_q <= 1'd`USB_IRQ_ACK_ERR_DEFAULT;
+
+wire usb_irq_ack_err_out_w = usb_irq_ack_err_q;
+
+
+// usb_irq_ack_done [auto_clr]
+reg usb_irq_ack_done_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_done_q <= 1'd`USB_IRQ_ACK_DONE_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_done_q <= reg_wdata[`USB_IRQ_ACK_DONE_R];
+else
+ usb_irq_ack_done_q <= 1'd`USB_IRQ_ACK_DONE_DEFAULT;
+
+wire usb_irq_ack_done_out_w = usb_irq_ack_done_q;
+
+
+// usb_irq_ack_sof [auto_clr]
+reg usb_irq_ack_sof_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_sof_q <= 1'd`USB_IRQ_ACK_SOF_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_sof_q <= reg_wdata[`USB_IRQ_ACK_SOF_R];
+else
+ usb_irq_ack_sof_q <= 1'd`USB_IRQ_ACK_SOF_DEFAULT;
+
+wire usb_irq_ack_sof_out_w = usb_irq_ack_sof_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_irq_sts
+//-----------------------------------------------------------------
+reg usb_irq_sts_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_sts_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_STS))
+ usb_irq_sts_wr_q <= 1'b1;
+else
+ usb_irq_sts_wr_q <= 1'b0;
+
+
+
+
+
+//-----------------------------------------------------------------
+// Register usb_irq_mask
+//-----------------------------------------------------------------
+reg usb_irq_mask_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_wr_q <= 1'b1;
+else
+ usb_irq_mask_wr_q <= 1'b0;
+
+// usb_irq_mask_device_detect [internal]
+reg usb_irq_mask_device_detect_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_device_detect_q <= 1'd`USB_IRQ_MASK_DEVICE_DETECT_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_device_detect_q <= reg_wdata[`USB_IRQ_MASK_DEVICE_DETECT_R];
+
+wire usb_irq_mask_device_detect_out_w = usb_irq_mask_device_detect_q;
+
+
+// usb_irq_mask_err [internal]
+reg usb_irq_mask_err_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_err_q <= 1'd`USB_IRQ_MASK_ERR_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_err_q <= reg_wdata[`USB_IRQ_MASK_ERR_R];
+
+wire usb_irq_mask_err_out_w = usb_irq_mask_err_q;
+
+
+// usb_irq_mask_done [internal]
+reg usb_irq_mask_done_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_done_q <= 1'd`USB_IRQ_MASK_DONE_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_done_q <= reg_wdata[`USB_IRQ_MASK_DONE_R];
+
+wire usb_irq_mask_done_out_w = usb_irq_mask_done_q;
+
+
+// usb_irq_mask_sof [internal]
+reg usb_irq_mask_sof_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_sof_q <= 1'd`USB_IRQ_MASK_SOF_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_sof_q <= reg_wdata[`USB_IRQ_MASK_SOF_R];
+
+wire usb_irq_mask_sof_out_w = usb_irq_mask_sof_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_xfer_data
+//-----------------------------------------------------------------
+reg usb_xfer_data_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_data_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_DATA))
+ usb_xfer_data_wr_q <= 1'b1;
+else
+ usb_xfer_data_wr_q <= 1'b0;
+
+// usb_xfer_data_tx_len [internal]
+reg [15:0] usb_xfer_data_tx_len_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_data_tx_len_q <= 16'd`USB_XFER_DATA_TX_LEN_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_DATA))
+ usb_xfer_data_tx_len_q <= reg_wdata[`USB_XFER_DATA_TX_LEN_R];
+
+wire [15:0] usb_xfer_data_tx_len_out_w = usb_xfer_data_tx_len_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_xfer_token
+//-----------------------------------------------------------------
+reg usb_xfer_token_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_wr_q <= 1'b1;
+else
+ usb_xfer_token_wr_q <= 1'b0;
+
+// usb_xfer_token_start [clearable]
+reg usb_xfer_token_start_q;
+
+wire usb_xfer_token_start_ack_in_w;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_start_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_start_q <= reg_wdata[`USB_XFER_TOKEN_START_R];
+else if (usb_xfer_token_start_ack_in_w)
+ usb_xfer_token_start_q <= 1'b0;
+
+wire usb_xfer_token_start_out_w = usb_xfer_token_start_q;
+
+
+// usb_xfer_token_in [internal]
+reg usb_xfer_token_in_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_in_q <= 1'd`USB_XFER_TOKEN_IN_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_in_q <= reg_wdata[`USB_XFER_TOKEN_IN_R];
+
+wire usb_xfer_token_in_out_w = usb_xfer_token_in_q;
+
+
+// usb_xfer_token_ack [internal]
+reg usb_xfer_token_ack_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_ack_q <= 1'd`USB_XFER_TOKEN_ACK_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_ack_q <= reg_wdata[`USB_XFER_TOKEN_ACK_R];
+
+wire usb_xfer_token_ack_out_w = usb_xfer_token_ack_q;
+
+
+// usb_xfer_token_pid_datax [internal]
+reg usb_xfer_token_pid_datax_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_pid_datax_q <= 1'd`USB_XFER_TOKEN_PID_DATAX_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_pid_datax_q <= reg_wdata[`USB_XFER_TOKEN_PID_DATAX_R];
+
+wire usb_xfer_token_pid_datax_out_w = usb_xfer_token_pid_datax_q;
+
+
+// usb_xfer_token_pid_bits [internal]
+reg [7:0] usb_xfer_token_pid_bits_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_pid_bits_q <= 8'd`USB_XFER_TOKEN_PID_BITS_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_pid_bits_q <= reg_wdata[`USB_XFER_TOKEN_PID_BITS_R];
+
+wire [7:0] usb_xfer_token_pid_bits_out_w = usb_xfer_token_pid_bits_q;
+
+
+// usb_xfer_token_dev_addr [internal]
+reg [6:0] usb_xfer_token_dev_addr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_dev_addr_q <= 7'd`USB_XFER_TOKEN_DEV_ADDR_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_dev_addr_q <= reg_wdata[`USB_XFER_TOKEN_DEV_ADDR_R];
+
+wire [6:0] usb_xfer_token_dev_addr_out_w = usb_xfer_token_dev_addr_q;
+
+
+// usb_xfer_token_ep_addr [internal]
+reg [3:0] usb_xfer_token_ep_addr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_ep_addr_q <= 4'd`USB_XFER_TOKEN_EP_ADDR_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_ep_addr_q <= reg_wdata[`USB_XFER_TOKEN_EP_ADDR_R];
+
+wire [3:0] usb_xfer_token_ep_addr_out_w = usb_xfer_token_ep_addr_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_rx_stat
+//-----------------------------------------------------------------
+reg usb_rx_stat_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_rx_stat_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_RX_STAT))
+ usb_rx_stat_wr_q <= 1'b1;
+else
+ usb_rx_stat_wr_q <= 1'b0;
+
+
+
+//-----------------------------------------------------------------
+// Retime write data
+//-----------------------------------------------------------------
+reg [31:0] wr_data_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ wr_data_q <= 32'b0;
+else if (cfg_wr)
+ wr_data_q <= reg_wdata;
+
+
+
+
+//-----------------------------------------------------------------
+// Register usb_wr_data
+//-----------------------------------------------------------------
+reg usb_wr_data_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_wr_data_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_WR_DATA))
+ usb_wr_data_wr_q <= 1'b1;
+else
+ usb_wr_data_wr_q <= 1'b0;
+
+// usb_wr_data_data [external]
+wire [7:0] usb_wr_data_data_out_w = wr_data_q[`USB_WR_DATA_DATA_R];
+
+//-----------------------------------------------------------------
+// Read mux
+//-----------------------------------------------------------------
+
+always @ *
+begin
+ reg_rdata_r = 32'b0;
+
+ case (reg_addr[5:0])
+
+ `USB_CTRL:
+ begin
+ reg_rdata_r[`USB_CTRL_PHY_DMPULLDOWN_R] = usb_ctrl_phy_dmpulldown_q;
+ reg_rdata_r[`USB_CTRL_PHY_DPPULLDOWN_R] = usb_ctrl_phy_dppulldown_q;
+ reg_rdata_r[`USB_CTRL_PHY_TERMSELECT_R] = usb_ctrl_phy_termselect_q;
+ reg_rdata_r[`USB_CTRL_PHY_XCVRSELECT_R] = usb_ctrl_phy_xcvrselect_q;
+ reg_rdata_r[`USB_CTRL_PHY_OPMODE_R] = usb_ctrl_phy_opmode_q;
+ reg_rdata_r[`USB_CTRL_ENABLE_SOF_R] = usb_ctrl_enable_sof_q;
+ end
+ `USB_STATUS:
+ begin
+ reg_rdata_r[`USB_STATUS_SOF_TIME_R] = usb_status_sof_time_in_w;
+ reg_rdata_r[`USB_STATUS_RX_ERROR_R] = usb_status_rx_error_in_w;
+ reg_rdata_r[`USB_STATUS_LINESTATE_BITS_R] = usb_status_linestate_bits_in_w;
+ end
+ `USB_IRQ_STS:
+ begin
+ reg_rdata_r[`USB_IRQ_STS_DEVICE_DETECT_R] = usb_irq_sts_device_detect_in_w;
+ reg_rdata_r[`USB_IRQ_STS_ERR_R] = usb_irq_sts_err_in_w;
+ reg_rdata_r[`USB_IRQ_STS_DONE_R] = usb_irq_sts_done_in_w;
+ reg_rdata_r[`USB_IRQ_STS_SOF_R] = usb_irq_sts_sof_in_w;
+ end
+ `USB_IRQ_MASK:
+ begin
+ reg_rdata_r[`USB_IRQ_MASK_DEVICE_DETECT_R] = usb_irq_mask_device_detect_q;
+ reg_rdata_r[`USB_IRQ_MASK_ERR_R] = usb_irq_mask_err_q;
+ reg_rdata_r[`USB_IRQ_MASK_DONE_R] = usb_irq_mask_done_q;
+ reg_rdata_r[`USB_IRQ_MASK_SOF_R] = usb_irq_mask_sof_q;
+ end
+ `USB_XFER_DATA:
+ begin
+ reg_rdata_r[`USB_XFER_DATA_TX_LEN_R] = usb_xfer_data_tx_len_q;
+ end
+ `USB_XFER_TOKEN:
+ begin
+ reg_rdata_r[`USB_XFER_TOKEN_IN_R] = usb_xfer_token_in_q;
+ reg_rdata_r[`USB_XFER_TOKEN_ACK_R] = usb_xfer_token_ack_q;
+ reg_rdata_r[`USB_XFER_TOKEN_PID_DATAX_R] = usb_xfer_token_pid_datax_q;
+ reg_rdata_r[`USB_XFER_TOKEN_PID_BITS_R] = usb_xfer_token_pid_bits_q;
+ reg_rdata_r[`USB_XFER_TOKEN_DEV_ADDR_R] = usb_xfer_token_dev_addr_q;
+ reg_rdata_r[`USB_XFER_TOKEN_EP_ADDR_R] = usb_xfer_token_ep_addr_q;
+ end
+ `USB_RX_STAT:
+ begin
+ reg_rdata_r[`USB_RX_STAT_START_PEND_R] = usb_rx_stat_start_pend_in_w;
+ reg_rdata_r[`USB_RX_STAT_CRC_ERR_R] = usb_rx_stat_crc_err_in_w;
+ reg_rdata_r[`USB_RX_STAT_RESP_TIMEOUT_R] = usb_rx_stat_resp_timeout_in_w;
+ reg_rdata_r[`USB_RX_STAT_IDLE_R] = usb_rx_stat_idle_in_w;
+ reg_rdata_r[`USB_RX_STAT_RESP_BITS_R] = usb_rx_stat_resp_bits_in_w;
+ reg_rdata_r[`USB_RX_STAT_COUNT_BITS_R] = usb_rx_stat_count_bits_in_w;
+ end
+ `USB_RD_DATA:
+ begin
+ reg_rdata_r[`USB_RD_DATA_DATA_R] = usb_rd_data_data_in_w;
+ end
+ default :
+ reg_rdata_r = 32'b0;
+ endcase
+end
+
+//-----------------------------------------------------------------
+// Register usb_rd_data
+//-----------------------------------------------------------------
+reg usb_rd_data_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_rd_data_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_RD_DATA))
+ usb_rd_data_wr_q <= 1'b1;
+else
+ usb_rd_data_wr_q <= 1'b0;
+
+
+
+wire usb_rd_data_rd_req_w = reg_cs & (reg_wr==0) & (!reg_ack) & (reg_addr[5:0] == `USB_RD_DATA);
+
+wire usb_wr_data_wr_req_w = usb_wr_data_wr_q;
+wire usb_rd_data_wr_req_w = usb_rd_data_wr_q;
+
+//-----------------------------------------------------------------
+// Registers / Wires
+//-----------------------------------------------------------------
+// SOF
+reg [10:0] sof_value_q;
+reg [15:0] sof_time_q;
+reg sof_irq_q;
+
+reg transfer_req_ack_q;
+
+wire [7:0] fifo_tx_data_w;
+wire fifo_tx_pop_w;
+
+wire [7:0] fifo_rx_data_w;
+wire fifo_rx_push_w;
+
+reg fifo_flush_q;
+
+wire [7:0] token_pid_w;
+wire [6:0] token_dev_w;
+wire [3:0] token_ep_w;
+
+reg transfer_start_q;
+reg in_transfer_q;
+reg sof_transfer_q;
+reg resp_expected_q;
+wire transfer_ack_w;
+
+wire status_crc_err_w;
+wire status_timeout_w;
+wire [7:0] status_response_w;
+wire [15:0] status_rx_count_w;
+wire status_sie_idle_w;
+wire status_tx_done_w;
+wire status_rx_done_w;
+
+wire send_sof_w;
+wire sof_gaurd_band_w;
+wire clear_to_send_w;
+
+reg usb_err_q;
+
+reg intr_done_q;
+reg intr_sof_q;
+reg intr_err_q;
+
+//-----------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------
+localparam SOF_ZERO = 0;
+localparam SOF_INC = 1;
+localparam SOF_THRESHOLD = (USB_CLK_FREQ/1000)-1;
+
+localparam CLKS_PER_BIT = (USB_CLK_FREQ / 12000000); // input clks per FS bit time
+
+localparam EOF1_THRESHOLD = (50 * CLKS_PER_BIT); // EOF1 + some margin
+localparam MAX_XFER_SIZE = 64;
+localparam MAX_XFER_PERIOD = ((MAX_XFER_SIZE + 6) * 10 * CLKS_PER_BIT); // Max packet transfer time (+ margin)
+localparam SOF_GAURD_LOW = (20 * CLKS_PER_BIT);
+localparam SOF_GAURD_HIGH = SOF_THRESHOLD - EOF1_THRESHOLD - MAX_XFER_PERIOD;
+
+localparam PID_SOF = 8'hA5;
+
+//-----------------------------------------------------------------
+// SIE
+//-----------------------------------------------------------------
+usbh_sie
+#( .USB_CLK_FREQ(USB_CLK_FREQ) )
+u_sie
+(
+ // Clock & reset
+ .clk_i(clk_i),
+ .rstn_i(rstn_i),
+
+ // Control
+ .start_i(transfer_start_q),
+ .in_transfer_i(in_transfer_q),
+ .sof_transfer_i(sof_transfer_q),
+ .resp_expected_i(resp_expected_q),
+ .ack_o(transfer_ack_w),
+
+ // Token packet
+ .token_pid_i(token_pid_w),
+ .token_dev_i(token_dev_w),
+ .token_ep_i(token_ep_w),
+
+ // Data packet
+ .data_len_i(usb_xfer_data_tx_len_out_w),
+ .data_idx_i(usb_xfer_token_pid_datax_out_w),
+
+ // Tx Data FIFO
+ .tx_data_i(fifo_tx_data_w),
+ .tx_pop_o(fifo_tx_pop_w),
+
+ // Rx Data FIFO
+ .rx_data_o(fifo_rx_data_w),
+ .rx_push_o(fifo_rx_push_w),
+
+ // Status
+ .rx_done_o(status_rx_done_w),
+ .tx_done_o(status_tx_done_w),
+ .crc_err_o(status_crc_err_w),
+ .timeout_o(status_timeout_w),
+ .response_o(status_response_w),
+ .rx_count_o(status_rx_count_w),
+ .idle_o(status_sie_idle_w),
+
+ // UTMI Interface
+ .utmi_data_o(utmi_data_out_o),
+ .utmi_txvalid_o(utmi_txvalid_o),
+ .utmi_txready_i(utmi_txready_i),
+ .utmi_data_i(utmi_data_in_i),
+ .utmi_rxvalid_i(utmi_rxvalid_i),
+ .utmi_rxactive_i(utmi_rxactive_i),
+ .utmi_linestate_i(utmi_linestate_i)
+);
+
+//-----------------------------------------------------------------
+// Peripheral Interface
+//-----------------------------------------------------------------
+assign usb_status_sof_time_in_w = sof_time_q;
+assign usb_status_rx_error_in_w = usb_err_q;
+assign usb_status_linestate_bits_in_w = utmi_linestate_i;
+
+assign usb_irq_sts_err_in_w = intr_err_q;
+assign usb_irq_sts_done_in_w = intr_done_q;
+assign usb_irq_sts_sof_in_w = intr_sof_q;
+
+assign usb_rx_stat_start_pend_in_w = usb_xfer_token_start_out_w;
+assign usb_rx_stat_crc_err_in_w = status_crc_err_w;
+assign usb_rx_stat_resp_timeout_in_w = status_timeout_w;
+assign usb_rx_stat_idle_in_w = status_sie_idle_w;
+assign usb_rx_stat_resp_bits_in_w = status_response_w;
+assign usb_rx_stat_count_bits_in_w = status_rx_count_w;
+
+assign usb_xfer_token_start_ack_in_w = transfer_req_ack_q;
+
+assign utmi_op_mode_o = usb_ctrl_phy_opmode_out_w;
+assign utmi_xcvrselect_o = usb_ctrl_phy_xcvrselect_out_w;
+assign utmi_termselect_o = usb_ctrl_phy_termselect_out_w;
+assign utmi_dppulldown_o = usb_ctrl_phy_dppulldown_out_w;
+assign utmi_dmpulldown_o = usb_ctrl_phy_dmpulldown_out_w;
+
+//-----------------------------------------------------------------
+// Tx FIFO (Host -> Device)
+//-----------------------------------------------------------------
+usbh_fifo
+u_fifo_tx
+(
+ .clk_i(clk_i),
+ .rstn_i(rstn_i),
+
+ .data_i(usb_wr_data_data_out_w),
+ .push_i(usb_wr_data_wr_req_w),
+
+ .flush_i(usb_ctrl_tx_flush_out_w),
+
+ .full_o(),
+ .empty_o(),
+
+ .data_o(fifo_tx_data_w),
+ .pop_i(fifo_tx_pop_w)
+);
+
+//-----------------------------------------------------------------
+// Rx FIFO (Device -> Host)
+//-----------------------------------------------------------------
+usbh_fifo
+u_fifo_rx
+(
+ .clk_i(clk_i),
+ .rstn_i(rstn_i),
+
+ // Receive from UTMI interface
+ .data_i(fifo_rx_data_w),
+ .push_i(fifo_rx_push_w),
+
+ .flush_i(fifo_flush_q),
+
+ .full_o(),
+ .empty_o(),
+
+ .data_o(usb_rd_data_data_in_w),
+ .pop_i(usb_rd_data_rd_req_w)
+);
+
+//-----------------------------------------------------------------
+// Assignments
+//-----------------------------------------------------------------
+assign send_sof_w = ({16'b0, sof_time_q} == SOF_THRESHOLD && usb_ctrl_enable_sof_out_w) & status_sie_idle_w;
+assign sof_gaurd_band_w = ({16'b0, sof_time_q} <= SOF_GAURD_LOW || {16'b0, sof_time_q} >= SOF_GAURD_HIGH);
+assign clear_to_send_w = (~sof_gaurd_band_w | ~usb_ctrl_enable_sof_out_w) & status_sie_idle_w;
+
+assign token_pid_w = sof_transfer_q ? PID_SOF : usb_xfer_token_pid_bits_out_w;
+
+assign token_dev_w = sof_transfer_q ?
+ {sof_value_q[0], sof_value_q[1], sof_value_q[2],
+ sof_value_q[3], sof_value_q[4], sof_value_q[5], sof_value_q[6]} :
+ {usb_xfer_token_dev_addr_out_w[0], usb_xfer_token_dev_addr_out_w[1], usb_xfer_token_dev_addr_out_w[2], usb_xfer_token_dev_addr_out_w[3], usb_xfer_token_dev_addr_out_w[4], usb_xfer_token_dev_addr_out_w[5], usb_xfer_token_dev_addr_out_w[6]};
+
+assign token_ep_w = sof_transfer_q ?
+ {sof_value_q[7], sof_value_q[8], sof_value_q[9], sof_value_q[10]} :
+ {usb_xfer_token_ep_addr_out_w[0], usb_xfer_token_ep_addr_out_w[1], usb_xfer_token_ep_addr_out_w[2], usb_xfer_token_ep_addr_out_w[3]};
+
+//-----------------------------------------------------------------
+// Control logic
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ fifo_flush_q <= 1'b0;
+ transfer_start_q <= 1'b0;
+ sof_transfer_q <= 1'b0;
+ transfer_req_ack_q <= 1'b0;
+ in_transfer_q <= 1'b0;
+ resp_expected_q <= 1'b0;
+end
+else
+begin
+ // Transfer in progress?
+ if (transfer_start_q)
+ begin
+ // Transfer accepted
+ if (transfer_ack_w)
+ transfer_start_q <= 1'b0;
+
+ fifo_flush_q <= 1'b0;
+ transfer_req_ack_q <= 1'b0;
+ end
+ // Time to send another SOF token?
+ else if (send_sof_w)
+ begin
+ // Start transfer
+ in_transfer_q <= 1'b0;
+ resp_expected_q <= 1'b0;
+ transfer_start_q <= 1'b1;
+ sof_transfer_q <= 1'b1;
+ end
+ // Not in SOF gaurd band region or SOF disabled?
+ else if (clear_to_send_w)
+ begin
+ // Transfer request
+ if (usb_xfer_token_start_out_w)
+ begin
+ // Flush un-used previous Rx data
+ fifo_flush_q <= 1'b1;
+
+ // Start transfer
+ in_transfer_q <= usb_xfer_token_in_out_w;
+ resp_expected_q <= usb_xfer_token_ack_out_w;
+ transfer_start_q <= 1'b1;
+ sof_transfer_q <= 1'b0;
+ transfer_req_ack_q <= 1'b1;
+ end
+ end
+end
+
+//-----------------------------------------------------------------
+// SOF Frame Number
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ sof_value_q <= 11'd0;
+ sof_time_q <= SOF_ZERO;
+ sof_irq_q <= 1'b0;
+end
+// Time to send another SOF token?
+else if (send_sof_w)
+begin
+ sof_time_q <= SOF_ZERO;
+ sof_value_q <= sof_value_q + 11'd1;
+
+ // Start of frame interrupt
+ sof_irq_q <= 1'b1;
+end
+else
+begin
+ // Increment the SOF timer
+ if ({16'b0, sof_time_q} != SOF_THRESHOLD)
+ sof_time_q <= sof_time_q + SOF_INC;
+
+ sof_irq_q <= 1'b0;
+end
+
+//-----------------------------------------------------------------
+// Record Errors
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_err_q <= 1'b0;
+// Clear error
+else if (usb_ctrl_wr_q)
+ usb_err_q <= 1'b0;
+// Record bus errors
+else if (utmi_rxerror_i)
+ usb_err_q <= 1'b1;
+
+//-----------------------------------------------------------------
+// Interrupts
+//-----------------------------------------------------------------
+reg err_cond_q;
+reg intr_q;
+reg device_det_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ intr_done_q <= 1'b0;
+ intr_sof_q <= 1'b0;
+ intr_err_q <= 1'b0;
+ err_cond_q <= 1'b0;
+ device_det_q <= 1'b0;
+ intr_q <= 1'b0;
+end
+else
+begin
+ if (status_rx_done_w || status_tx_done_w)
+ intr_done_q <= 1'b1;
+ else if (usb_irq_ack_done_out_w)
+ intr_done_q <= 1'b0;
+
+ if (sof_irq_q)
+ intr_sof_q <= 1'b1;
+ else if (usb_irq_ack_sof_out_w)
+ intr_sof_q <= 1'b0;
+
+ if ((status_crc_err_w || status_timeout_w) && (!err_cond_q))
+ intr_err_q <= 1'b1;
+ else if (usb_irq_ack_err_out_w)
+ intr_err_q <= 1'b0;
+
+ // Line state != SE0
+ if (utmi_linestate_i != 2'b0)
+ device_det_q <= 1'b1;
+ else if (usb_irq_ack_device_detect_out_w)
+ device_det_q <= 1'b0;
+
+ err_cond_q <= (status_crc_err_w | status_timeout_w);
+
+ intr_q <= (intr_done_q & usb_irq_mask_done_out_w) |
+ (intr_err_q & usb_irq_mask_err_out_w) |
+ (intr_sof_q & usb_irq_mask_sof_out_w) |
+ (device_det_q & usb_irq_mask_device_detect_out_w);
+end
+
+assign usb_irq_sts_device_detect_in_w = 1'b0;
+
+assign intr_o = intr_q;
+
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/core/usbh_crc16.sv b/verilog/rtl/usb1_host/src/core/usbh_crc16.sv
new file mode 100644
index 0000000..11f767c
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_crc16.sv
@@ -0,0 +1,89 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+//-----------------------------------------------------------------
+// Module: 16-bit CRC used by USB data packets
+//-----------------------------------------------------------------
+module usbh_crc16
+(
+ input [15:0] crc_i,
+ input [7:0] data_i,
+ output [15:0] crc_o
+);
+
+//-----------------------------------------------------------------
+// Implementation
+//-----------------------------------------------------------------
+assign crc_o[15] = data_i[0] ^ data_i[1] ^ data_i[2] ^ data_i[3] ^ data_i[4] ^
+ data_i[5] ^ data_i[6] ^ data_i[7] ^ crc_i[7] ^ crc_i[6] ^
+ crc_i[5] ^ crc_i[4] ^ crc_i[3] ^ crc_i[2] ^
+ crc_i[1] ^ crc_i[0];
+assign crc_o[14] = data_i[0] ^ data_i[1] ^ data_i[2] ^ data_i[3] ^ data_i[4] ^ data_i[5] ^
+ data_i[6] ^ crc_i[6] ^ crc_i[5] ^ crc_i[4] ^
+ crc_i[3] ^ crc_i[2] ^ crc_i[1] ^ crc_i[0];
+assign crc_o[13] = data_i[6] ^ data_i[7] ^ crc_i[7] ^ crc_i[6];
+assign crc_o[12] = data_i[5] ^ data_i[6] ^ crc_i[6] ^ crc_i[5];
+assign crc_o[11] = data_i[4] ^ data_i[5] ^ crc_i[5] ^ crc_i[4];
+assign crc_o[10] = data_i[3] ^ data_i[4] ^ crc_i[4] ^ crc_i[3];
+assign crc_o[9] = data_i[2] ^ data_i[3] ^ crc_i[3] ^ crc_i[2];
+assign crc_o[8] = data_i[1] ^ data_i[2] ^ crc_i[2] ^ crc_i[1];
+assign crc_o[7] = data_i[0] ^ data_i[1] ^ crc_i[15] ^ crc_i[1] ^ crc_i[0];
+assign crc_o[6] = data_i[0] ^ crc_i[14] ^ crc_i[0];
+assign crc_o[5] = crc_i[13];
+assign crc_o[4] = crc_i[12];
+assign crc_o[3] = crc_i[11];
+assign crc_o[2] = crc_i[10];
+assign crc_o[1] = crc_i[9];
+assign crc_o[0] = data_i[0] ^ data_i[1] ^ data_i[2] ^ data_i[3] ^ data_i[4] ^ data_i[5] ^
+ data_i[6] ^ data_i[7] ^ crc_i[8] ^ crc_i[7] ^ crc_i[6] ^
+ crc_i[5] ^ crc_i[4] ^ crc_i[3] ^ crc_i[2] ^
+ crc_i[1] ^ crc_i[0];
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/core/usbh_crc5.sv b/verilog/rtl/usb1_host/src/core/usbh_crc5.sv
new file mode 100644
index 0000000..f125905
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_crc5.sv
@@ -0,0 +1,79 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+//-----------------------------------------------------------------
+// Module: 5-bit CRC used by USB tokens
+//-----------------------------------------------------------------
+module usbh_crc5
+(
+ input [4:0] crc_i,
+ input [10:0] data_i,
+ output [4:0] crc_o
+);
+
+//-----------------------------------------------------------------
+// Implementation
+//-----------------------------------------------------------------
+assign crc_o[0] = data_i[10] ^ data_i[9] ^ data_i[6] ^ data_i[5] ^ data_i[3] ^ data_i[0] ^
+ crc_i[0] ^ crc_i[3] ^ crc_i[4];
+
+assign crc_o[1] = data_i[10] ^ data_i[7] ^ data_i[6] ^ data_i[4] ^ data_i[1] ^
+ crc_i[0] ^ crc_i[1] ^ crc_i[4];
+
+assign crc_o[2] = data_i[10] ^ data_i[9] ^ data_i[8] ^ data_i[7] ^ data_i[6] ^ data_i[3] ^ data_i[2] ^ data_i[0] ^
+ crc_i[0] ^ crc_i[1] ^ crc_i[2] ^ crc_i[3] ^ crc_i[4];
+
+assign crc_o[3] = data_i[10] ^ data_i[9] ^ data_i[8] ^ data_i[7] ^ data_i[4] ^ data_i[3] ^ data_i[1] ^
+ crc_i[1] ^ crc_i[2] ^ crc_i[3] ^ crc_i[4];
+
+assign crc_o[4] = data_i[10] ^ data_i[9] ^ data_i[8] ^ data_i[5] ^ data_i[4] ^ data_i[2] ^
+ crc_i[2] ^ crc_i[3] ^ crc_i[4];
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/core/usbh_fifo.sv b/verilog/rtl/usb1_host/src/core/usbh_fifo.sv
new file mode 100644
index 0000000..67113c3
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_fifo.sv
@@ -0,0 +1,143 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+module usbh_fifo
+(
+ // Inputs
+ input clk_i
+ ,input rstn_i
+ ,input [ 7:0] data_i
+ ,input push_i
+ ,input pop_i
+ ,input flush_i
+
+ // Outputs
+ ,output full_o
+ ,output empty_o
+ ,output [ 7:0] data_o
+);
+
+
+
+parameter WIDTH = 8;
+parameter DEPTH = 64;
+parameter ADDR_W = 6;
+
+//-----------------------------------------------------------------
+// Local Params
+//-----------------------------------------------------------------
+localparam COUNT_W = ADDR_W + 1;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+reg [WIDTH-1:0] ram [DEPTH-1:0];
+reg [ADDR_W-1:0] rd_ptr;
+reg [ADDR_W-1:0] wr_ptr;
+reg [COUNT_W-1:0] count;
+
+//-----------------------------------------------------------------
+// Sequential
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ count <= {(COUNT_W) {1'b0}};
+ rd_ptr <= {(ADDR_W) {1'b0}};
+ wr_ptr <= {(ADDR_W) {1'b0}};
+end
+else
+begin
+
+ if (flush_i)
+ begin
+ count <= {(COUNT_W) {1'b0}};
+ rd_ptr <= {(ADDR_W) {1'b0}};
+ wr_ptr <= {(ADDR_W) {1'b0}};
+ end
+
+ // Push
+ if (push_i & ~full_o)
+ begin
+ ram[wr_ptr] <= data_i;
+ wr_ptr <= wr_ptr + 1;
+ end
+
+ // Pop
+ if (pop_i & ~empty_o)
+ begin
+ rd_ptr <= rd_ptr + 1;
+ end
+
+ // Count up
+ if ((push_i & ~full_o) & ~(pop_i & ~empty_o))
+ begin
+ count <= count + 1;
+ end
+ // Count down
+ else if (~(push_i & ~full_o) & (pop_i & ~empty_o))
+ begin
+ count <= count - 1;
+ end
+end
+
+//-------------------------------------------------------------------
+// Combinatorial
+//-------------------------------------------------------------------
+/* verilator lint_off WIDTH */
+assign full_o = (count == DEPTH);
+assign empty_o = (count == 0);
+/* verilator lint_on WIDTH */
+
+assign data_o = ram[rd_ptr];
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/core/usbh_sie.sv b/verilog/rtl/usb1_host/src/core/usbh_sie.sv
new file mode 100644
index 0000000..0d046c0
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_sie.sv
@@ -0,0 +1,846 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+module usbh_sie
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+#(
+ parameter USB_CLK_FREQ = 48000000
+)
+//-----------------------------------------------------------------
+// Ports
+//-----------------------------------------------------------------
+(
+ // Inputs
+ input clk_i,
+ input rstn_i,
+ input start_i,
+ input in_transfer_i,
+ input sof_transfer_i,
+ input resp_expected_i,
+ input [ 7:0] token_pid_i,
+ input [ 6:0] token_dev_i,
+ input [ 3:0] token_ep_i,
+ input [ 15:0] data_len_i,
+ input data_idx_i,
+ input [ 7:0] tx_data_i,
+ input utmi_txready_i,
+ input [ 7:0] utmi_data_i,
+ input utmi_rxvalid_i,
+ input utmi_rxactive_i,
+ input [ 1:0] utmi_linestate_i,
+
+ // Outputs
+ output ack_o,
+ output tx_pop_o,
+ output [ 7:0] rx_data_o,
+ output rx_push_o,
+ output tx_done_o,
+ output rx_done_o,
+ output crc_err_o,
+ output timeout_o,
+ output [ 7:0] response_o,
+ output [ 15:0] rx_count_o,
+ output idle_o,
+ output [ 7:0] utmi_data_o,
+ output utmi_txvalid_o
+);
+
+
+
+//-----------------------------------------------------------------
+// Registers / Wires
+//-----------------------------------------------------------------
+logic start_ack_q;
+
+// Status
+logic status_tx_done_q;
+logic status_rx_done_q;
+logic status_crc_err_q;
+logic status_timeout_q;
+logic [7:0] status_response_q;
+
+logic [15:0] byte_count_q;
+logic in_transfer_q;
+
+logic [8:0] last_tx_time_q;
+
+logic send_data1_q;
+logic send_sof_q;
+logic send_ack_q;
+
+// CRC16
+logic [15:0] crc_sum_q;
+logic [15:0] crc_out_w;
+logic [7:0] crc_data_in_w;
+
+// CRC5
+logic [4:0] crc5_out_w;
+wire [4:0] crc5_next_w = crc5_out_w ^ 5'h1F;
+
+logic [15:0] token_q;
+
+logic wait_resp_q;
+
+logic [3:0] state_q;
+
+//-----------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------
+localparam RX_TIMEOUT = (USB_CLK_FREQ == 60000000) ? 9'd511 : 9'd255;
+ // 2 FS bit times (x5 CLKs @ 60MHz, x4 CLKs @ 48MHz)
+localparam TX_IFS = (USB_CLK_FREQ == 60000000) ? 4'd10 : 4'd7;
+
+localparam PID_OUT = 8'hE1;
+localparam PID_IN = 8'h69;
+localparam PID_SOF = 8'hA5;
+localparam PID_SETUP = 8'h2D;
+
+localparam PID_DATA0 = 8'hC3;
+localparam PID_DATA1 = 8'h4B;
+
+localparam PID_ACK = 8'hD2;
+localparam PID_NAK = 8'h5A;
+localparam PID_STALL = 8'h1E;
+
+// States
+localparam STATE_IDLE = 4'd0;
+localparam STATE_RX_DATA = 4'd1;
+localparam STATE_TX_PID = 4'd2;
+localparam STATE_TX_DATA = 4'd3;
+localparam STATE_TX_CRC1 = 4'd4;
+localparam STATE_TX_CRC2 = 4'd5;
+localparam STATE_TX_TOKEN1 = 4'd6;
+localparam STATE_TX_TOKEN2 = 4'd7;
+localparam STATE_TX_TOKEN3 = 4'd8;
+localparam STATE_TX_ACKNAK = 4'd9;
+localparam STATE_TX_WAIT = 4'd10;
+localparam STATE_RX_WAIT = 4'd11;
+localparam STATE_TX_IFS = 4'd12;
+
+//-----------------------------------------------------------------
+// Wires
+//-----------------------------------------------------------------
+// Rx data
+logic [7:0] rx_data_w;
+logic data_ready_w;
+logic crc_byte_w;
+logic rx_active_w;
+logic rx_active_rise_w;
+
+// Tx/Rx -> Tx IFS timeout
+logic ifs_busy_w;
+
+// Response timeout (no response after 500uS from transmit)
+wire rx_resp_timeout_w = (last_tx_time_q >= RX_TIMEOUT) & wait_resp_q;
+
+// CRC16 error on received data
+wire crc_error_w = (state_q == STATE_RX_DATA) && !rx_active_w && in_transfer_q &&
+ (status_response_q == PID_DATA0 || status_response_q == PID_DATA1) &&
+ (crc_sum_q != 16'hB001);
+
+//-----------------------------------------------------------------
+// State Machine
+//-----------------------------------------------------------------
+logic [3:0] next_state_r;
+
+always @ *
+begin
+ next_state_r = state_q;
+
+ //-----------------------------------------
+ // Tx State Machine
+ //-----------------------------------------
+ case (state_q)
+
+ //-----------------------------------------
+ // TX_TOKEN1 (byte 1 of token)
+ //-----------------------------------------
+ STATE_TX_TOKEN1 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ next_state_r = STATE_TX_TOKEN2;
+ end
+ //-----------------------------------------
+ // TX_TOKEN2 (byte 2 of token)
+ //-----------------------------------------
+ STATE_TX_TOKEN2 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ next_state_r = STATE_TX_TOKEN3;
+ end
+ //-----------------------------------------
+ // TX_TOKEN3 (byte 3 of token)
+ //-----------------------------------------
+ STATE_TX_TOKEN3 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ begin
+ // SOF - no data packet
+ if (send_sof_q)
+ next_state_r = STATE_TX_IFS;
+ // IN - wait for data
+ else if (in_transfer_q)
+ next_state_r = STATE_RX_WAIT;
+ // OUT/SETUP - Send data or ZLP
+ else
+ next_state_r = STATE_TX_IFS;
+ end
+ end
+ //-----------------------------------------
+ // TX_IFS
+ //-----------------------------------------
+ STATE_TX_IFS :
+ begin
+ // IFS expired
+ if (~ifs_busy_w)
+ begin
+ // SOF - no data packet
+ if (send_sof_q)
+ next_state_r = STATE_IDLE;
+ // OUT/SETUP - Send data or ZLP
+ else
+ next_state_r = STATE_TX_PID;
+ end
+ end
+ //-----------------------------------------
+ // TX_PID
+ //-----------------------------------------
+ STATE_TX_PID :
+ begin
+ // Last data byte sent?
+ if (utmi_txready_i && (byte_count_q == 16'b0))
+ next_state_r = STATE_TX_CRC1;
+ else if (utmi_txready_i)
+ next_state_r = STATE_TX_DATA;
+ end
+ //-----------------------------------------
+ // TX_DATA
+ //-----------------------------------------
+ STATE_TX_DATA :
+ begin
+ // Last data byte sent?
+ if (utmi_txready_i && (byte_count_q == 16'b0))
+ next_state_r = STATE_TX_CRC1;
+ end
+ //-----------------------------------------
+ // TX_CRC1 (first byte)
+ //-----------------------------------------
+ STATE_TX_CRC1 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ next_state_r = STATE_TX_CRC2;
+ end
+ //-----------------------------------------
+ // TX_CRC (second byte)
+ //-----------------------------------------
+ STATE_TX_CRC2 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ begin
+ // If a response is expected
+ if (wait_resp_q)
+ next_state_r = STATE_RX_WAIT;
+ // No response expected (e.g ISO transfer)
+ else
+ next_state_r = STATE_IDLE;
+ end
+ end
+ //-----------------------------------------
+ // STATE_TX_WAIT
+ //-----------------------------------------
+ STATE_TX_WAIT :
+ begin
+ // Waited long enough?
+ if (~ifs_busy_w)
+ next_state_r = STATE_TX_ACKNAK;
+ end
+ //-----------------------------------------
+ // STATE_TX_ACKNAK
+ //-----------------------------------------
+ STATE_TX_ACKNAK :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_WAIT
+ //-----------------------------------------
+ STATE_RX_WAIT :
+ begin
+ // Data received?
+ if (data_ready_w)
+ next_state_r = STATE_RX_DATA;
+ // Waited long enough?
+ else if (rx_resp_timeout_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // RX_DATA
+ //-----------------------------------------
+ STATE_RX_DATA :
+ begin
+ // Receive complete
+ if (~rx_active_w)
+ begin
+ // Send ACK but incoming data had CRC error, do not ACK
+ if (send_ack_q && crc_error_w)
+ next_state_r = STATE_IDLE;
+ // Send an ACK response without CPU interaction?
+ else if (send_ack_q && (status_response_q == PID_DATA0 || status_response_q == PID_DATA1))
+ next_state_r = STATE_TX_WAIT;
+ else
+ next_state_r = STATE_IDLE;
+ end
+ end
+ //-----------------------------------------
+ // IDLE / RECEIVE BEGIN
+ //-----------------------------------------
+ STATE_IDLE :
+ begin
+ // Token transfer request
+ if (start_i)
+ next_state_r = STATE_TX_TOKEN1;
+ end
+ default :
+ ;
+ endcase
+end
+
+// Update state
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ state_q <= STATE_IDLE;
+else
+ state_q <= next_state_r;
+
+//-----------------------------------------------------------------
+// Tx Token
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ token_q <= 16'h0000;
+else if (state_q == STATE_IDLE)
+ token_q <= {token_dev_i, token_ep_i, 5'b0};
+// PID of token sent, capture calculated CRC for token packet
+else if (state_q == STATE_TX_TOKEN1 && utmi_txready_i)
+ token_q[4:0] <= crc5_next_w;
+
+//-----------------------------------------------------------------
+// Tx EOP - detect end of transmit (token, data or ACK/NAK)
+//-----------------------------------------------------------------
+reg [1:0] utmi_linestate_q;
+reg se0_detect_q;
+reg wait_eop_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ utmi_linestate_q <= 2'b0;
+else
+ utmi_linestate_q <= utmi_linestate_i;
+
+// SE0 filtering (2 cycles FS)
+wire se0_detect_w = (utmi_linestate_q == 2'b00 && utmi_linestate_i == 2'b00);
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ se0_detect_q <= 1'b0;
+else
+ se0_detect_q <= se0_detect_w;
+
+// TODO: This needs updating for HS USB...
+wire eop_detected_w = se0_detect_q & (utmi_linestate_i != 2'b00);
+
+// End of transmit detection
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ wait_eop_q <= 1'b0;
+else if (eop_detected_w)
+ wait_eop_q <= 1'b0;
+else if ((state_q == STATE_TX_CRC2 && next_state_r != STATE_TX_CRC2) ||
+ (state_q == STATE_TX_TOKEN3 && next_state_r != STATE_TX_TOKEN3) ||
+ (state_q == STATE_TX_ACKNAK && next_state_r != STATE_TX_ACKNAK))
+ wait_eop_q <= 1'b1;
+else if (rx_active_rise_w)
+ wait_eop_q <= 1'b1;
+
+localparam TX_IFS_W = 4;
+reg [TX_IFS_W-1:0] tx_ifs_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ tx_ifs_q <= {(TX_IFS_W){1'b0}};
+// Start counting down from last Tx or EOP being detected at end of Rx
+else if (wait_eop_q || eop_detected_w)
+ tx_ifs_q <= TX_IFS;
+// Decrement IFS counter
+else if (tx_ifs_q != {(TX_IFS_W){1'b0}})
+ tx_ifs_q <= tx_ifs_q - 1;
+
+assign ifs_busy_w = wait_eop_q || (tx_ifs_q != {(TX_IFS_W){1'b0}});
+
+//-----------------------------------------------------------------
+// Tx Timer
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ last_tx_time_q <= 9'd0;
+// Start counting from last Tx
+else if (state_q == STATE_IDLE || (utmi_txvalid_o && utmi_txready_i))
+ last_tx_time_q <= 9'd0;
+// Increment the Tx timeout
+else if (last_tx_time_q != RX_TIMEOUT)
+ last_tx_time_q <= last_tx_time_q + 9'd1;
+
+//-----------------------------------------------------------------
+// Transmit / Receive counter
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ byte_count_q <= 16'h0000;
+// New transfer request (not automatic SOF request)
+else if (state_q == STATE_IDLE && start_i && !sof_transfer_i)
+ byte_count_q <= data_len_i;
+else if (state_q == STATE_RX_WAIT)
+ byte_count_q <= 16'h0000;
+// Transmit byte
+else if ((state_q == STATE_TX_PID || state_q == STATE_TX_DATA) && utmi_txready_i)
+begin
+ // Count down data left to send
+ if (byte_count_q != 16'd0)
+ byte_count_q <= byte_count_q - 16'd1;
+end
+// Received byte
+else if (state_q == STATE_RX_DATA && data_ready_w && !crc_byte_w)
+ byte_count_q <= byte_count_q + 16'd1;
+
+//-----------------------------------------------------------------
+// Transfer start ack
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ start_ack_q <= 1'b0;
+// First byte of PID sent, ack transfer request
+else if (state_q == STATE_TX_TOKEN1 && utmi_txready_i)
+ start_ack_q <= 1'b1;
+else
+ start_ack_q <= 1'b0;
+
+//-----------------------------------------------------------------
+// Record request details
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ in_transfer_q <= 1'b0;
+ send_ack_q <= 1'b0;
+ send_data1_q <= 1'b0;
+ send_sof_q <= 1'b0;
+end
+// Start of new request
+else if (state_q == STATE_IDLE && start_i)
+begin
+ // Transfer request
+ // e.g. (H)SOF [sof_transfer_i]
+ // (H)OUT + (H)DATA + (F)ACK/NACK/STALL [data_len_i >= 0 && !in_transfer_i]
+ // (H)IN + (F)DATA + (H)ACK [in_transfer_i]
+ // (H)IN + (F)NAK/STALL [in_transfer_i]
+ in_transfer_q <= in_transfer_i;
+
+ // Send ACK in response to IN DATA
+ send_ack_q <= in_transfer_i && resp_expected_i;
+
+ // DATA0/1
+ send_data1_q <= data_idx_i;
+
+ send_sof_q <= sof_transfer_i;
+end
+
+//-----------------------------------------------------------------
+// Response expected
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ wait_resp_q <= 1'b0;
+// Incoming data
+else if (state_q == STATE_RX_WAIT && data_ready_w)
+ wait_resp_q <= 1'b0;
+else if (state_q == STATE_IDLE && start_i)
+ wait_resp_q <= resp_expected_i;
+
+//-----------------------------------------------------------------
+// Status
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+begin
+ if (!rstn_i)
+ begin
+ status_response_q <= 8'h00;
+ status_timeout_q <= 1'b0;
+ status_rx_done_q <= 1'b0;
+ status_tx_done_q <= 1'b0;
+ end
+ else
+ begin
+ case (state_q)
+
+ //-----------------------------------------
+ // RX_WAIT
+ //-----------------------------------------
+ STATE_RX_WAIT :
+ begin
+ // Store response PID
+ if (data_ready_w)
+ status_response_q <= rx_data_w;
+
+ // Waited long enough?
+ if (rx_resp_timeout_w)
+ status_timeout_q <= 1'b1;
+
+ status_tx_done_q <= 1'b0;
+ end
+ //-----------------------------------------
+ // RX_DATA
+ //-----------------------------------------
+ STATE_RX_DATA :
+ begin
+ // Receive complete
+ if (!utmi_rxactive_i)
+ status_rx_done_q <= 1'b1;
+ else
+ status_rx_done_q <= 1'b0;
+ end
+ //-----------------------------------------
+ // TX_CRC (second byte)
+ //-----------------------------------------
+ STATE_TX_CRC2 :
+ begin
+ // Data sent?
+ if (utmi_txready_i && !wait_resp_q)
+ begin
+ // Transfer now complete
+ status_tx_done_q <= 1'b1;
+ end
+ end
+ //-----------------------------------------
+ // IDLE / RECEIVE BEGIN
+ //-----------------------------------------
+ STATE_IDLE :
+ begin
+ // Transfer request
+ // e.g. (H)SOF [sof_transfer_i]
+ // (H)OUT + (H)DATA + (F)ACK/NACK/STALL [data_len_i >= 0 && !in_transfer_i]
+ // (H)IN + (F)DATA + (H)ACK [in_transfer_i]
+ // (H)IN + (F)NAK/STALL [in_transfer_i]
+ if (start_i && !sof_transfer_i) // (not automatic SOF request)
+ begin
+ // Clear status
+ status_response_q <= 8'h00;
+ status_timeout_q <= 1'b0;
+ end
+
+ status_rx_done_q <= 1'b0;
+ status_tx_done_q <= 1'b0;
+ end
+ //-----------------------------------------
+ // DEFAULT
+ //-----------------------------------------
+ default :
+ begin
+ status_rx_done_q <= 1'b0;
+ status_tx_done_q <= 1'b0;
+ end
+ endcase
+ end
+end
+
+
+//-----------------------------------------------------------------
+// Data delay (to strip the CRC16 trailing bytes)
+//-----------------------------------------------------------------
+reg [31:0] data_buffer_q;
+reg [3:0] data_valid_q;
+reg [3:0] rx_active_q;
+
+wire shift_en_w = (utmi_rxvalid_i & utmi_rxactive_i) || !utmi_rxactive_i;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ data_buffer_q <= 32'b0;
+else if (shift_en_w)
+ data_buffer_q <= {utmi_data_i, data_buffer_q[31:8]};
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ data_valid_q <= 4'b0;
+else if (shift_en_w)
+ data_valid_q <= {(utmi_rxvalid_i & utmi_rxactive_i), data_valid_q[3:1]};
+else
+ data_valid_q <= {data_valid_q[3:1], 1'b0};
+
+reg [1:0] data_crc_q;
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ data_crc_q <= 2'b0;
+else if (shift_en_w)
+ data_crc_q <= {!utmi_rxactive_i, data_crc_q[1]};
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rx_active_q <= 4'b0;
+else
+ rx_active_q <= {utmi_rxactive_i, rx_active_q[3:1]};
+
+assign rx_data_w = data_buffer_q[7:0];
+assign data_ready_w = data_valid_q[0];
+assign crc_byte_w = data_crc_q[0];
+assign rx_active_w = rx_active_q[0];
+
+assign rx_active_rise_w = !rx_active_q[3] && utmi_rxactive_i;
+
+//-----------------------------------------------------------------
+// CRC
+//-----------------------------------------------------------------
+
+// CRC16 (Data)
+usbh_crc16
+u_crc16
+(
+ .crc_i(crc_sum_q),
+ .data_i(crc_data_in_w),
+ .crc_o(crc_out_w)
+);
+
+// CRC5 (Token)
+usbh_crc5
+u_crc5
+(
+ .crc_i(5'h1F),
+ .data_i(token_q[15:5]),
+ .crc_o(crc5_out_w)
+);
+
+// CRC control / check
+always @ (posedge clk_i or negedge rstn_i)
+begin
+ if (!rstn_i)
+ begin
+ crc_sum_q <= 16'hFFFF;
+ status_crc_err_q <= 1'b0;
+ end
+ else
+ begin
+ case (state_q)
+ //-----------------------------------------
+ // TX_PID
+ //-----------------------------------------
+ STATE_TX_PID :
+ begin
+ // First byte is PID (not CRC'd), reset CRC16
+ crc_sum_q <= 16'hFFFF;
+ end
+ //-----------------------------------------
+ // TX_DATA
+ //-----------------------------------------
+ STATE_TX_DATA :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ begin
+ // Next CRC start value
+ crc_sum_q <= crc_out_w;
+ end
+ end
+ //-----------------------------------------
+ // RX_WAIT
+ //-----------------------------------------
+ STATE_RX_WAIT :
+ begin
+ // Reset CRC16
+ crc_sum_q <= 16'hFFFF;
+ end
+ //-----------------------------------------
+ // RX_DATA
+ //-----------------------------------------
+ STATE_RX_DATA :
+ begin
+ // Data received?
+ if (data_ready_w)
+ begin
+ // Next CRC start value
+ crc_sum_q <= crc_out_w;
+ end
+ // Receive complete
+ else if (!rx_active_w)
+ begin
+ // If some data received, check CRC
+ if (crc_error_w)
+ status_crc_err_q <= 1'b1;
+ else
+ status_crc_err_q <= 1'b0;
+ end
+ end
+
+ //-----------------------------------------
+ // IDLE / RECEIVE BEGIN
+ //-----------------------------------------
+ STATE_IDLE :
+ begin
+ // Start transfer request
+ if (start_i && !sof_transfer_i)
+ begin
+ // Clear error flag!
+ status_crc_err_q <= 1'b0;
+ end
+ end
+ default :
+ ;
+ endcase
+ end
+end
+
+//-----------------------------------------------------------------
+// Assignments
+//-----------------------------------------------------------------
+wire [15:0] token_rev_w;
+
+genvar i;
+generate
+for (i=0; i < 16; i=i+1)
+begin : LOOP
+ assign token_rev_w[i] = token_q[15-i];
+end
+endgenerate
+
+reg utmi_txvalid_r;
+reg [7:0] utmi_data_r;
+
+always @ *
+begin
+ if (state_q == STATE_TX_CRC1)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = crc_sum_q[7:0] ^ 8'hFF;
+ end
+ else if (state_q == STATE_TX_CRC2)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = crc_sum_q[15:8] ^ 8'hFF;
+ end
+ else if (state_q == STATE_TX_TOKEN1)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = token_pid_i;
+ end
+ else if (state_q == STATE_TX_TOKEN2)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = token_rev_w[7:0];
+ end
+ else if (state_q == STATE_TX_TOKEN3)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = token_rev_w[15:8];
+ end
+ else if (state_q == STATE_TX_PID)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = send_data1_q ? PID_DATA1 : PID_DATA0;
+ end
+ else if (state_q == STATE_TX_ACKNAK)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = PID_ACK;
+ end
+ else if (state_q == STATE_TX_DATA)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = tx_data_i;
+ end
+ else
+ begin
+ utmi_txvalid_r = 1'b0;
+ utmi_data_r = 8'b0;
+ end
+end
+
+assign utmi_txvalid_o = utmi_txvalid_r;
+assign utmi_data_o = utmi_data_r;
+
+// Push incoming data into FIFO (not PID or CRC)
+assign rx_data_o = rx_data_w;
+assign rx_push_o = (state_q != STATE_IDLE && state_q != STATE_RX_WAIT) & data_ready_w & !crc_byte_w;
+
+assign crc_data_in_w = (state_q == STATE_RX_DATA) ? rx_data_w : tx_data_i;
+
+assign rx_count_o = byte_count_q;
+assign idle_o = (state_q == STATE_IDLE);
+
+assign ack_o = start_ack_q;
+
+assign tx_pop_o = state_q == STATE_TX_DATA && utmi_txready_i;
+
+assign tx_done_o = status_tx_done_q;
+assign rx_done_o = status_rx_done_q;
+assign crc_err_o = status_crc_err_q;
+assign timeout_o = status_timeout_q;
+assign response_o = status_response_q;
+
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/filelist.f b/verilog/rtl/usb1_host/src/filelist.f
new file mode 100644
index 0000000..6288443
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/filelist.f
@@ -0,0 +1,10 @@
+core/usbh_core.sv
+core/usbh_crc16.sv
+core/usbh_crc5.sv
+core/usbh_fifo.sv
+core/usbh_sie.sv
+phy/usb_fs_phy.v
+phy/usb_transceiver.v
+lib/async_wb.sv
+lib/async_fifo.sv
+top/usb1_host.sv
diff --git a/verilog/rtl/usb1_host/src/includes/usbh_host_defs.v b/verilog/rtl/usb1_host/src/includes/usbh_host_defs.v
new file mode 100644
index 0000000..ac0441d
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/includes/usbh_host_defs.v
@@ -0,0 +1,325 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+`define USB_CTRL 6'h0
+
+ `define USB_CTRL_TX_FLUSH 8
+ `define USB_CTRL_TX_FLUSH_DEFAULT 0
+ `define USB_CTRL_TX_FLUSH_B 8
+ `define USB_CTRL_TX_FLUSH_T 8
+ `define USB_CTRL_TX_FLUSH_W 1
+ `define USB_CTRL_TX_FLUSH_R 8:8
+
+ `define USB_CTRL_PHY_DMPULLDOWN 7
+ `define USB_CTRL_PHY_DMPULLDOWN_DEFAULT 0
+ `define USB_CTRL_PHY_DMPULLDOWN_B 7
+ `define USB_CTRL_PHY_DMPULLDOWN_T 7
+ `define USB_CTRL_PHY_DMPULLDOWN_W 1
+ `define USB_CTRL_PHY_DMPULLDOWN_R 7:7
+
+ `define USB_CTRL_PHY_DPPULLDOWN 6
+ `define USB_CTRL_PHY_DPPULLDOWN_DEFAULT 0
+ `define USB_CTRL_PHY_DPPULLDOWN_B 6
+ `define USB_CTRL_PHY_DPPULLDOWN_T 6
+ `define USB_CTRL_PHY_DPPULLDOWN_W 1
+ `define USB_CTRL_PHY_DPPULLDOWN_R 6:6
+
+ `define USB_CTRL_PHY_TERMSELECT 5
+ `define USB_CTRL_PHY_TERMSELECT_DEFAULT 0
+ `define USB_CTRL_PHY_TERMSELECT_B 5
+ `define USB_CTRL_PHY_TERMSELECT_T 5
+ `define USB_CTRL_PHY_TERMSELECT_W 1
+ `define USB_CTRL_PHY_TERMSELECT_R 5:5
+
+ `define USB_CTRL_PHY_XCVRSELECT_DEFAULT 0
+ `define USB_CTRL_PHY_XCVRSELECT_B 3
+ `define USB_CTRL_PHY_XCVRSELECT_T 4
+ `define USB_CTRL_PHY_XCVRSELECT_W 2
+ `define USB_CTRL_PHY_XCVRSELECT_R 4:3
+
+ `define USB_CTRL_PHY_OPMODE_DEFAULT 0
+ `define USB_CTRL_PHY_OPMODE_B 1
+ `define USB_CTRL_PHY_OPMODE_T 2
+ `define USB_CTRL_PHY_OPMODE_W 2
+ `define USB_CTRL_PHY_OPMODE_R 2:1
+
+ `define USB_CTRL_ENABLE_SOF 0
+ `define USB_CTRL_ENABLE_SOF_DEFAULT 0
+ `define USB_CTRL_ENABLE_SOF_B 0
+ `define USB_CTRL_ENABLE_SOF_T 0
+ `define USB_CTRL_ENABLE_SOF_W 1
+ `define USB_CTRL_ENABLE_SOF_R 0:0
+
+`define USB_STATUS 6'h4
+
+ `define USB_STATUS_SOF_TIME_DEFAULT 0
+ `define USB_STATUS_SOF_TIME_B 16
+ `define USB_STATUS_SOF_TIME_T 31
+ `define USB_STATUS_SOF_TIME_W 16
+ `define USB_STATUS_SOF_TIME_R 31:16
+
+ `define USB_STATUS_RX_ERROR 2
+ `define USB_STATUS_RX_ERROR_DEFAULT 0
+ `define USB_STATUS_RX_ERROR_B 2
+ `define USB_STATUS_RX_ERROR_T 2
+ `define USB_STATUS_RX_ERROR_W 1
+ `define USB_STATUS_RX_ERROR_R 2:2
+
+ `define USB_STATUS_LINESTATE_BITS_DEFAULT 0
+ `define USB_STATUS_LINESTATE_BITS_B 0
+ `define USB_STATUS_LINESTATE_BITS_T 1
+ `define USB_STATUS_LINESTATE_BITS_W 2
+ `define USB_STATUS_LINESTATE_BITS_R 1:0
+
+`define USB_IRQ_ACK 6'h8
+
+ `define USB_IRQ_ACK_DEVICE_DETECT 3
+ `define USB_IRQ_ACK_DEVICE_DETECT_DEFAULT 0
+ `define USB_IRQ_ACK_DEVICE_DETECT_B 3
+ `define USB_IRQ_ACK_DEVICE_DETECT_T 3
+ `define USB_IRQ_ACK_DEVICE_DETECT_W 1
+ `define USB_IRQ_ACK_DEVICE_DETECT_R 3:3
+
+ `define USB_IRQ_ACK_ERR 2
+ `define USB_IRQ_ACK_ERR_DEFAULT 0
+ `define USB_IRQ_ACK_ERR_B 2
+ `define USB_IRQ_ACK_ERR_T 2
+ `define USB_IRQ_ACK_ERR_W 1
+ `define USB_IRQ_ACK_ERR_R 2:2
+
+ `define USB_IRQ_ACK_DONE 1
+ `define USB_IRQ_ACK_DONE_DEFAULT 0
+ `define USB_IRQ_ACK_DONE_B 1
+ `define USB_IRQ_ACK_DONE_T 1
+ `define USB_IRQ_ACK_DONE_W 1
+ `define USB_IRQ_ACK_DONE_R 1:1
+
+ `define USB_IRQ_ACK_SOF 0
+ `define USB_IRQ_ACK_SOF_DEFAULT 0
+ `define USB_IRQ_ACK_SOF_B 0
+ `define USB_IRQ_ACK_SOF_T 0
+ `define USB_IRQ_ACK_SOF_W 1
+ `define USB_IRQ_ACK_SOF_R 0:0
+
+`define USB_IRQ_STS 6'hc
+
+ `define USB_IRQ_STS_DEVICE_DETECT 3
+ `define USB_IRQ_STS_DEVICE_DETECT_DEFAULT 0
+ `define USB_IRQ_STS_DEVICE_DETECT_B 3
+ `define USB_IRQ_STS_DEVICE_DETECT_T 3
+ `define USB_IRQ_STS_DEVICE_DETECT_W 1
+ `define USB_IRQ_STS_DEVICE_DETECT_R 3:3
+
+ `define USB_IRQ_STS_ERR 2
+ `define USB_IRQ_STS_ERR_DEFAULT 0
+ `define USB_IRQ_STS_ERR_B 2
+ `define USB_IRQ_STS_ERR_T 2
+ `define USB_IRQ_STS_ERR_W 1
+ `define USB_IRQ_STS_ERR_R 2:2
+
+ `define USB_IRQ_STS_DONE 1
+ `define USB_IRQ_STS_DONE_DEFAULT 0
+ `define USB_IRQ_STS_DONE_B 1
+ `define USB_IRQ_STS_DONE_T 1
+ `define USB_IRQ_STS_DONE_W 1
+ `define USB_IRQ_STS_DONE_R 1:1
+
+ `define USB_IRQ_STS_SOF 0
+ `define USB_IRQ_STS_SOF_DEFAULT 0
+ `define USB_IRQ_STS_SOF_B 0
+ `define USB_IRQ_STS_SOF_T 0
+ `define USB_IRQ_STS_SOF_W 1
+ `define USB_IRQ_STS_SOF_R 0:0
+
+`define USB_IRQ_MASK 6'h10
+
+ `define USB_IRQ_MASK_DEVICE_DETECT 3
+ `define USB_IRQ_MASK_DEVICE_DETECT_DEFAULT 0
+ `define USB_IRQ_MASK_DEVICE_DETECT_B 3
+ `define USB_IRQ_MASK_DEVICE_DETECT_T 3
+ `define USB_IRQ_MASK_DEVICE_DETECT_W 1
+ `define USB_IRQ_MASK_DEVICE_DETECT_R 3:3
+
+ `define USB_IRQ_MASK_ERR 2
+ `define USB_IRQ_MASK_ERR_DEFAULT 0
+ `define USB_IRQ_MASK_ERR_B 2
+ `define USB_IRQ_MASK_ERR_T 2
+ `define USB_IRQ_MASK_ERR_W 1
+ `define USB_IRQ_MASK_ERR_R 2:2
+
+ `define USB_IRQ_MASK_DONE 1
+ `define USB_IRQ_MASK_DONE_DEFAULT 0
+ `define USB_IRQ_MASK_DONE_B 1
+ `define USB_IRQ_MASK_DONE_T 1
+ `define USB_IRQ_MASK_DONE_W 1
+ `define USB_IRQ_MASK_DONE_R 1:1
+
+ `define USB_IRQ_MASK_SOF 0
+ `define USB_IRQ_MASK_SOF_DEFAULT 0
+ `define USB_IRQ_MASK_SOF_B 0
+ `define USB_IRQ_MASK_SOF_T 0
+ `define USB_IRQ_MASK_SOF_W 1
+ `define USB_IRQ_MASK_SOF_R 0:0
+
+`define USB_XFER_DATA 6'h14
+
+ `define USB_XFER_DATA_TX_LEN_DEFAULT 0
+ `define USB_XFER_DATA_TX_LEN_B 0
+ `define USB_XFER_DATA_TX_LEN_T 15
+ `define USB_XFER_DATA_TX_LEN_W 16
+ `define USB_XFER_DATA_TX_LEN_R 15:0
+
+`define USB_XFER_TOKEN 6'h18
+
+ `define USB_XFER_TOKEN_START 31
+ `define USB_XFER_TOKEN_START_DEFAULT 0
+ `define USB_XFER_TOKEN_START_B 31
+ `define USB_XFER_TOKEN_START_T 31
+ `define USB_XFER_TOKEN_START_W 1
+ `define USB_XFER_TOKEN_START_R 31:31
+
+ `define USB_XFER_TOKEN_IN 30
+ `define USB_XFER_TOKEN_IN_DEFAULT 0
+ `define USB_XFER_TOKEN_IN_B 30
+ `define USB_XFER_TOKEN_IN_T 30
+ `define USB_XFER_TOKEN_IN_W 1
+ `define USB_XFER_TOKEN_IN_R 30:30
+
+ `define USB_XFER_TOKEN_ACK 29
+ `define USB_XFER_TOKEN_ACK_DEFAULT 0
+ `define USB_XFER_TOKEN_ACK_B 29
+ `define USB_XFER_TOKEN_ACK_T 29
+ `define USB_XFER_TOKEN_ACK_W 1
+ `define USB_XFER_TOKEN_ACK_R 29:29
+
+ `define USB_XFER_TOKEN_PID_DATAX 28
+ `define USB_XFER_TOKEN_PID_DATAX_DEFAULT 0
+ `define USB_XFER_TOKEN_PID_DATAX_B 28
+ `define USB_XFER_TOKEN_PID_DATAX_T 28
+ `define USB_XFER_TOKEN_PID_DATAX_W 1
+ `define USB_XFER_TOKEN_PID_DATAX_R 28:28
+
+ `define USB_XFER_TOKEN_PID_BITS_DEFAULT 0
+ `define USB_XFER_TOKEN_PID_BITS_B 16
+ `define USB_XFER_TOKEN_PID_BITS_T 23
+ `define USB_XFER_TOKEN_PID_BITS_W 8
+ `define USB_XFER_TOKEN_PID_BITS_R 23:16
+
+ `define USB_XFER_TOKEN_DEV_ADDR_DEFAULT 0
+ `define USB_XFER_TOKEN_DEV_ADDR_B 9
+ `define USB_XFER_TOKEN_DEV_ADDR_T 15
+ `define USB_XFER_TOKEN_DEV_ADDR_W 7
+ `define USB_XFER_TOKEN_DEV_ADDR_R 15:9
+
+ `define USB_XFER_TOKEN_EP_ADDR_DEFAULT 0
+ `define USB_XFER_TOKEN_EP_ADDR_B 5
+ `define USB_XFER_TOKEN_EP_ADDR_T 8
+ `define USB_XFER_TOKEN_EP_ADDR_W 4
+ `define USB_XFER_TOKEN_EP_ADDR_R 8:5
+
+`define USB_RX_STAT 6'h1c
+
+ `define USB_RX_STAT_START_PEND 31
+ `define USB_RX_STAT_START_PEND_DEFAULT 0
+ `define USB_RX_STAT_START_PEND_B 31
+ `define USB_RX_STAT_START_PEND_T 31
+ `define USB_RX_STAT_START_PEND_W 1
+ `define USB_RX_STAT_START_PEND_R 31:31
+
+ `define USB_RX_STAT_CRC_ERR 30
+ `define USB_RX_STAT_CRC_ERR_DEFAULT 0
+ `define USB_RX_STAT_CRC_ERR_B 30
+ `define USB_RX_STAT_CRC_ERR_T 30
+ `define USB_RX_STAT_CRC_ERR_W 1
+ `define USB_RX_STAT_CRC_ERR_R 30:30
+
+ `define USB_RX_STAT_RESP_TIMEOUT 29
+ `define USB_RX_STAT_RESP_TIMEOUT_DEFAULT 0
+ `define USB_RX_STAT_RESP_TIMEOUT_B 29
+ `define USB_RX_STAT_RESP_TIMEOUT_T 29
+ `define USB_RX_STAT_RESP_TIMEOUT_W 1
+ `define USB_RX_STAT_RESP_TIMEOUT_R 29:29
+
+ `define USB_RX_STAT_IDLE 28
+ `define USB_RX_STAT_IDLE_DEFAULT 0
+ `define USB_RX_STAT_IDLE_B 28
+ `define USB_RX_STAT_IDLE_T 28
+ `define USB_RX_STAT_IDLE_W 1
+ `define USB_RX_STAT_IDLE_R 28:28
+
+ `define USB_RX_STAT_RESP_BITS_DEFAULT 0
+ `define USB_RX_STAT_RESP_BITS_B 16
+ `define USB_RX_STAT_RESP_BITS_T 23
+ `define USB_RX_STAT_RESP_BITS_W 8
+ `define USB_RX_STAT_RESP_BITS_R 23:16
+
+ `define USB_RX_STAT_COUNT_BITS_DEFAULT 0
+ `define USB_RX_STAT_COUNT_BITS_B 0
+ `define USB_RX_STAT_COUNT_BITS_T 15
+ `define USB_RX_STAT_COUNT_BITS_W 16
+ `define USB_RX_STAT_COUNT_BITS_R 15:0
+
+`define USB_WR_DATA 6'h20
+
+ `define USB_WR_DATA_DATA_DEFAULT 0
+ `define USB_WR_DATA_DATA_B 0
+ `define USB_WR_DATA_DATA_T 7
+ `define USB_WR_DATA_DATA_W 8
+ `define USB_WR_DATA_DATA_R 7:0
+
+`define USB_RD_DATA 6'h20
+
+ `define USB_RD_DATA_DATA_DEFAULT 0
+ `define USB_RD_DATA_DATA_B 0
+ `define USB_RD_DATA_DATA_T 7
+ `define USB_RD_DATA_DATA_W 8
+ `define USB_RD_DATA_DATA_R 7:0
+
diff --git a/verilog/rtl/usb1_host/src/phy/usb_fs_phy.v b/verilog/rtl/usb1_host/src/phy/usb_fs_phy.v
new file mode 100644
index 0000000..c7ac174
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/phy/usb_fs_phy.v
@@ -0,0 +1,713 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed (12mbps) Phy
+// V0.2
+// Ultra-Embedded.com
+// Copyright 2015
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//-----------------------------------------------------------------
+//
+// 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, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+module usb_fs_phy
+(
+ // Inputs
+ input clk_i
+ ,input rstn_i
+ ,input [ 7:0] utmi_data_out_i
+ ,input utmi_txvalid_i
+ ,input [ 1:0] utmi_op_mode_i
+ ,input [ 1:0] utmi_xcvrselect_i
+ ,input utmi_termselect_i
+ ,input utmi_dppulldown_i
+ ,input utmi_dmpulldown_i
+ ,input usb_rx_rcv_i
+ ,input usb_rx_dp_i
+ ,input usb_rx_dn_i
+ ,input usb_reset_assert_i
+
+ // Outputs
+ ,output [ 7:0] utmi_data_in_o
+ ,output utmi_txready_o
+ ,output utmi_rxvalid_o
+ ,output utmi_rxactive_o
+ ,output utmi_rxerror_o
+ ,output [ 1:0] utmi_linestate_o
+ ,output usb_tx_dp_o
+ ,output usb_tx_dn_o
+ ,output usb_tx_oen_o
+ ,output usb_reset_detect_o
+ ,output usb_en_o
+);
+
+
+
+
+//-----------------------------------------------------------------
+// Wires / Registers
+//-----------------------------------------------------------------
+reg rx_en_q;
+
+// Xilinx placement pragmas:
+//synthesis attribute IOB of out_dp_q is "TRUE"
+//synthesis attribute IOB of out_dn_q is "TRUE"
+reg out_dp_q;
+reg out_dn_q;
+
+wire in_dp_w;
+wire in_dn_w;
+wire in_rx_w;
+
+wire in_j_w;
+wire in_k_w;
+wire in_se0_w;
+wire in_invalid_w;
+
+wire sample_w;
+
+wire bit_edge_w;
+wire bit_transition_w;
+
+reg [2:0] bit_count_q;
+reg [2:0] ones_count_q;
+reg [7:0] data_q;
+reg send_eop_q;
+
+reg sync_j_detected_q;
+
+wire bit_stuff_bit_w;
+wire next_is_bit_stuff_w;
+
+wire usb_reset_assert_w = usb_reset_assert_i |
+ (utmi_xcvrselect_i == 2'b00 &&
+ utmi_termselect_i == 1'b0 &&
+ utmi_op_mode_i == 2'b10 &&
+ utmi_dppulldown_i &&
+ utmi_dmpulldown_i);
+
+//-----------------------------------------------------------------
+// Resample async signals
+//-----------------------------------------------------------------
+reg rx_dp_ms;
+reg rx_dn_ms;
+reg rxd_ms;
+
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ rx_dp_ms <= 1'b0;
+ rx_dn_ms <= 1'b0;
+ rxd_ms <= 1'b0;
+end
+else
+begin
+ rx_dp_ms <= in_dp_w;
+ rx_dn_ms <= in_dn_w;
+ rxd_ms <= in_rx_w;
+end
+
+//-----------------------------------------------------------------
+// Edge Detection
+//-----------------------------------------------------------------
+reg rx_dp0_q;
+reg rx_dn0_q;
+reg rx_dp1_q;
+reg rx_dn1_q;
+reg rx_dp_q;
+reg rx_dn_q;
+reg rxd0_q;
+reg rxd1_q;
+reg rxd_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ rx_dp0_q <= 1'b0;
+ rx_dn0_q <= 1'b0;
+ rx_dp1_q <= 1'b0;
+ rx_dn1_q <= 1'b0;
+ rx_dp_q <= 1'b0;
+ rx_dn_q <= 1'b0;
+ rxd0_q <= 1'b0;
+ rxd1_q <= 1'b0;
+ rxd_q <= 1'b0;
+end
+else
+begin
+ // Glitch free versions
+ if (rx_dp0_q & rx_dp1_q)
+ rx_dp_q <= 1'b1;
+ else if (!rx_dp0_q & !rx_dp1_q)
+ rx_dp_q <= 1'b0;
+
+ if (rx_dn0_q & rx_dn1_q)
+ rx_dn_q <= 1'b1;
+ else if (!rx_dn0_q & !rx_dn1_q)
+ rx_dn_q <= 1'b0;
+
+ if (rxd0_q & rxd1_q)
+ rxd_q <= 1'b1;
+ else if (!rxd0_q & !rxd1_q)
+ rxd_q <= 1'b0;
+
+ // Resyncs
+ rx_dp1_q <= rx_dp0_q;
+ rx_dp0_q <= rx_dp_ms;
+
+ rx_dn1_q <= rx_dn0_q;
+ rx_dn0_q <= rx_dn_ms;
+
+ rxd1_q <= rxd0_q;
+ rxd0_q <= rxd_ms;
+end
+
+// For Full Speed USB:
+// SE0 = D+ = 0 && D- = 0
+// J = D+ = 1 && D- = 0
+// K = D+ = 0 && D- = 1
+
+assign in_j_w = in_se0_w ? 1'b0 : rxd_q;
+assign in_k_w = in_se0_w ? 1'b0 : ~rxd_q;
+assign in_se0_w = (!rx_dp_q & !rx_dn_q);
+assign in_invalid_w = (rx_dp_q & rx_dn_q);
+
+// Line state matches tx outputs if drivers enabled
+assign utmi_linestate_o = usb_tx_oen_o ? {rx_dn_q, rx_dp_q} : {usb_tx_dn_o, usb_tx_dp_o};
+
+//-----------------------------------------------------------------
+// State Machine
+//-----------------------------------------------------------------
+localparam STATE_W = 4;
+localparam STATE_IDLE = 4'd0;
+localparam STATE_RX_DETECT = 4'd1;
+localparam STATE_RX_SYNC_J = 4'd2;
+localparam STATE_RX_SYNC_K = 4'd3;
+localparam STATE_RX_ACTIVE = 4'd4;
+localparam STATE_RX_EOP0 = 4'd5;
+localparam STATE_RX_EOP1 = 4'd6;
+localparam STATE_TX_SYNC = 4'd7;
+localparam STATE_TX_ACTIVE = 4'd8;
+localparam STATE_TX_EOP_STUFF = 4'd9;
+localparam STATE_TX_EOP0 = 4'd10;
+localparam STATE_TX_EOP1 = 4'd11;
+localparam STATE_TX_EOP2 = 4'd12;
+localparam STATE_TX_RST = 4'd13;
+
+// Current state
+reg [STATE_W-1:0] state_q;
+
+reg [STATE_W-1:0] next_state_r;
+always @ *
+begin
+ next_state_r = state_q;
+
+ case (state_q)
+ //-----------------------------------------
+ // STATE_IDLE
+ //-----------------------------------------
+ STATE_IDLE :
+ begin
+ if (in_k_w)
+ next_state_r = STATE_RX_DETECT;
+ else if (utmi_txvalid_i)
+ next_state_r = STATE_TX_SYNC;
+ else if (usb_reset_assert_w)
+ next_state_r = STATE_TX_RST;
+ end
+ //-----------------------------------------
+ // STATE_RX_DETECT
+ //-----------------------------------------
+ STATE_RX_DETECT :
+ begin
+ if (in_k_w && sample_w)
+ next_state_r = STATE_RX_SYNC_K;
+ else if (sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_SYNC_J
+ //-----------------------------------------
+ STATE_RX_SYNC_J :
+ begin
+ if (in_k_w && sample_w)
+ next_state_r = STATE_RX_SYNC_K;
+ // K glitch followed by multiple J's - return to idle
+ else if ((bit_count_q == 3'd1) && sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_SYNC_K
+ //-----------------------------------------
+ STATE_RX_SYNC_K :
+ begin
+ // End of SYNC field ends with 2 K's
+ // Must have seen at least 1 J state first!
+ if (sync_j_detected_q && in_k_w && sample_w)
+ next_state_r = STATE_RX_ACTIVE;
+ // No J detected since IDLE, must be an error!
+ else if (!sync_j_detected_q && in_k_w && sample_w)
+ next_state_r = STATE_IDLE;
+ else if (in_j_w && sample_w)
+ next_state_r = STATE_RX_SYNC_J;
+ end
+ //-----------------------------------------
+ // STATE_RX_ACTIVE
+ //-----------------------------------------
+ STATE_RX_ACTIVE :
+ begin
+ if (in_se0_w && sample_w)
+ next_state_r = STATE_RX_EOP0;
+ // Error!
+ else if (in_invalid_w && sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_EOP0
+ //-----------------------------------------
+ STATE_RX_EOP0 :
+ begin
+ if (in_se0_w && sample_w)
+ next_state_r = STATE_RX_EOP1;
+ // Error!
+ else if (sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_EOP1
+ //-----------------------------------------
+ STATE_RX_EOP1 :
+ begin
+ // Return to idle
+ if (in_j_w && sample_w)
+ next_state_r = STATE_IDLE;
+ // Error!
+ else if (sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_TX_SYNC
+ //-----------------------------------------
+ STATE_TX_SYNC :
+ begin
+ if (bit_count_q == 3'd7 && sample_w)
+ next_state_r = STATE_TX_ACTIVE;
+ end
+ //-----------------------------------------
+ // STATE_TX_ACTIVE
+ //-----------------------------------------
+ STATE_TX_ACTIVE :
+ begin
+ if (bit_count_q == 3'd7 && sample_w && (!utmi_txvalid_i || send_eop_q) && !bit_stuff_bit_w)
+ begin
+ // Bit stuff required at end of packet?
+ if (next_is_bit_stuff_w)
+ next_state_r = STATE_TX_EOP_STUFF;
+ else
+ next_state_r = STATE_TX_EOP0;
+ end
+ end
+ //-----------------------------------------
+ // STATE_TX_EOP_STUFF
+ //-----------------------------------------
+ STATE_TX_EOP_STUFF :
+ begin
+ if (sample_w)
+ next_state_r = STATE_TX_EOP0;
+ end
+ //-----------------------------------------
+ // STATE_TX_EOP0
+ //-----------------------------------------
+ STATE_TX_EOP0 :
+ begin
+ if (sample_w)
+ next_state_r = STATE_TX_EOP1;
+ end
+ //-----------------------------------------
+ // STATE_TX_EOP1
+ //-----------------------------------------
+ STATE_TX_EOP1 :
+ begin
+ if (sample_w)
+ next_state_r = STATE_TX_EOP2;
+ end
+ //-----------------------------------------
+ // STATE_TX_EOP2
+ //-----------------------------------------
+ STATE_TX_EOP2 :
+ begin
+ if (sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_TX_RST
+ //-----------------------------------------
+ STATE_TX_RST :
+ begin
+ if (!usb_reset_assert_w)
+ next_state_r = STATE_IDLE;
+ end
+ default:
+ ;
+ endcase
+end
+
+// Update state
+always @ (negedge rstn_i or posedge clk_i)
+if (!rstn_i)
+ state_q <= STATE_IDLE;
+else
+ state_q <= next_state_r;
+
+//-----------------------------------------------------------------
+// SYNC detect
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ sync_j_detected_q <= 1'b0;
+// Reset sync detect state in IDLE
+else if (state_q == STATE_IDLE)
+ sync_j_detected_q <= 1'b0;
+// At least one J detected
+else if (state_q == STATE_RX_SYNC_J)
+ sync_j_detected_q <= 1'b1;
+
+//-----------------------------------------------------------------
+// Rx Error Detection
+//-----------------------------------------------------------------
+reg rx_error_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rx_error_q <= 1'b0;
+// Rx bit stuffing error
+else if (ones_count_q == 3'd7)
+ rx_error_q <= 1'b1;
+// Invalid line state detection
+else if (in_invalid_w && sample_w)
+ rx_error_q <= 1'b1;
+// Detect invalid SYNC sequence
+else if ((state_q == STATE_RX_SYNC_K) && !sync_j_detected_q && in_k_w && sample_w)
+ rx_error_q <= 1'b1;
+else
+ rx_error_q <= 1'b0;
+
+assign utmi_rxerror_o = rx_error_q;
+
+//-----------------------------------------------------------------
+// Edge Detector
+//-----------------------------------------------------------------
+reg rxd_last_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rxd_last_q <= 1'b0;
+else
+ rxd_last_q <= in_j_w;
+
+assign bit_edge_w = rxd_last_q ^ in_j_w;
+
+//-----------------------------------------------------------------
+// Sample Timer
+//-----------------------------------------------------------------
+reg [1:0] sample_cnt_q;
+reg adjust_delayed_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ sample_cnt_q <= 2'd0;
+ adjust_delayed_q <= 1'b0;
+end
+// Delayed adjustment
+else if (adjust_delayed_q)
+ adjust_delayed_q <= 1'b0;
+else if (bit_edge_w && (sample_cnt_q != 2'd0) && (state_q < STATE_TX_SYNC))
+ sample_cnt_q <= 2'd0;
+// Can't adjust sampling point now?
+else if (bit_edge_w && (sample_cnt_q == 2'd0) && (state_q < STATE_TX_SYNC))
+begin
+ // Want to reset sampling point but need to delay adjustment by 1 cycle!
+ adjust_delayed_q <= 1'b1;
+ sample_cnt_q <= sample_cnt_q + 2'd1;
+end
+else
+ sample_cnt_q <= sample_cnt_q + 2'd1;
+
+assign sample_w = (sample_cnt_q == 2'd0);
+
+//-----------------------------------------------------------------
+// NRZI Receiver
+//-----------------------------------------------------------------
+reg rxd_last_j_q;
+
+// NRZI:
+// 0 = transition between J & K
+// 1 = same state
+// After 6 consequitive 1's, a 0 is inserted to maintain the transitions
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rxd_last_j_q <= 1'b0;
+else if ((state_q == STATE_IDLE) || sample_w)
+ rxd_last_j_q <= in_j_w;
+
+assign bit_transition_w = sample_w ? rxd_last_j_q ^ in_j_w : 1'b0;
+
+//-----------------------------------------------------------------
+// Bit Counters
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ ones_count_q <= 3'd1;
+// The packet starts with a double K (no transition)
+else if (state_q == STATE_IDLE)
+ ones_count_q <= 3'd1;
+// Rx
+else if ((state_q == STATE_RX_ACTIVE) && sample_w)
+begin
+ if (bit_transition_w)
+ ones_count_q <= 3'b0;
+ else
+ ones_count_q <= ones_count_q + 3'd1;
+end
+// Tx
+else if ((state_q == STATE_TX_ACTIVE) && sample_w)
+begin
+ // Toggle output data
+ if (!data_q[0] || bit_stuff_bit_w)
+ ones_count_q <= 3'b0;
+ else
+ ones_count_q <= ones_count_q + 3'd1;
+end
+
+assign bit_stuff_bit_w = (ones_count_q == 3'd6);
+assign next_is_bit_stuff_w = (ones_count_q == 3'd5) && !bit_transition_w;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ bit_count_q <= 3'b0;
+else if ((state_q == STATE_IDLE) || (state_q == STATE_RX_SYNC_K))
+ bit_count_q <= 3'b0;
+else if ((state_q == STATE_RX_ACTIVE || state_q == STATE_TX_ACTIVE) && sample_w && !bit_stuff_bit_w)
+ bit_count_q <= bit_count_q + 3'd1;
+else if (((state_q == STATE_TX_SYNC) || (state_q == STATE_RX_SYNC_J)) && sample_w)
+ bit_count_q <= bit_count_q + 3'd1;
+
+//-----------------------------------------------------------------
+// Shift register
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ data_q <= 8'b0;
+// Pre-load shift register with SYNC word
+else if (state_q == STATE_IDLE)
+ data_q <= 8'b00101010;
+else if ((state_q == STATE_RX_ACTIVE) && sample_w && !bit_stuff_bit_w)
+ data_q <= {~bit_transition_w, data_q[7:1]};
+else if ((state_q == STATE_TX_SYNC) && sample_w)
+begin
+ if (bit_count_q == 3'd7)
+ data_q <= utmi_data_out_i;
+ else
+ data_q <= {~bit_transition_w, data_q[7:1]};
+end
+else if ((state_q == STATE_TX_ACTIVE) && sample_w && !bit_stuff_bit_w)
+begin
+ if (bit_count_q == 3'd7)
+ data_q <= utmi_data_out_i;
+ else
+ data_q <= {~bit_transition_w, data_q[7:1]};
+end
+
+// Receive active (SYNC recieved)
+assign utmi_rxactive_o = (state_q == STATE_RX_ACTIVE);
+
+assign utmi_data_in_o = data_q;
+
+//-----------------------------------------------------------------
+// Rx Ready
+//-----------------------------------------------------------------
+reg rx_ready_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rx_ready_q <= 1'b0;
+else if ((state_q == STATE_RX_ACTIVE) && sample_w && (bit_count_q == 3'd7) && !bit_stuff_bit_w)
+ rx_ready_q <= 1'b1;
+else
+ rx_ready_q <= 1'b0;
+
+assign utmi_rxvalid_o = rx_ready_q;
+
+//-----------------------------------------------------------------
+// Tx Ready
+//-----------------------------------------------------------------
+reg tx_ready_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ tx_ready_q <= 1'b0;
+else if ((state_q == STATE_TX_SYNC) && sample_w && (bit_count_q == 3'd7))
+ tx_ready_q <= 1'b1;
+else if ((state_q == STATE_TX_ACTIVE) && sample_w && !bit_stuff_bit_w && (bit_count_q == 3'd7) && !send_eop_q)
+ tx_ready_q <= 1'b1;
+else
+ tx_ready_q <= 1'b0;
+
+assign utmi_txready_o = tx_ready_q;
+
+//-----------------------------------------------------------------
+// EOP pending
+//-----------------------------------------------------------------
+always @ (negedge rstn_i or negedge clk_i)
+if (!rstn_i)
+ send_eop_q <= 1'b0;
+else if ((state_q == STATE_TX_ACTIVE) && !utmi_txvalid_i)
+ send_eop_q <= 1'b1;
+else if (state_q == STATE_TX_EOP0)
+ send_eop_q <= 1'b0;
+
+//-----------------------------------------------------------------
+// Tx
+//-----------------------------------------------------------------
+wire out_bit_w = sample_w ? data_q[0] : 1'bz;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ out_dp_q <= 1'b0;
+ out_dn_q <= 1'b0;
+ rx_en_q <= 1'b1;
+end
+else if (state_q == STATE_IDLE)
+begin
+ // IDLE
+ out_dp_q <= 1'b1;
+ out_dn_q <= 1'b0;
+
+ if (utmi_txvalid_i || usb_reset_assert_w)
+ rx_en_q <= 1'b0;
+ else
+ rx_en_q <= 1'b1;
+end
+else if ((state_q == STATE_TX_SYNC) && sample_w)
+begin
+ out_dp_q <= data_q[0];
+ out_dn_q <= ~data_q[0];
+end
+else if ((state_q == STATE_TX_ACTIVE || state_q == STATE_TX_EOP_STUFF) && sample_w)
+begin
+ // 0 = toggle, 1 = hold
+ if (!data_q[0] || bit_stuff_bit_w)
+ begin
+ out_dp_q <= ~out_dp_q;
+ out_dn_q <= ~out_dn_q;
+ end
+end
+else if ((state_q == STATE_TX_EOP0 || state_q == STATE_TX_EOP1) && sample_w)
+begin
+ // SE0
+ out_dp_q <= 1'b0;
+ out_dn_q <= 1'b0;
+end
+else if ((state_q == STATE_TX_EOP2) && sample_w)
+begin
+ // IDLE
+ out_dp_q <= 1'b1;
+ out_dn_q <= 1'b0;
+
+ // Set bus to input
+ rx_en_q <= 1'b1;
+end
+else if (state_q == STATE_TX_RST)
+begin
+ // SE0
+ out_dp_q <= 1'b0;
+ out_dn_q <= 1'b0;
+end
+
+//-----------------------------------------------------------------
+// Reset detection
+//-----------------------------------------------------------------
+reg [6:0] se0_cnt_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ se0_cnt_q <= 7'b0;
+else if (in_se0_w)
+begin
+ if (se0_cnt_q != 7'd127)
+ se0_cnt_q <= se0_cnt_q + 7'd1;
+end
+else
+ se0_cnt_q <= 7'b0;
+
+assign usb_reset_detect_o = (se0_cnt_q == 7'd127);
+
+//-----------------------------------------------------------------
+// Transceiver Interface
+//-----------------------------------------------------------------
+// Tx output enable (active low)
+assign usb_tx_oen_o = rx_en_q;
+
+// Tx +/-
+assign usb_tx_dp_o = out_dp_q;
+assign usb_tx_dn_o = out_dn_q;
+
+// Receive D+/D-
+assign in_dp_w = usb_rx_dp_i;
+assign in_dn_w = usb_rx_dn_i;
+
+// Receive data
+assign in_rx_w = usb_rx_rcv_i;
+
+// USB device pull-up enable
+assign usb_en_o = utmi_termselect_i;
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/phy/usb_transceiver.v b/verilog/rtl/usb1_host/src/phy/usb_transceiver.v
new file mode 100644
index 0000000..6a3575b
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/phy/usb_transceiver.v
@@ -0,0 +1,187 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//-----------------------------------------------------------------
+// USB Full Speed (12mbps) Phy
+// V0.2
+// Ultra-Embedded.com
+// Copyright 2015
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//-----------------------------------------------------------------
+//
+// 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, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+module usb_transceiver
+(
+ // Inputs
+ input usb_phy_tx_dp_i,
+ input usb_phy_tx_dn_i,
+ input usb_phy_tx_oen_i,
+ input mode_i,
+
+ output reg out_dp,
+ output reg out_dn,
+ output out_tx_oen,
+
+ // Outputs
+ input in_dp,
+ input in_dn,
+
+ output usb_phy_rx_rcv_o,
+ output usb_phy_rx_dp_o,
+ output usb_phy_rx_dn_o
+);
+
+
+
+//-----------------------------------------------------------------
+// Module: usb_transceiver
+// Emulate standard USB PHY interface and produce a D+/D- outputs.
+// Allows direct connection of USB port to FPGA.
+// Limitations:
+// As no differential amplifier present, no common mode noise
+// rejection occurs.
+// Unlikely to work well with longer connections!
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Wires
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Assignments
+//-----------------------------------------------------------------
+
+// D+/D- Tristate buffers
+//assign usb_dp_io = (usb_phy_tx_oen_i == 1'b0) ? out_dp : 1'bz;
+//assign usb_dn_io = (usb_phy_tx_oen_i == 1'b0) ? out_dn : 1'bz;
+//
+assign out_tx_oen = usb_phy_tx_oen_i;
+
+// Receive D+/D-
+assign usb_phy_rx_dp_o = in_dp;
+assign usb_phy_rx_dn_o = in_dn;
+
+// Receive output
+assign usb_phy_rx_rcv_o = (in_dp == 1'b1 && in_dn == 1'b0) ? 1'b1 : 1'b0;
+
+// PHY Transmit Mode:
+// When phy_tx_mode_i is '0' the outputs are encoded as:
+// vmo_i, vpo_i
+// 0 0 Differential Logic '0'
+// 0 1 Differential Logic '1'
+// 1 0 Single Ended '0'
+// 1 1 Single Ended '0'
+// When phy_tx_mode_i is '1' the outputs are encoded as:
+// vmo_i, vpo_i
+// 0 0 Single Ended '0'
+// 0 1 Differential Logic '1'
+// 1 0 Differential Logic '0'
+// 1 1 Illegal State
+always_comb
+begin : MUX
+// Logic "0"
+out_dp = 1'b0;
+out_dn = 1'b1;
+ case(mode_i)
+ 1'b0:
+ begin
+ if (usb_phy_tx_dp_i == 1'b0 && usb_phy_tx_dn_i == 1'b0)
+ begin
+ // Logic "0"
+ out_dp = 1'b0;
+ out_dn = 1'b1;
+ end
+ else if (usb_phy_tx_dp_i == 1'b0 && usb_phy_tx_dn_i == 1'b1)
+ begin
+ // SE0 (both low)
+ out_dp = 1'b0;
+ out_dn = 1'b0;
+ end
+ else if (usb_phy_tx_dp_i == 1'b1 && usb_phy_tx_dn_i == 1'b0)
+ begin
+ // Logic "1"
+ out_dp = 1'b1;
+ out_dn = 1'b0;
+ end
+ else if (usb_phy_tx_dp_i == 1'b1 && usb_phy_tx_dn_i == 1'b1)
+ begin
+ // SE0 (both low)
+ out_dp = 1'b0;
+ out_dn = 1'b0;
+ end
+ end
+ 1'b1 :
+ begin
+ if (usb_phy_tx_dp_i == 1'b0 && usb_phy_tx_dn_i == 1'b0)
+ begin
+ // SE0 (both low)
+ out_dp = 1'b0;
+ out_dn = 1'b0;
+ end
+ else if (usb_phy_tx_dp_i == 1'b0 && usb_phy_tx_dn_i == 1'b1)
+ begin
+ // Logic "0"
+ out_dp = 1'b0;
+ out_dn = 1'b1;
+ end
+ else if (usb_phy_tx_dp_i == 1'b1 && usb_phy_tx_dn_i == 1'b0)
+ begin
+ // Logic "1"
+ out_dp = 1'b1;
+ out_dn = 1'b0;
+ end
+ else if (usb_phy_tx_dp_i == 1'b1 && usb_phy_tx_dn_i == 1'b1)
+ begin
+ // Illegal
+ out_dp = 1'b1;
+ out_dn = 1'b1;
+ end
+ end
+ endcase
+end
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/top/usb1_host.sv b/verilog/rtl/usb1_host/src/top/usb1_host.sv
new file mode 100644
index 0000000..1de70d4
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/top/usb1_host.sv
@@ -0,0 +1,238 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// USB1.1 HOST Controller + PHY ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// USB1 Core from github.com/ultraembedded/core_usb_host ////
+//// USBB Phy from github.com/ultraembedded/core_usb_fs_phy.git ////
+//// ////
+//// Description ////
+//// Following Modification are Done ////
+//// 1. Integrated the Wishbone Interface ////
+//// 2. WishBone interface made async w.r.t usb clock ////
+//// 3. usb1 core Axi logic is modified to normal Register ////
+//// read/write I/F ////
+//// ////
+//// This module integrate following sub module ////
+//// 1. async_wb : Async wishbone interface does the wishbone ////
+//// to usbclk clock synchronization ////
+//// 2. usb1_core: usb1 core ////
+//// 3. usb1_host : usb phy ////
+//// ////
+//// Assumptiom: usb_clk is 48Mhz ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module usb1_host (
+ input logic usb_clk_i ,
+ input logic usb_rstn_i ,
+
+ // USB D+/D-
+ input in_dp ,
+ input in_dn ,
+
+ input out_dp ,
+ input out_dn ,
+ output out_tx_oen,
+
+ // Master Port
+ input logic wbm_rst_n , // Regular Reset signal
+ input logic wbm_clk_i , // System clock
+ input logic wbm_stb_i , // strobe/request
+ input logic [5:0] wbm_adr_i , // address
+ input logic wbm_we_i , // write
+ input logic [31:0] wbm_dat_i , // data output
+ input logic [3:0] wbm_sel_i , // byte enable
+ output logic [31:0] wbm_dat_o , // data input
+ output logic wbm_ack_o , // acknowlegement
+ output logic wbm_err_o , // error
+
+ // Outputs
+ output usb_intr_o
+
+
+ );
+
+ logic [7:0] utmi_data_in_i;
+ logic utmi_txready_i;
+ logic utmi_rxvalid_i;
+ logic utmi_rxactive_i;
+ logic utmi_rxerror_i;
+ logic [1:0] utmi_linestate_i;
+
+ logic [7:0] utmi_data_out_o;
+ logic utmi_txvalid_o;
+ logic [1:0] utmi_op_mode_o;
+ logic [1:0] utmi_xcvrselect_o;
+ logic utmi_termselect_o;
+ logic utmi_dppulldown_o;
+ logic utmi_dmpulldown_o;
+ logic usb_pads_tx_dp_w;
+ logic usb_pads_tx_oen_w;
+ logic usb_pads_rx_dn_w;
+ logic usb_pads_tx_dn_w;
+ logic usb_pads_rx_rcv_w;
+ logic usb_pads_rx_dp_w;
+ logic usb_xcvr_mode_w = 1'h1;
+
+ // Reg Bus Interface Signal
+ logic reg_cs;
+ logic reg_wr;
+ logic [5:0] reg_addr;
+ logic [31:0] reg_wdata;
+ logic [3:0] reg_be;
+
+ // Outputs
+ logic [31:0] reg_rdata;
+ logic reg_ack;
+
+
+
+async_wb #(.AW (6))
+ u_async_wb(
+
+ // Master Port
+ .wbm_rst_n (wbm_rst_n ), // Regular Reset signal
+ .wbm_clk_i (wbm_clk_i ), // System clock
+ .wbm_cyc_i (wbm_stb_i ), // strobe/request
+ .wbm_stb_i (wbm_stb_i ), // strobe/request
+ .wbm_adr_i (wbm_adr_i ), // address
+ .wbm_we_i (wbm_we_i ), // write
+ .wbm_dat_i (wbm_dat_i ), // data output
+ .wbm_sel_i (wbm_sel_i ), // byte enable
+ .wbm_dat_o (wbm_dat_o ), // data input
+ .wbm_ack_o (wbm_ack_o ), // acknowlegement
+ .wbm_err_o (wbm_err_o ), // error
+
+ // Slave Port
+ .wbs_rst_n (usb_rstn_i ), // Regular Reset signal
+ .wbs_clk_i (usb_clk_i ), // System clock
+ .wbs_cyc_o ( ), // strobe/request
+ .wbs_stb_o (reg_cs ), // strobe/request
+ .wbs_adr_o (reg_addr ), // address
+ .wbs_we_o (reg_wr ), // write
+ .wbs_dat_o (reg_wdata ), // data output
+ .wbs_sel_o (reg_be ), // byte enable
+ .wbs_dat_i (reg_rdata ), // data input
+ .wbs_ack_i (reg_ack ), // acknowlegement
+ .wbs_err_i (1'b0 ) // error
+
+ );
+
+usbh_core u_core (
+ // Inputs
+ .clk_i (usb_clk_i ),
+ .rstn_i (usb_rstn_i ),
+
+ .reg_cs (reg_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_rdata ),
+ .reg_ack (reg_ack ),
+
+ // Outputs
+ .intr_o (usb_intr_o ),
+
+ .utmi_data_in_i (utmi_data_in_i ),
+ .utmi_rxvalid_i (utmi_rxvalid_i ),
+ .utmi_rxactive_i (utmi_rxactive_i ),
+ .utmi_rxerror_i (utmi_rxerror_i ),
+ .utmi_linestate_i (utmi_linestate_i ),
+
+ .utmi_txready_i (utmi_txready_i ),
+ .utmi_data_out_o (utmi_data_out_o ),
+ .utmi_txvalid_o (utmi_txvalid_o ),
+
+ .utmi_op_mode_o (utmi_op_mode_o ),
+ .utmi_xcvrselect_o (utmi_xcvrselect_o ),
+ .utmi_termselect_o (utmi_termselect_o ),
+ .utmi_dppulldown_o (utmi_dppulldown_o ),
+ .utmi_dmpulldown_o (utmi_dmpulldown_o )
+);
+
+
+
+usb_fs_phy u_phy(
+ // Inputs
+ .clk_i (usb_clk_i ),
+ .rstn_i (usb_rstn_i ),
+ .utmi_data_out_i (utmi_data_out_o ),
+ .utmi_txvalid_i (utmi_txvalid_o ),
+ .utmi_op_mode_i (utmi_op_mode_o ),
+ .utmi_xcvrselect_i (utmi_xcvrselect_o ),
+ .utmi_termselect_i (utmi_termselect_o ),
+ .utmi_dppulldown_i (utmi_dppulldown_o ),
+ .utmi_dmpulldown_i (utmi_dmpulldown_o ),
+ .usb_rx_rcv_i (usb_pads_rx_rcv_w ),
+ .usb_rx_dp_i (usb_pads_rx_dp_w ),
+ .usb_rx_dn_i (usb_pads_rx_dn_w ),
+ .usb_reset_assert_i ( 1'b0 ),
+
+ // Outputs
+ .utmi_data_in_o (utmi_data_in_i ),
+ .utmi_txready_o (utmi_txready_i ),
+ .utmi_rxvalid_o (utmi_rxvalid_i ),
+ .utmi_rxactive_o (utmi_rxactive_i ),
+ .utmi_rxerror_o (utmi_rxerror_i ),
+ .utmi_linestate_o (utmi_linestate_i ),
+ .usb_tx_dp_o (usb_pads_tx_dp_w ),
+ .usb_tx_dn_o (usb_pads_tx_dn_w ),
+ .usb_tx_oen_o (usb_pads_tx_oen_w ),
+ .usb_reset_detect_o ( ),
+ .usb_en_o ( )
+ );
+
+
+ usb_transceiver u_usb_xcvr (
+ // Inputs
+ .usb_phy_tx_dp_i (usb_pads_tx_dp_w ),
+ .usb_phy_tx_dn_i (usb_pads_tx_dn_w ),
+ .usb_phy_tx_oen_i (usb_pads_tx_oen_w ),
+ .mode_i (usb_xcvr_mode_w ),
+
+ .out_dp (out_dp ),
+ .out_dn (out_dn ),
+ .out_tx_oen (out_tx_oen ),
+
+ .in_dp (in_dp ),
+ .in_dn (in_dn ),
+
+
+ // Outputs
+ .usb_phy_rx_rcv_o (usb_pads_rx_rcv_w ),
+ .usb_phy_rx_dp_o (usb_pads_rx_dp_w ),
+ .usb_phy_rx_dn_o (usb_pads_rx_dn_w )
+);
+
+
+endmodule
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
new file mode 100644
index 0000000..c39bf3b
--- /dev/null
+++ b/verilog/rtl/user_project_wrapper.v
@@ -0,0 +1,1632 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Digital core ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// This is digital core and integrate all the main block ////
+//// here. Following block are integrated here ////
+//// 1. Risc V Core ////
+//// 2. Quad SPI Master ////
+//// 3. Wishbone Cross Bar ////
+//// 4. UART ////
+//// 5, USB 1.1 ////
+//// 6. SPI Master (Single) ////
+//// 7. TCM SRAM 2KB ////
+//// 8. 2KB icache and 2KB dcache ////
+//// 8. 6 Channel ADC ////
+//// 9. Pinmux with GPIO and 6 PWM ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 16th Feb 2021, Dinesh A ////
+//// Initial integration with Risc-V core + ////
+//// Wishbone Cross Bar + SPI Master ////
+//// 0.2 - 17th June 2021, Dinesh A ////
+//// 1. In risc core, wishbone and core domain is ////
+//// created ////
+//// 2. cpu and rtc clock are generated in glbl reg block ////
+//// 3. in wishbone interconnect:- Stagging flop are added ////
+//// at interface to break wishbone timing path ////
+//// 4. buswidth warning are fixed inside spi_master ////
+//// modified rtl files are ////
+//// verilog/rtl/digital_core/src/digital_core.sv ////
+//// verilog/rtl/digital_core/src/glbl_cfg.sv ////
+//// verilog/rtl/lib/wb_stagging.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_dmem_wb.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_imem_wb.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_top_wb.sv ////
+//// verilog/rtl/user_project_wrapper.v ////
+//// verilog/rtl/wb_interconnect/src/wb_interconnect.sv ////
+//// verilog/rtl/spi_master/src/spim_clkgen.sv ////
+//// verilog/rtl/spi_master/src/spim_ctrl.sv ////
+//// 0.3 - 20th June 2021, Dinesh A ////
+//// 1. uart core is integrated ////
+//// 2. 3rd Slave ported added to wishbone interconnect ////
+//// 0.4 - 25th June 2021, Dinesh A ////
+//// Moved the pad logic inside sdram,spi,uart block to ////
+//// avoid logic at digital core level ////
+//// 0.5 - 25th June 2021, Dinesh A ////
+//// Since carvel gives only 16MB address space for user ////
+//// space, we have implemented indirect address select ////
+//// with 8 bit bank select given inside wb_host ////
+//// core Address = {Bank_Sel[7:0], Wb_Address[23:0] ////
+//// caravel user address space is ////
+//// 0x3000_0000 to 0x30FF_FFFF ////
+//// 0.6 - 27th June 2021, Dinesh A ////
+//// Digital core level tie are moved inside IP to avoid ////
+//// power hook up at core level ////
+//// u_risc_top - test_mode & test_rst_n ////
+//// u_intercon - s*_wbd_err_i ////
+//// unused wb_cti_i is removed from u_sdram_ctrl ////
+//// 0.7 - 28th June 2021, Dinesh A ////
+//// wb_interconnect master port are interchanged for ////
+//// better physical placement. ////
+//// m0 - External HOST ////
+//// m1 - RISC IMEM ////
+//// m2 - RISC DMEM ////
+//// 0.8 - 6th July 2021, Dinesh A ////
+//// For Better SDRAM Interface timing we have taping ////
+//// sdram_clock goint to io_out[29] directly from ////
+//// global register block, this help in better SDRAM ////
+//// interface timing control ////
+//// 0.9 - 7th July 2021, Dinesh A ////
+//// Removed 2 Unused port connection io_in[31:30] to ////
+//// spi_master to avoid lvs issue ////
+//// 1.0 - 28th July 2021, Dinesh A ////
+//// i2cm integrated part of uart_i2cm module, ////
+//// due to number of IO pin limitation, ////
+//// Only UART OR I2C selected based on config mode ////
+//// 1.1 - 1st Aug 2021, Dinesh A ////
+//// usb1.1 host integrated part of uart_i2cm_usb module,////
+//// due to number of IO pin limitation, ////
+//// Only UART/I2C/USB selected based on config mode ////
+//// 1.2 - 29th Sept 2021, Dinesh.A ////
+//// 1. copied the repo from yifive and renames as ////
+//// riscdunino ////
+//// 2. Removed the SDRAM controlled ////
+//// 3. Added PinMux ////
+//// 4. Added SAR ADC for 6 channel ////
+//// 1.3 - 30th Sept 2021, Dinesh.A ////
+//// 2KB SRAM Interface added to RISC Core ////
+//// 1.4 - 13th Oct 2021, Dinesh A ////
+//// Basic verification and Synthesis cleanup ////
+//// 1.5 - 6th Nov 2021, Dinesh A ////
+//// Clock Skew block moved inside respective block due ////
+//// to top-level power hook-up challenges for small IP ////
+//// 1.6 Nov 14, 2021, Dinesh A ////
+//// Major bug, clock divider inside the wb_host reset ////
+//// connectivity open is fixed ////
+//// 1.7 Nov 15, 2021, Dinesh A ////
+//// Bug fix in clk_ctrl High/Low counter width ////
+//// Removed sram_clock ////
+//// 1.8 Nov 23, 2021, Dinesh A ////
+//// Three Chip Specific Signature added at PinMux Reg ////
+//// reg_22,reg_23,reg_24 ////
+//// 1.9 Dec 11, 2021, Dinesh A ////
+//// 2 x 2K SRAM added into Wishbone Interface ////
+//// Temporary ADC block removed ////
+//// 2.0 Dec 14, 2021, Dinesh A ////
+//// Added two more 2K SRAM added into Wishbone Interface ////
+//// 2.1 Dec 16, 2021, Dinesh A ////
+//// 1.4 MBIST controller changed to single one ////
+//// 2.Added one more SRAM to TCM memory ////
+//// 3.WishBone Interconnect chang to take care mbist changes////
+//// 4.Pinmux change to take care of mbist changes ////
+//// 2.2 Dec 20, 2021, Dinesh A ////
+//// 1. MBIST design issue fix for yosys ////
+//// 2. Full chip Timing and Transition clean-up ////
+//// 2.3 Dec 24, 2021, Dinesh A ////
+//// UART Master added with message handler at wb_host ////
+//// 2.4 Jan 01, 2022, Dinesh A ////
+//// LA[0] is added as soft reset option at wb_port ////
+//// 2.5 Jan 06, 2022, Dinesh A ////
+//// TCM RAM Bug fix inside syntacore ////
+//// 2.6 Jan 08, 2022, Dinesh A ////
+//// Pinmux Interrupt Logic change ////
+//// 3.0 Jan 14, 2022, Dinesh A ////
+//// Moving from riscv core from syntacore/scr1 to ////
+//// yfive/ycr1 on sankranti 2022 (A Hindu New Year) ////
+//// 3.1 Jan 15, 2022, Dinesh A ////
+//// Major changes in qspim logic to handle special mode ////
+//// 3.2 Feb 02, 2022, Dinesh A ////
+//// Bug fix around icache/dcache and wishbone burst ////
+//// access clean-up ////
+//// 3.3 Feb 08, 2022, Dinesh A ////
+//// support added spisram support in qspim ip ////
+//// There are 4 chip select available in qspim ////
+//// CS#0/CS#1 targeted for SPI FLASH ////
+//// CS#2/CS#3 targeted for SPI SRAM ////
+//// 3.4 Feb 14, 2022, Dinesh A ////
+//// burst mode supported added in imem buffer inside ////
+//// riscv core ////
+//// We have created seperate repo from this onwards ////
+//// SRAM based SOC is spin-out to ////
+//// dineshannayya/riscduino_sram.git ////
+//// This repo will remove mbist + SRAM and RISC SRAM will be ////
+//// replaced with DFRAM ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module user_project_wrapper (
+`ifdef USE_POWER_PINS
+ inout vdda1, // User area 1 3.3V supply
+ inout vdda2, // User area 2 3.3V supply
+ inout vssa1, // User area 1 analog ground
+ inout vssa2, // User area 2 analog ground
+ inout vccd1, // User area 1 1.8V supply
+ inout vccd2, // User area 2 1.8v supply
+ inout vssd1, // User area 1 digital ground
+ inout vssd2, // User area 2 digital ground
+`endif
+ input wire wb_clk_i , // System clock
+ input wire user_clock2 , // user Clock
+ input wire wb_rst_i , // Regular Reset signal
+
+ input wire wbs_cyc_i , // strobe/request
+ input wire wbs_stb_i , // strobe/request
+ input wire [WB_WIDTH-1:0] wbs_adr_i , // address
+ input wire wbs_we_i , // write
+ input wire [WB_WIDTH-1:0] wbs_dat_i , // data output
+ input wire [3:0] wbs_sel_i , // byte enable
+ output wire [WB_WIDTH-1:0] wbs_dat_o , // data input
+ output wire wbs_ack_o , // acknowlegement
+
+ // Analog (direct connection to GPIO pad---use with caution)
+ // Note that analog I/O is not available on the 7 lowest-numbered
+ // GPIO pads, and so the analog_io indexing is offset from the
+ // GPIO indexing by 7 (also upper 2 GPIOs do not have analog_io).
+ inout [28:0] analog_io,
+
+ // Logic Analyzer Signals
+ input wire [127:0] la_data_in ,
+ output wire [127:0] la_data_out ,
+ input wire [127:0] la_oenb ,
+
+
+ // IOs
+ input wire [37:0] io_in ,
+ output wire [37:0] io_out ,
+ output wire [37:0] io_oeb ,
+
+ output wire [2:0] user_irq
+
+);
+
+//---------------------------------------------------
+// Local Parameter Declaration
+// --------------------------------------------------
+
+parameter BIST_NO_SRAM = 4; // NO of MBIST MEMORY
+parameter SDR_DW = 8; // SDR Data Width
+parameter SDR_BW = 1; // SDR Byte Width
+parameter WB_WIDTH = 32; // WB ADDRESS/DARA WIDTH
+parameter BIST1_ADDR_WD = 11; // 512x32 SRAM
+parameter BIST_DATA_WD = 32;
+
+//---------------------------------------------------------------------
+// Wishbone Risc V Dcache Memory Interface
+//---------------------------------------------------------------------
+wire wbd_riscv_dcache_stb_i ; // strobe/request
+wire [WB_WIDTH-1:0] wbd_riscv_dcache_adr_i ; // address
+wire wbd_riscv_dcache_we_i ; // write
+wire [WB_WIDTH-1:0] wbd_riscv_dcache_dat_i ; // data output
+wire [3:0] wbd_riscv_dcache_sel_i ; // byte enable
+wire [9:0] wbd_riscv_dcache_bl_i ; // burst length
+wire wbd_riscv_dcache_bry_i ; // burst ready
+wire [WB_WIDTH-1:0] wbd_riscv_dcache_dat_o ; // data input
+wire wbd_riscv_dcache_ack_o ; // acknowlegement
+wire wbd_riscv_dcache_lack_o ; // last burst acknowlegement
+wire wbd_riscv_dcache_err_o ; // error
+
+// CACHE SRAM Memory I/F
+wire dcache_mem_clk0 ; // CLK
+wire dcache_mem_csb0 ; // CS#
+wire dcache_mem_web0 ; // WE#
+wire [8:0] dcache_mem_addr0 ; // Address
+wire [3:0] dcache_mem_wmask0 ; // WMASK#
+wire [31:0] dcache_mem_din0 ; // Write Data
+wire [31:0] dcache_mem_dout0 ; // Read Data
+
+// SRAM-0 PORT-1, IMEM I/F
+wire dcache_mem_clk1 ; // CLK
+wire dcache_mem_csb1 ; // CS#
+wire [8:0] dcache_mem_addr1 ; // Address
+wire [31:0] dcache_mem_dout1 ; // Read Data
+//---------------------------------------------------------------------
+// Wishbone Risc V Icache Memory Interface
+//---------------------------------------------------------------------
+wire wbd_riscv_icache_stb_i ; // strobe/request
+wire [WB_WIDTH-1:0] wbd_riscv_icache_adr_i ; // address
+wire wbd_riscv_icache_we_i ; // write
+wire [3:0] wbd_riscv_icache_sel_i ; // byte enable
+wire [9:0] wbd_riscv_icache_bl_i ; // burst length
+wire wbd_riscv_icache_bry_i ; // burst ready
+wire [WB_WIDTH-1:0] wbd_riscv_icache_dat_o ; // data input
+wire wbd_riscv_icache_ack_o ; // acknowlegement
+wire wbd_riscv_icache_lack_o ; // last burst acknowlegement
+wire wbd_riscv_icache_err_o ; // error
+
+// CACHE SRAM Memory I/F
+wire icache_mem_clk0 ; // CLK
+wire icache_mem_csb0 ; // CS#
+wire icache_mem_web0 ; // WE#
+wire [8:0] icache_mem_addr0 ; // Address
+wire [3:0] icache_mem_wmask0 ; // WMASK#
+wire [31:0] icache_mem_din0 ; // Write Data
+// wire [31:0] icache_mem_dout0 ; // Read Data
+
+// SRAM-0 PORT-1, IMEM I/F
+wire icache_mem_clk1 ; // CLK
+wire icache_mem_csb1 ; // CS#
+wire [8:0] icache_mem_addr1 ; // Address
+wire [31:0] icache_mem_dout1 ; // Read Data
+
+//---------------------------------------------------------------------
+// RISC V Wishbone Data Memory Interface
+//---------------------------------------------------------------------
+wire wbd_riscv_dmem_stb_i ; // strobe/request
+wire [WB_WIDTH-1:0] wbd_riscv_dmem_adr_i ; // address
+wire wbd_riscv_dmem_we_i ; // write
+wire [WB_WIDTH-1:0] wbd_riscv_dmem_dat_i ; // data output
+wire [3:0] wbd_riscv_dmem_sel_i ; // byte enable
+wire [WB_WIDTH-1:0] wbd_riscv_dmem_dat_o ; // data input
+wire wbd_riscv_dmem_ack_o ; // acknowlegement
+wire wbd_riscv_dmem_err_o ; // error
+
+//---------------------------------------------------------------------
+// WB HOST Interface
+//---------------------------------------------------------------------
+wire wbd_int_cyc_i ; // strobe/request
+wire wbd_int_stb_i ; // strobe/request
+wire [WB_WIDTH-1:0] wbd_int_adr_i ; // address
+wire wbd_int_we_i ; // write
+wire [WB_WIDTH-1:0] wbd_int_dat_i ; // data output
+wire [3:0] wbd_int_sel_i ; // byte enable
+wire [WB_WIDTH-1:0] wbd_int_dat_o ; // data input
+wire wbd_int_ack_o ; // acknowlegement
+wire wbd_int_err_o ; // error
+//---------------------------------------------------------------------
+// SPI Master Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_spim_stb_o ; // strobe/request
+wire [WB_WIDTH-1:0] wbd_spim_adr_o ; // address
+wire wbd_spim_we_o ; // write
+wire [WB_WIDTH-1:0] wbd_spim_dat_o ; // data output
+wire [3:0] wbd_spim_sel_o ; // byte enable
+wire [9:0] wbd_spim_bl_o ; // Burst count
+wire wbd_spim_bry_o ; // Busrt Ready
+wire wbd_spim_cyc_o ;
+wire [WB_WIDTH-1:0] wbd_spim_dat_i ; // data input
+wire wbd_spim_ack_i ; // acknowlegement
+wire wbd_spim_lack_i ; // Last acknowlegement
+wire wbd_spim_err_i ; // error
+
+//---------------------------------------------------------------------
+// SPI Master Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_adc_stb_o ;
+wire [7:0] wbd_adc_adr_o ;
+wire wbd_adc_we_o ; // 1 - Write, 0 - Read
+wire [WB_WIDTH-1:0] wbd_adc_dat_o ;
+wire [WB_WIDTH/8-1:0] wbd_adc_sel_o ; // Byte enable
+wire wbd_adc_cyc_o ;
+wire [2:0] wbd_adc_cti_o ;
+wire [WB_WIDTH-1:0] wbd_adc_dat_i ;
+wire wbd_adc_ack_i ;
+
+//---------------------------------------------------------------------
+// Global Register Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_glbl_stb_o ; // strobe/request
+wire [7:0] wbd_glbl_adr_o ; // address
+wire wbd_glbl_we_o ; // write
+wire [WB_WIDTH-1:0] wbd_glbl_dat_o ; // data output
+wire [3:0] wbd_glbl_sel_o ; // byte enable
+wire wbd_glbl_cyc_o ;
+wire [WB_WIDTH-1:0] wbd_glbl_dat_i ; // data input
+wire wbd_glbl_ack_i ; // acknowlegement
+wire wbd_glbl_err_i ; // error
+
+//---------------------------------------------------------------------
+// Global Register Wishbone Interface
+//---------------------------------------------------------------------
+wire wbd_uart_stb_o ; // strobe/request
+wire [7:0] wbd_uart_adr_o ; // address
+wire wbd_uart_we_o ; // write
+wire [31:0] wbd_uart_dat_o ; // data output
+wire [3:0] wbd_uart_sel_o ; // byte enable
+wire wbd_uart_cyc_o ;
+wire [31:0] wbd_uart_dat_i ; // data input
+wire wbd_uart_ack_i ; // acknowlegement
+wire wbd_uart_err_i ; // error
+
+//---------------------------------------------------------------------
+// MBIST1
+//---------------------------------------------------------------------
+wire wbd_mbist_stb_o ; // strobe/request
+wire [12:0] wbd_mbist_adr_o ; // address
+wire wbd_mbist_we_o ; // write
+wire [WB_WIDTH-1:0] wbd_mbist_dat_o ; // data output
+wire [3:0] wbd_mbist_sel_o ; // byte enable
+wire [9:0] wbd_mbist_bl_o ; // byte enable
+wire wbd_mbist_bry_o ; // byte enable
+wire wbd_mbist_cyc_o ;
+wire [WB_WIDTH-1:0] wbd_mbist_dat_i ; // data input
+wire wbd_mbist_ack_i ; // acknowlegement
+wire wbd_mbist_lack_i ; // acknowlegement
+wire wbd_mbist_err_i ; // error
+
+//----------------------------------------------------
+// CPU Configuration
+//----------------------------------------------------
+wire cpu_rst_n ;
+wire qspim_rst_n ;
+wire sspim_rst_n ;
+wire uart_rst_n ; // uart reset
+wire i2c_rst_n ; // i2c reset
+wire usb_rst_n ; // i2c reset
+wire [3:0] boot_remap ; // Boot Remap
+wire [3:0] dcache_remap ; // Remap the dcache address
+wire cpu_clk ;
+wire rtc_clk ;
+wire usb_clk ;
+wire wbd_clk_int ;
+
+wire wbd_clk_pinmux ;
+//wire wbd_clk_int1 ;
+//wire wbd_clk_int2 ;
+wire wbd_int_rst_n ;
+//wire wbd_int1_rst_n ;
+//wire wbd_int2_rst_n ;
+
+wire [31:0] fuse_mhartid ;
+wire [15:0] irq_lines ;
+wire soft_irq ;
+
+
+wire [7:0] cfg_glb_ctrl ;
+wire [31:0] cfg_clk_ctrl1 ;
+wire [31:0] cfg_clk_ctrl2 ;
+wire [3:0] cfg_cska_wi ; // clock skew adjust for wishbone interconnect
+wire [3:0] cfg_cska_wh ; // clock skew adjust for web host
+
+wire [3:0] cfg_cska_riscv ; // clock skew adjust for riscv
+wire [3:0] cfg_cska_uart ; // clock skew adjust for uart
+wire [3:0] cfg_cska_qspi ; // clock skew adjust for spi
+wire [3:0] cfg_cska_pinmux ; // clock skew adjust for pinmux
+wire [3:0] cfg_cska_qspi_co ; // clock skew adjust for global reg
+wire [3:0] cfg_cska_mbist1 ;
+wire [3:0] cfg_cska_mbist2 ;
+wire [3:0] cfg_cska_mbist3 ;
+wire [3:0] cfg_cska_mbist4 ;
+
+// Bus Repeater Signals output from Wishbone Interface
+wire [3:0] cfg_cska_riscv_rp ; // clock skew adjust for riscv
+wire [3:0] cfg_cska_uart_rp ; // clock skew adjust for uart
+wire [3:0] cfg_cska_qspi_rp ; // clock skew adjust for spi
+wire [3:0] cfg_cska_pinmux_rp ; // clock skew adjust for pinmux
+wire [3:0] cfg_cska_qspi_co_rp ; // clock skew adjust for global reg
+wire [3:0] cfg_cska_mbist1_rp ;
+wire [3:0] cfg_cska_mbist2_rp ;
+wire [3:0] cfg_cska_mbist3_rp ;
+wire [3:0] cfg_cska_mbist4_rp ;
+
+wire [31:0] fuse_mhartid_rp ; // Repeater
+wire [15:0] irq_lines_rp ; // Repeater
+wire soft_irq_rp ; // Repeater
+
+wire wbd_clk_risc_rp ;
+wire wbd_clk_qspi_rp ;
+wire wbd_clk_uart_rp ;
+wire wbd_clk_pinmux_rp ;
+wire wbd_clk_mbist1_rp ;
+wire wbd_clk_mbist2_rp ;
+wire wbd_clk_mbist3_rp ;
+wire wbd_clk_mbist4_rp ;
+
+// Progammable Clock Skew inserted signals
+wire wbd_clk_wi_skew ; // clock for wishbone interconnect with clock skew
+wire wbd_clk_riscv_skew ; // clock for riscv with clock skew
+wire wbd_clk_uart_skew ; // clock for uart with clock skew
+wire wbd_clk_spi_skew ; // clock for spi with clock skew
+wire wbd_clk_glbl_skew ; // clock for global reg with clock skew
+wire wbd_clk_wh_skew ; // clock for global reg
+wire wbd_clk_mbist_skew ; // clock for global reg
+wire wbd_clk_mbist2_skew ; // clock for global reg
+wire wbd_clk_mbist3_skew ; // clock for global reg
+wire wbd_clk_mbist4_skew ; // clock for global reg
+
+
+
+wire [31:0] spi_debug ;
+wire [31:0] pinmux_debug ;
+wire [63:0] riscv_debug ;
+
+// SFLASH I/F
+wire sflash_sck ;
+wire [3:0] sflash_ss ;
+wire [3:0] sflash_oen ;
+wire [3:0] sflash_do ;
+wire [3:0] sflash_di ;
+
+// SSRAM I/F
+//wire ssram_sck ;
+//wire ssram_ss ;
+//wire ssram_oen ;
+//wire [3:0] ssram_do ;
+//wire [3:0] ssram_di ;
+
+// USB I/F
+wire usb_dp_o ;
+wire usb_dn_o ;
+wire usb_oen ;
+wire usb_dp_i ;
+wire usb_dn_i ;
+
+// UART I/F
+wire uart_txd ;
+wire uart_rxd ;
+
+// I2CM I/F
+wire i2cm_clk_o ;
+wire i2cm_clk_i ;
+wire i2cm_clk_oen ;
+wire i2cm_data_oen ;
+wire i2cm_data_o ;
+wire i2cm_data_i ;
+
+// SPI MASTER
+wire spim_sck ;
+wire spim_ss ;
+wire spim_miso ;
+wire spim_mosi ;
+
+wire [7:0] sar2dac ;
+wire analog_dac_out ;
+wire pulse1m_mclk ;
+wire h_reset_n ;
+
+`ifndef SCR1_TCM_MEM
+// SRAM-0 PORT-0 - DMEM I/F
+wire sram0_clk0 ; // CLK
+wire sram0_csb0 ; // CS#
+wire sram0_web0 ; // WE#
+wire [8:0] sram0_addr0 ; // Address
+wire [3:0] sram0_wmask0 ; // WMASK#
+wire [31:0] sram0_din0 ; // Write Data
+wire [31:0] sram0_dout0 ; // Read Data
+
+// SRAM-0 PORT-1, IMEM I/F
+wire sram0_clk1 ; // CLK
+wire sram0_csb1 ; // CS#
+wire [8:0] sram0_addr1 ; // Address
+wire [31:0] sram0_dout1 ; // Read Data
+
+// SRAM-1 PORT-0 - DMEM I/F
+wire sram1_clk0 ; // CLK
+wire sram1_csb0 ; // CS#
+wire sram1_web0 ; // WE#
+wire [8:0] sram1_addr0 ; // Address
+wire [3:0] sram1_wmask0 ; // WMASK#
+wire [31:0] sram1_din0 ; // Write Data
+wire [31:0] sram1_dout0 ; // Read Data
+
+// SRAM-1 PORT-1, IMEM I/F
+wire sram1_clk1 ; // CLK
+wire sram1_csb1 ; // CS#
+wire [8:0] sram1_addr1 ; // Address
+wire [31:0] sram1_dout1 ; // Read Data
+
+`endif
+
+// SPIM I/F
+wire sspim_sck ; // clock out
+wire sspim_so ; // serial data out
+wire sspim_si ; // serial data in
+wire sspim_ssn ; // cs_n
+
+
+wire usb_intr_o ;
+wire i2cm_intr_o ;
+
+//----------------------------------------------------------------
+// UART Master I/F
+// -------------------------------------------------------------
+wire uartm_rxd ;
+wire uartm_txd ;
+
+//----------------------------------------------------------
+// BIST I/F
+// ---------------------------------------------------------
+wire bist_en ;
+wire bist_run ;
+wire bist_load ;
+
+wire bist_sdi ;
+wire bist_shift ;
+wire bist_sdo ;
+
+wire bist_done ;
+wire [3:0] bist_error ;
+wire [3:0] bist_correct ;
+wire [3:0] bist_error_cnt0 ;
+wire [3:0] bist_error_cnt1 ;
+wire [3:0] bist_error_cnt2 ;
+wire [3:0] bist_error_cnt3 ;
+
+// With Repeater Buffer
+wire bist_en_rp ;
+wire bist_run_rp ;
+wire bist_load_rp ;
+
+wire bist_sdi_rp ;
+wire bist_shift_rp ;
+wire bist_sdo_rp ;
+
+wire bist_done_rp ;
+wire [3:0] bist_error_rp ;
+wire [3:0] bist_correct_rp ;
+wire [3:0] bist_error_cnt0_rp ;
+wire [3:0] bist_error_cnt1_rp ;
+wire [3:0] bist_error_cnt2_rp ;
+wire [3:0] bist_error_cnt3_rp ;
+
+// towards memory MBIST1
+// PORT-A
+wire [BIST_NO_SRAM-1:0] mem_clk_a ;
+wire [BIST1_ADDR_WD-1:2] mem0_addr_a ;
+wire [BIST1_ADDR_WD-1:2] mem1_addr_a ;
+wire [BIST1_ADDR_WD-1:2] mem2_addr_a ;
+wire [BIST1_ADDR_WD-1:2] mem3_addr_a ;
+wire [BIST_NO_SRAM-1:0] mem_cen_a ;
+wire [BIST_NO_SRAM-1:0] mem_web_a ;
+wire [BIST_DATA_WD/8-1:0] mem0_mask_a ;
+wire [BIST_DATA_WD/8-1:0] mem1_mask_a ;
+wire [BIST_DATA_WD/8-1:0] mem2_mask_a ;
+wire [BIST_DATA_WD/8-1:0] mem3_mask_a ;
+wire [BIST_DATA_WD-1:0] mem0_din_a ;
+wire [BIST_DATA_WD-1:0] mem1_din_a ;
+wire [BIST_DATA_WD-1:0] mem2_din_a ;
+wire [BIST_DATA_WD-1:0] mem3_din_a ;
+wire [BIST_DATA_WD-1:0] mem0_dout_a ;
+wire [BIST_DATA_WD-1:0] mem1_dout_a ;
+wire [BIST_DATA_WD-1:0] mem2_dout_a ;
+wire [BIST_DATA_WD-1:0] mem3_dout_a ;
+
+// PORT-B
+wire [BIST_NO_SRAM-1:0] mem_clk_b ;
+wire [BIST_NO_SRAM-1:0] mem_cen_b ;
+wire [BIST1_ADDR_WD-1:2] mem0_addr_b ;
+wire [BIST1_ADDR_WD-1:2] mem1_addr_b ;
+wire [BIST1_ADDR_WD-1:2] mem2_addr_b ;
+wire [BIST1_ADDR_WD-1:2] mem3_addr_b ;
+
+wire [3:0] spi_csn ;
+
+/////////////////////////////////////////////////////////
+// Clock Skew Ctrl
+////////////////////////////////////////////////////////
+
+assign cfg_cska_wi = cfg_clk_ctrl1[3:0];
+assign cfg_cska_wh = cfg_clk_ctrl1[7:4];
+assign cfg_cska_riscv = cfg_clk_ctrl1[11:8];
+assign cfg_cska_qspi = cfg_clk_ctrl1[15:12];
+assign cfg_cska_uart = cfg_clk_ctrl1[19:16];
+assign cfg_cska_pinmux = cfg_clk_ctrl1[23:20];
+assign cfg_cska_qspi_co = cfg_clk_ctrl1[27:24];
+
+assign cfg_cska_mbist1 = cfg_clk_ctrl2[3:0];
+assign cfg_cska_mbist2 = cfg_clk_ctrl2[7:4];
+assign cfg_cska_mbist3 = cfg_clk_ctrl2[11:8];
+assign cfg_cska_mbist4 = cfg_clk_ctrl2[15:12];
+assign dcache_remap = cfg_clk_ctrl2[27:24];
+assign boot_remap = cfg_clk_ctrl2[31:28];
+
+//assign la_data_out = {riscv_debug,spi_debug,sdram_debug};
+assign la_data_out[127:0] = {pinmux_debug,spi_debug,riscv_debug};
+
+//clk_buf u_buf1_wb_rstn (.clk_i(wbd_int_rst_n),.clk_o(wbd_int1_rst_n));
+//clk_buf u_buf2_wb_rstn (.clk_i(wbd_int1_rst_n),.clk_o(wbd_int2_rst_n));
+//
+//clk_buf u_buf1_wbclk (.clk_i(wbd_clk_int),.clk_o(wbd_clk_int1));
+//clk_buf u_buf2_wbclk (.clk_i(wbd_clk_int1),.clk_o(wbd_clk_int2));
+
+wb_host u_wb_host(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .user_clock1 (wb_clk_i ),
+ .user_clock2 (user_clock2 ),
+
+ .cpu_clk (cpu_clk ),
+ .rtc_clk (rtc_clk ),
+ .usb_clk (usb_clk ),
+
+ .wbd_int_rst_n (wbd_int_rst_n ),
+ .cpu_rst_n (cpu_rst_n ),
+ .qspim_rst_n (qspim_rst_n ),
+ .sspim_rst_n (sspim_rst_n ), // spi reset
+ .uart_rst_n (uart_rst_n ), // uart reset
+ .i2cm_rst_n (i2c_rst_n ), // i2c reset
+ .usb_rst_n (usb_rst_n ), // usb reset
+ .bist_rst_n (bist_rst_n ), // BIST Reset
+
+ // Master Port
+ .wbm_rst_i (wb_rst_i ),
+ .wbm_clk_i (wb_clk_i ),
+ .wbm_cyc_i (wbs_cyc_i ),
+ .wbm_stb_i (wbs_stb_i ),
+ .wbm_adr_i (wbs_adr_i ),
+ .wbm_we_i (wbs_we_i ),
+ .wbm_dat_i (wbs_dat_i ),
+ .wbm_sel_i (wbs_sel_i ),
+ .wbm_dat_o (wbs_dat_o ),
+ .wbm_ack_o (wbs_ack_o ),
+ .wbm_err_o ( ),
+
+ // Clock Skeq Adjust
+ .wbd_clk_int (wbd_clk_int ),
+ .wbd_clk_wh (wbd_clk_wh ),
+ .cfg_cska_wh (cfg_cska_wh ),
+
+ // Slave Port
+ .wbs_clk_out (wbd_clk_int ),
+ .wbs_clk_i (wbd_clk_wh ),
+ .wbs_cyc_o (wbd_int_cyc_i ),
+ .wbs_stb_o (wbd_int_stb_i ),
+ .wbs_adr_o (wbd_int_adr_i ),
+ .wbs_we_o (wbd_int_we_i ),
+ .wbs_dat_o (wbd_int_dat_i ),
+ .wbs_sel_o (wbd_int_sel_i ),
+ .wbs_dat_i (wbd_int_dat_o ),
+ .wbs_ack_i (wbd_int_ack_o ),
+ .wbs_err_i (wbd_int_err_o ),
+
+ .cfg_clk_ctrl1 (cfg_clk_ctrl1 ),
+ .cfg_clk_ctrl2 (cfg_clk_ctrl2 ),
+
+ .la_data_in (la_data_in[17:0] ),
+
+ .uartm_rxd (uartm_rxd ),
+ .uartm_txd (uartm_txd )
+
+
+ );
+
+
+
+
+//------------------------------------------------------------------------------
+// RISC V Core instance
+//------------------------------------------------------------------------------
+ycr1_top_wb u_riscv_top (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .wbd_clk_int (wbd_clk_risc_rp ),
+ .cfg_cska_riscv (cfg_cska_riscv_rp ),
+ .wbd_clk_riscv (wbd_clk_riscv_skew ),
+
+ // Reset
+ .pwrup_rst_n (wbd_int_rst_n ),
+ .rst_n (wbd_int_rst_n ),
+ .cpu_rst_n (cpu_rst_n ),
+ .riscv_debug (riscv_debug ),
+
+ // Clock
+ .core_clk (cpu_clk ),
+ .rtc_clk (rtc_clk ),
+
+ // Fuses
+ .fuse_mhartid (fuse_mhartid_rp ),
+
+ // IRQ
+ .irq_lines (irq_lines_rp ),
+ .soft_irq (soft_irq_rp ), // TODO - Interrupts
+
+ // DFT
+ // .test_mode (1'b0 ), // Moved inside IP
+ // .test_rst_n (1'b1 ), // Moved inside IP
+
+`ifndef SCR1_TCM_MEM
+ // SRAM-0 PORT-0
+ .sram0_clk0 (sram0_clk0 ),
+ .sram0_csb0 (sram0_csb0 ),
+ .sram0_web0 (sram0_web0 ),
+ .sram0_addr0 (sram0_addr0 ),
+ .sram0_wmask0 (sram0_wmask0 ),
+ .sram0_din0 (sram0_din0 ),
+ .sram0_dout0 (sram0_dout0 ),
+
+ // SRAM-0 PORT-0
+ .sram0_clk1 (sram0_clk1 ),
+ .sram0_csb1 (sram0_csb1 ),
+ .sram0_addr1 (sram0_addr1 ),
+ .sram0_dout1 (sram0_dout1 ),
+
+ // // SRAM-1 PORT-0
+ // .sram1_clk0 (sram1_clk0 ),
+ // .sram1_csb0 (sram1_csb0 ),
+ // .sram1_web0 (sram1_web0 ),
+ // .sram1_addr0 (sram1_addr0 ),
+ // .sram1_wmask0 (sram1_wmask0 ),
+ // .sram1_din0 (sram1_din0 ),
+ // .sram1_dout0 (sram1_dout0 ),
+ //
+ // // SRAM PORT-0
+ // .sram1_clk1 (sram1_clk1 ),
+ // .sram1_csb1 (sram1_csb1 ),
+ // .sram1_addr1 (sram1_addr1 ),
+ // .sram1_dout1 (sram1_dout1 ),
+`endif
+
+ .wb_rst_n (wbd_int_rst_n ),
+ .wb_clk (wbd_clk_riscv_skew ),
+
+ // Instruction cache memory interface
+ .wb_icache_stb_o (wbd_riscv_icache_stb_i ),
+ .wb_icache_adr_o (wbd_riscv_icache_adr_i ),
+ .wb_icache_we_o (wbd_riscv_icache_we_i ),
+ .wb_icache_sel_o (wbd_riscv_icache_sel_i ),
+ .wb_icache_bl_o (wbd_riscv_icache_bl_i ),
+ .wb_icache_bry_o (wbd_riscv_icache_bry_i ),
+ .wb_icache_dat_i (wbd_riscv_icache_dat_o ),
+ .wb_icache_ack_i (wbd_riscv_icache_ack_o ),
+ .wb_icache_lack_i (wbd_riscv_icache_lack_o ),
+ .wb_icache_err_i (wbd_riscv_icache_err_o ),
+
+ .icache_mem_clk0 (icache_mem_clk0 ), // CLK
+ .icache_mem_csb0 (icache_mem_csb0 ), // CS#
+ .icache_mem_web0 (icache_mem_web0 ), // WE#
+ .icache_mem_addr0 (icache_mem_addr0 ), // Address
+ .icache_mem_wmask0 (icache_mem_wmask0 ), // WMASK#
+ .icache_mem_din0 (icache_mem_din0 ), // Write Data
+// .icache_mem_dout0 (icache_mem_dout0 ), // Read Data
+
+
+ .icache_mem_clk1 (icache_mem_clk1 ), // CLK
+ .icache_mem_csb1 (icache_mem_csb1 ), // CS#
+ .icache_mem_addr1 (icache_mem_addr1 ), // Address
+ .icache_mem_dout1 (icache_mem_dout1 ), // Read Data
+
+ // Data cache memory interface
+ .wb_dcache_stb_o (wbd_riscv_dcache_stb_i ),
+ .wb_dcache_adr_o (wbd_riscv_dcache_adr_i ),
+ .wb_dcache_we_o (wbd_riscv_dcache_we_i ),
+ .wb_dcache_dat_o (wbd_riscv_dcache_dat_i ),
+ .wb_dcache_sel_o (wbd_riscv_dcache_sel_i ),
+ .wb_dcache_bl_o (wbd_riscv_dcache_bl_i ),
+ .wb_dcache_bry_o (wbd_riscv_dcache_bry_i ),
+ .wb_dcache_dat_i (wbd_riscv_dcache_dat_o ),
+ .wb_dcache_ack_i (wbd_riscv_dcache_ack_o ),
+ .wb_dcache_lack_i (wbd_riscv_dcache_lack_o ),
+ .wb_dcache_err_i (wbd_riscv_dcache_err_o ),
+
+ .dcache_mem_clk0 (dcache_mem_clk0 ), // CLK
+ .dcache_mem_csb0 (dcache_mem_csb0 ), // CS#
+ .dcache_mem_web0 (dcache_mem_web0 ), // WE#
+ .dcache_mem_addr0 (dcache_mem_addr0 ), // Address
+ .dcache_mem_wmask0 (dcache_mem_wmask0 ), // WMASK#
+ .dcache_mem_din0 (dcache_mem_din0 ), // Write Data
+ .dcache_mem_dout0 (dcache_mem_dout0 ), // Read Data
+
+
+ .dcache_mem_clk1 (dcache_mem_clk1 ), // CLK
+ .dcache_mem_csb1 (dcache_mem_csb1 ), // CS#
+ .dcache_mem_addr1 (dcache_mem_addr1 ), // Address
+ .dcache_mem_dout1 (dcache_mem_dout1 ), // Read Data
+
+
+ // Data memory interface
+ .wbd_dmem_stb_o (wbd_riscv_dmem_stb_i ),
+ .wbd_dmem_adr_o (wbd_riscv_dmem_adr_i ),
+ .wbd_dmem_we_o (wbd_riscv_dmem_we_i ),
+ .wbd_dmem_dat_o (wbd_riscv_dmem_dat_i ),
+ .wbd_dmem_sel_o (wbd_riscv_dmem_sel_i ),
+ .wbd_dmem_dat_i (wbd_riscv_dmem_dat_o ),
+ .wbd_dmem_ack_i (wbd_riscv_dmem_ack_o ),
+ .wbd_dmem_err_i (wbd_riscv_dmem_err_o )
+);
+
+`ifndef SCR1_TCM_MEM
+sky130_sram_2kbyte_1rw1r_32x512_8 u_tsram0_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// area 1 1.8V supply
+ .vssd1 (vssd1 ),// area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (sram0_clk0 ),
+ .csb0 (sram0_csb0 ),
+ .web0 (sram0_web0 ),
+ .wmask0 (sram0_wmask0 ),
+ .addr0 (sram0_addr0 ),
+ .din0 (sram0_din0 ),
+ .dout0 (sram0_dout0 ),
+// Port 1: R
+ .clk1 (sram0_clk1 ),
+ .csb1 (sram0_csb1 ),
+ .addr1 (sram0_addr1 ),
+ .dout1 (sram0_dout1 )
+ );
+
+/***
+sky130_sram_2kbyte_1rw1r_32x512_8 u_tsram1_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (sram1_clk0 ),
+ .csb0 (sram1_csb0 ),
+ .web0 (sram1_web0 ),
+ .wmask0 (sram1_wmask0 ),
+ .addr0 (sram1_addr0 ),
+ .din0 (sram1_din0 ),
+ .dout0 (sram1_dout0 ),
+// Port 1: R
+ .clk1 (sram1_clk1 ),
+ .csb1 (sram1_csb1 ),
+ .addr1 (sram1_addr1 ),
+ .dout1 (sram1_dout1 )
+ );
+***/
+`endif
+
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_icache_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (icache_mem_clk0 ),
+ .csb0 (icache_mem_csb0 ),
+ .web0 (icache_mem_web0 ),
+ .wmask0 (icache_mem_wmask0 ),
+ .addr0 (icache_mem_addr0 ),
+ .din0 (icache_mem_din0 ),
+ .dout0 ( ),
+// Port 1: R
+ .clk1 (icache_mem_clk1 ),
+ .csb1 (icache_mem_csb1 ),
+ .addr1 (icache_mem_addr1 ),
+ .dout1 (icache_mem_dout1 )
+ );
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_dcache_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (dcache_mem_clk0 ),
+ .csb0 (dcache_mem_csb0 ),
+ .web0 (dcache_mem_web0 ),
+ .wmask0 (dcache_mem_wmask0 ),
+ .addr0 (dcache_mem_addr0 ),
+ .din0 (dcache_mem_din0 ),
+ .dout0 (dcache_mem_dout0 ),
+// Port 1: R
+ .clk1 (dcache_mem_clk1 ),
+ .csb1 (dcache_mem_csb1 ),
+ .addr1 (dcache_mem_addr1 ),
+ .dout1 (dcache_mem_dout1 )
+ );
+
+
+/*********************************************************
+* SPI Master
+* This is implementation of an SPI master that is controlled via an AXI bus .
+* It has FIFOs for transmitting and receiving data.
+* It supports both the normal SPI mode and QPI mode with 4 data lines.
+* *******************************************************/
+
+qspim_top
+# (
+`ifndef SYNTHESIS
+ .WB_WIDTH (WB_WIDTH )
+`endif
+) u_qspi_master
+(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .mclk (wbd_clk_spi ),
+ .rst_n (qspim_rst_n ),
+
+ // Clock Skew Adjust
+ .cfg_cska_sp_co (cfg_cska_qspi_co_rp ),
+ .cfg_cska_spi (cfg_cska_qspi_rp ),
+ .wbd_clk_int (wbd_clk_qspi_rp ),
+ .wbd_clk_spi (wbd_clk_spi ),
+
+ .wbd_stb_i (wbd_spim_stb_o ),
+ .wbd_adr_i (wbd_spim_adr_o ),
+ .wbd_we_i (wbd_spim_we_o ),
+ .wbd_dat_i (wbd_spim_dat_o ),
+ .wbd_sel_i (wbd_spim_sel_o ),
+ .wbd_bl_i (wbd_spim_bl_o ),
+ .wbd_bry_i (wbd_spim_bry_o ),
+ .wbd_dat_o (wbd_spim_dat_i ),
+ .wbd_ack_o (wbd_spim_ack_i ),
+ .wbd_lack_o (wbd_spim_lack_i ),
+ .wbd_err_o (wbd_spim_err_i ),
+
+ .spi_debug (spi_debug ),
+
+ // Pad Interface
+ .spi_sdi (sflash_di ),
+ .spi_clk (sflash_sck ),
+ .spi_csn (spi_csn ),
+ .spi_sdo (sflash_do ),
+ .spi_oen (sflash_oen )
+
+);
+
+
+
+wb_interconnect #(
+ `ifndef SYNTHESIS
+ .CH_CLK_WD (8 ),
+ .CH_DATA_WD (116 )
+ `endif
+ ) u_intercon (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .ch_clk_in ({
+ wbd_clk_int,
+ wbd_clk_int,
+ wbd_clk_int,
+ wbd_clk_int,
+ wbd_clk_int,
+ wbd_clk_int,
+ wbd_clk_int,
+ wbd_clk_int} ),
+ .ch_clk_out ({
+ wbd_clk_mbist4_rp,
+ wbd_clk_mbist3_rp,
+ wbd_clk_mbist2_rp,
+ wbd_clk_mbist1_rp,
+ wbd_clk_pinmux_rp,
+ wbd_clk_uart_rp,
+ wbd_clk_qspi_rp,
+ wbd_clk_risc_rp} ),
+ .ch_data_in ({
+ bist_error_cnt3[3:0],
+ bist_correct[3],
+ bist_error[3],
+
+ bist_error_cnt2[3:0],
+ bist_correct[2],
+ bist_error[2],
+
+ bist_error_cnt1[3:0],
+ bist_correct[1],
+ bist_error[1],
+
+ bist_error_cnt0[3:0],
+ bist_correct[0],
+ bist_error[0],
+ bist_done,
+ bist_sdo,
+ bist_shift,
+ bist_sdi,
+ bist_load,
+ bist_run,
+ bist_en,
+
+
+ soft_irq,
+ irq_lines[15:0],
+ fuse_mhartid[31:0],
+
+ cfg_cska_mbist4[3:0],
+ cfg_cska_mbist3[3:0],
+ cfg_cska_mbist2[3:0],
+ cfg_cska_mbist1[3:0],
+ cfg_cska_qspi_co[3:0],
+ cfg_cska_pinmux[3:0],
+ cfg_cska_uart[3:0],
+ cfg_cska_qspi[3:0],
+ cfg_cska_riscv[3:0]
+ } ),
+ .ch_data_out ({
+ bist_error_cnt3_rp[3:0],
+ bist_correct_rp[3],
+ bist_error_rp[3],
+
+ bist_error_cnt2_rp[3:0],
+ bist_correct_rp[2],
+ bist_error_rp[2],
+
+ bist_error_cnt1_rp[3:0],
+ bist_correct_rp[1],
+ bist_error_rp[1],
+
+ bist_error_cnt0_rp[3:0],
+ bist_correct_rp[0],
+ bist_error_rp[0],
+ bist_done_rp,
+ bist_sdo_rp,
+ bist_shift_rp,
+ bist_sdi_rp,
+ bist_load_rp,
+ bist_run_rp,
+ bist_en_rp,
+
+ soft_irq_rp,
+ irq_lines_rp[15:0],
+ fuse_mhartid_rp[31:0],
+
+ cfg_cska_mbist4_rp[3:0],
+ cfg_cska_mbist3_rp[3:0],
+ cfg_cska_mbist2_rp[3:0],
+ cfg_cska_mbist1_rp[3:0],
+ cfg_cska_qspi_co_rp[3:0],
+ cfg_cska_pinmux_rp[3:0],
+ cfg_cska_uart_rp[3:0],
+ cfg_cska_qspi_rp[3:0],
+ cfg_cska_riscv_rp[3:0]
+ }),
+ // Clock Skew adjust
+ .wbd_clk_int (wbd_clk_int ),
+ .cfg_cska_wi (cfg_cska_wi ),
+ .wbd_clk_wi (wbd_clk_wi_skew ),
+
+ .clk_i (wbd_clk_wi_skew ),
+ .rst_n (wbd_int_rst_n ),
+ .dcache_remap (dcache_remap ),
+ .boot_remap (boot_remap ),
+
+ // Master 0 Interface
+ .m0_wbd_dat_i (wbd_int_dat_i ),
+ .m0_wbd_adr_i (wbd_int_adr_i ),
+ .m0_wbd_sel_i (wbd_int_sel_i ),
+ .m0_wbd_we_i (wbd_int_we_i ),
+ .m0_wbd_cyc_i (wbd_int_cyc_i ),
+ .m0_wbd_stb_i (wbd_int_stb_i ),
+ .m0_wbd_dat_o (wbd_int_dat_o ),
+ .m0_wbd_ack_o (wbd_int_ack_o ),
+ .m0_wbd_err_o (wbd_int_err_o ),
+
+ // Master 1 Interface
+ .m1_wbd_dat_i (wbd_riscv_dmem_dat_i ),
+ .m1_wbd_adr_i (wbd_riscv_dmem_adr_i ),
+ .m1_wbd_sel_i (wbd_riscv_dmem_sel_i ),
+ .m1_wbd_we_i (wbd_riscv_dmem_we_i ),
+ .m1_wbd_cyc_i (wbd_riscv_dmem_stb_i ),
+ .m1_wbd_stb_i (wbd_riscv_dmem_stb_i ),
+ .m1_wbd_dat_o (wbd_riscv_dmem_dat_o ),
+ .m1_wbd_ack_o (wbd_riscv_dmem_ack_o ),
+ .m1_wbd_err_o (wbd_riscv_dmem_err_o ),
+
+ // Master 2 Interface
+ .m2_wbd_dat_i (wbd_riscv_dcache_dat_i ),
+ .m2_wbd_adr_i (wbd_riscv_dcache_adr_i ),
+ .m2_wbd_sel_i (wbd_riscv_dcache_sel_i ),
+ .m2_wbd_bl_i (wbd_riscv_dcache_bl_i ),
+ .m2_wbd_bry_i (wbd_riscv_dcache_bry_i ),
+ .m2_wbd_we_i (wbd_riscv_dcache_we_i ),
+ .m2_wbd_cyc_i (wbd_riscv_dcache_stb_i ),
+ .m2_wbd_stb_i (wbd_riscv_dcache_stb_i ),
+ .m2_wbd_dat_o (wbd_riscv_dcache_dat_o ),
+ .m2_wbd_ack_o (wbd_riscv_dcache_ack_o ),
+ .m2_wbd_lack_o (wbd_riscv_dcache_lack_o ),
+ .m2_wbd_err_o (wbd_riscv_dcache_err_o ),
+
+ // Master 3 Interface
+ .m3_wbd_adr_i (wbd_riscv_icache_adr_i ),
+ .m3_wbd_sel_i (wbd_riscv_icache_sel_i ),
+ .m3_wbd_bl_i (wbd_riscv_icache_bl_i ),
+ .m3_wbd_bry_i (wbd_riscv_icache_bry_i ),
+ .m3_wbd_we_i (wbd_riscv_icache_we_i ),
+ .m3_wbd_cyc_i (wbd_riscv_icache_stb_i ),
+ .m3_wbd_stb_i (wbd_riscv_icache_stb_i ),
+ .m3_wbd_dat_o (wbd_riscv_icache_dat_o ),
+ .m3_wbd_ack_o (wbd_riscv_icache_ack_o ),
+ .m3_wbd_lack_o (wbd_riscv_icache_lack_o ),
+ .m3_wbd_err_o (wbd_riscv_icache_err_o ),
+
+
+ // Slave 0 Interface
+ // .s0_wbd_err_i (1'b0 ), - Moved inside IP
+ .s0_wbd_dat_i (wbd_spim_dat_i ),
+ .s0_wbd_ack_i (wbd_spim_ack_i ),
+ .s0_wbd_lack_i (wbd_spim_lack_i ),
+ .s0_wbd_dat_o (wbd_spim_dat_o ),
+ .s0_wbd_adr_o (wbd_spim_adr_o ),
+ .s0_wbd_bry_o (wbd_spim_bry_o ),
+ .s0_wbd_bl_o (wbd_spim_bl_o ),
+ .s0_wbd_sel_o (wbd_spim_sel_o ),
+ .s0_wbd_we_o (wbd_spim_we_o ),
+ .s0_wbd_cyc_o (wbd_spim_cyc_o ),
+ .s0_wbd_stb_o (wbd_spim_stb_o ),
+
+ // Slave 1 Interface
+ // .s1_wbd_err_i (1'b0 ), - Moved inside IP
+ .s1_wbd_dat_i (wbd_uart_dat_i ),
+ .s1_wbd_ack_i (wbd_uart_ack_i ),
+ .s1_wbd_dat_o (wbd_uart_dat_o ),
+ .s1_wbd_adr_o (wbd_uart_adr_o ),
+ .s1_wbd_sel_o (wbd_uart_sel_o ),
+ .s1_wbd_we_o (wbd_uart_we_o ),
+ .s1_wbd_cyc_o (wbd_uart_cyc_o ),
+ .s1_wbd_stb_o (wbd_uart_stb_o ),
+
+ // Slave 2 Interface
+ // .s2_wbd_err_i (1'b0 ), - Moved inside IP
+ .s2_wbd_dat_i (wbd_glbl_dat_i ),
+ .s2_wbd_ack_i (wbd_glbl_ack_i ),
+ .s2_wbd_dat_o (wbd_glbl_dat_o ),
+ .s2_wbd_adr_o (wbd_glbl_adr_o ),
+ .s2_wbd_sel_o (wbd_glbl_sel_o ),
+ .s2_wbd_we_o (wbd_glbl_we_o ),
+ .s2_wbd_cyc_o (wbd_glbl_cyc_o ),
+ .s2_wbd_stb_o (wbd_glbl_stb_o ),
+
+ // Slave 3 Interface
+ // .s3_wbd_err_i (1'b0 ), - Moved inside IP
+ .s3_wbd_dat_i (wbd_mbist_dat_i ),
+ .s3_wbd_ack_i (wbd_mbist_ack_i ),
+ .s3_wbd_lack_i (wbd_mbist_lack_i ),
+ .s3_wbd_dat_o (wbd_mbist_dat_o ),
+ .s3_wbd_adr_o (wbd_mbist_adr_o ),
+ .s3_wbd_sel_o (wbd_mbist_sel_o ),
+ .s3_wbd_bry_o (wbd_mbist_bry_o ),
+ .s3_wbd_bl_o (wbd_mbist_bl_o ),
+ .s3_wbd_we_o (wbd_mbist_we_o ),
+ .s3_wbd_cyc_o (wbd_mbist_cyc_o ),
+ .s3_wbd_stb_o (wbd_mbist_stb_o )
+
+ );
+
+
+uart_i2c_usb_spi_top u_uart_i2c_usb_spi (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .wbd_clk_int (wbd_clk_uart_rp ),
+ .cfg_cska_uart (cfg_cska_uart_rp ),
+ .wbd_clk_uart (wbd_clk_uart_skew ),
+
+ .uart_rstn (uart_rst_n ), // uart reset
+ .i2c_rstn (i2c_rst_n ), // i2c reset
+ .usb_rstn (usb_rst_n ), // USB reset
+ .spi_rstn (sspim_rst_n ), // SPI reset
+ .app_clk (wbd_clk_uart_skew ),
+ .usb_clk (usb_clk ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (wbd_uart_stb_o ),
+ .reg_wr (wbd_uart_we_o ),
+ .reg_addr (wbd_uart_adr_o[7:0] ),
+ .reg_wdata (wbd_uart_dat_o ),
+ .reg_be (wbd_uart_sel_o ),
+
+ // Outputs
+ .reg_rdata (wbd_uart_dat_i ),
+ .reg_ack (wbd_uart_ack_i ),
+
+ // Pad interface
+ .scl_pad_i (i2cm_clk_i ),
+ .scl_pad_o (i2cm_clk_o ),
+ .scl_pad_oen_o (i2cm_clk_oen ),
+
+ .sda_pad_i (i2cm_data_i ),
+ .sda_pad_o (i2cm_data_o ),
+ .sda_padoen_o (i2cm_data_oen ),
+
+ .i2cm_intr_o (i2cm_intr_o ),
+
+ .uart_rxd (uart_rxd ),
+ .uart_txd (uart_txd ),
+
+ .usb_in_dp (usb_dp_i ),
+ .usb_in_dn (usb_dn_i ),
+
+ .usb_out_dp (usb_dp_o ),
+ .usb_out_dn (usb_dn_o ),
+ .usb_out_tx_oen (usb_oen ),
+
+ .usb_intr_o (usb_intr_o ),
+
+ // SPIM Master
+ .sspim_sck (sspim_sck ),
+ .sspim_so (sspim_so ),
+ .sspim_si (sspim_si ),
+ .sspim_ssn (sspim_ssn )
+
+ );
+
+
+pinmux u_pinmux(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ //clk skew adjust
+ .cfg_cska_pinmux (cfg_cska_pinmux_rp ),
+ .wbd_clk_int (wbd_clk_pinmux_rp ),
+ .wbd_clk_pinmux (wbd_clk_pinmux_skew ),
+
+ // System Signals
+ // Inputs
+ .mclk (wbd_clk_pinmux_skew ),
+ .h_reset_n (wbd_int_rst_n ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (wbd_glbl_stb_o ),
+ .reg_wr (wbd_glbl_we_o ),
+ .reg_addr (wbd_glbl_adr_o ),
+ .reg_wdata (wbd_glbl_dat_o ),
+ .reg_be (wbd_glbl_sel_o ),
+
+ // Outputs
+ .reg_rdata (wbd_glbl_dat_i ),
+ .reg_ack (wbd_glbl_ack_i ),
+
+
+ // Risc configuration
+ .fuse_mhartid (fuse_mhartid ),
+ .irq_lines (irq_lines ),
+ .soft_irq (soft_irq ),
+ .user_irq (user_irq ),
+ .usb_intr (usb_intr_o ),
+ .i2cm_intr (i2cm_intr_o ),
+
+ // Digital IO
+ .digital_io_out (io_out ),
+ .digital_io_oen (io_oeb ),
+ .digital_io_in (io_in ),
+
+ // SFLASH I/F
+ .sflash_sck (sflash_sck ),
+ .sflash_ss (spi_csn ),
+ .sflash_oen (sflash_oen ),
+ .sflash_do (sflash_do ),
+ .sflash_di (sflash_di ),
+
+
+ // USB I/F
+ .usb_dp_o (usb_dp_o ),
+ .usb_dn_o (usb_dn_o ),
+ .usb_oen (usb_oen ),
+ .usb_dp_i (usb_dp_i ),
+ .usb_dn_i (usb_dn_i ),
+
+ // UART I/F
+ .uart_txd (uart_txd ),
+ .uart_rxd (uart_rxd ),
+
+ // I2CM I/F
+ .i2cm_clk_o (i2cm_clk_o ),
+ .i2cm_clk_i (i2cm_clk_i ),
+ .i2cm_clk_oen (i2cm_clk_oen ),
+ .i2cm_data_oen (i2cm_data_oen ),
+ .i2cm_data_o (i2cm_data_o ),
+ .i2cm_data_i (i2cm_data_i ),
+
+ // SPI MASTER
+ .spim_sck (sspim_sck ),
+ .spim_ss (sspim_ssn ),
+ .spim_miso (sspim_so ),
+ .spim_mosi (sspim_si ),
+
+ // UART MASTER I/F
+ .uartm_rxd (uartm_rxd ),
+ .uartm_txd (uartm_txd ),
+
+
+ .pulse1m_mclk (pulse1m_mclk ),
+
+ .pinmux_debug (pinmux_debug ),
+
+ // BIST I/F
+ .bist_en (bist_en ),
+ .bist_run (bist_run ),
+ .bist_load (bist_load ),
+
+ .bist_sdi (bist_sdi ),
+ .bist_shift (bist_shift ),
+ .bist_sdo (bist_sdo_rp ),
+
+ .bist_done (bist_done_rp ),
+ .bist_error (bist_error_rp ),
+ .bist_correct (bist_correct_rp ),
+ .bist_error_cnt0 (bist_error_cnt0_rp ),
+ .bist_error_cnt1 (bist_error_cnt1_rp ),
+ .bist_error_cnt2 (bist_error_cnt2_rp ),
+ .bist_error_cnt3 (bist_error_cnt3_rp )
+
+
+ );
+//------------- MBIST - 512x32 ----
+
+mbist_wrapper #(
+ `ifndef SYNTHESIS
+ .BIST_NO_SRAM (4 ),
+ .BIST_ADDR_WD (BIST1_ADDR_WD-2 ),
+ .BIST_DATA_WD (BIST_DATA_WD ),
+ .BIST_ADDR_START (9'h000 ),
+ .BIST_ADDR_END (9'h1FB ),
+ .BIST_REPAIR_ADDR_START (9'h1FC ),
+ .BIST_RAD_WD_I (BIST1_ADDR_WD-2 ),
+ .BIST_RAD_WD_O (BIST1_ADDR_WD-2 )
+ `endif
+ )
+ u_mbist (
+
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+
+ // Clock Skew adjust
+ .wbd_clk_int (wbd_clk_mbist1_rp ),
+ .cfg_cska_mbist (cfg_cska_mbist1_rp ),
+ .wbd_clk_mbist (wbd_clk_mbist_skew ),
+
+ // WB I/F
+ .wb_clk2_i (wbd_clk_mbist_skew ),
+ .wb_clk_i (wbd_clk_mbist_skew ),
+ .wb_stb_i (wbd_mbist_stb_o),
+ .wb_cs_i (wbd_mbist_adr_o[12:11]),
+ .wb_adr_i (wbd_mbist_adr_o[BIST1_ADDR_WD-1:2]),
+ .wb_we_i (wbd_mbist_we_o ),
+ .wb_dat_i (wbd_mbist_dat_o),
+ .wb_sel_i (wbd_mbist_sel_o),
+ .wb_bl_i (wbd_mbist_bl_o),
+ .wb_bry_i (wbd_mbist_bry_o),
+ .wb_dat_o (wbd_mbist_dat_i),
+ .wb_ack_o (wbd_mbist_ack_i),
+ .wb_lack_o (wbd_mbist_lack_i),
+ .wb_err_o ( ),
+
+ .rst_n (bist_rst_n ),
+
+
+ .bist_en (bist_en_rp ),
+ .bist_run (bist_run_rp ),
+ .bist_shift (bist_shift_rp ),
+ .bist_load (bist_load_rp ),
+ .bist_sdi (bist_sdi_rp ),
+
+ .bist_error_cnt3 (bist_error_cnt3 ),
+ .bist_error_cnt2 (bist_error_cnt2 ),
+ .bist_error_cnt1 (bist_error_cnt1 ),
+ .bist_error_cnt0 (bist_error_cnt0 ),
+ .bist_correct (bist_correct ),
+ .bist_error (bist_error ),
+ .bist_done (bist_done ),
+ .bist_sdo (bist_sdo ),
+
+ // towards memory
+ // PORT-A
+ .mem_clk_a (mem_clk_a ),
+ .mem_addr_a0 (mem0_addr_a ),
+ .mem_addr_a1 (mem1_addr_a ),
+ .mem_addr_a2 (mem2_addr_a ),
+ .mem_addr_a3 (mem3_addr_a ),
+ .mem_cen_a (mem_cen_a ),
+ .mem_web_a (mem_web_a ),
+ .mem_mask_a0 (mem0_mask_a ),
+ .mem_mask_a1 (mem1_mask_a ),
+ .mem_mask_a2 (mem2_mask_a ),
+ .mem_mask_a3 (mem3_mask_a ),
+ .mem_din_a0 (mem0_din_a ),
+ .mem_din_a1 (mem1_din_a ),
+ .mem_din_a2 (mem2_din_a ),
+ .mem_din_a3 (mem3_din_a ),
+ .mem_dout_a0 (mem0_dout_a ),
+ .mem_dout_a1 (mem1_dout_a ),
+ .mem_dout_a2 (mem2_dout_a ),
+ .mem_dout_a3 (mem3_dout_a ),
+ // PORT-B
+ .mem_clk_b (mem_clk_b ),
+ .mem_cen_b (mem_cen_b ),
+ .mem_addr_b0 (mem0_addr_b ),
+ .mem_addr_b1 (mem1_addr_b ),
+ .mem_addr_b2 (mem2_addr_b ),
+ .mem_addr_b3 (mem3_addr_b )
+
+
+);
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram0_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[0] ),
+ .csb0 (mem_cen_a[0] ),
+ .web0 (mem_web_a[0] ),
+ .wmask0 (mem0_mask_a ),
+ .addr0 (mem0_addr_a ),
+ .din0 (mem0_din_a ),
+ .dout0 (mem0_dout_a ),
+// Port 1: R
+ .clk1 (mem_clk_b[0] ),
+ .csb1 (mem_cen_b[0] ),
+ .addr1 (mem0_addr_b ),
+ .dout1 ( )
+ );
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram1_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[1] ),
+ .csb0 (mem_cen_a[1] ),
+ .web0 (mem_web_a[1] ),
+ .wmask0 (mem1_mask_a ),
+ .addr0 (mem1_addr_a ),
+ .din0 (mem1_din_a ),
+ .dout0 (mem1_dout_a ),
+// Port 1: R
+ .clk1 (mem_clk_b[1] ),
+ .csb1 (mem_cen_b[1] ),
+ .addr1 (mem1_addr_b ),
+ .dout1 ( )
+ );
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram2_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[2] ),
+ .csb0 (mem_cen_a[2] ),
+ .web0 (mem_web_a[2] ),
+ .wmask0 (mem2_mask_a ),
+ .addr0 (mem2_addr_a ),
+ .din0 (mem2_din_a ),
+ .dout0 (mem2_dout_a ),
+// Port 1: R
+ .clk1 (mem_clk_b[2] ),
+ .csb1 (mem_cen_b[2] ),
+ .addr1 (mem2_addr_b ),
+ .dout1 ( )
+ );
+
+
+sky130_sram_2kbyte_1rw1r_32x512_8 u_sram3_2kb(
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+// Port 0: RW
+ .clk0 (mem_clk_a[3] ),
+ .csb0 (mem_cen_a[3] ),
+ .web0 (mem_web_a[3] ),
+ .wmask0 (mem3_mask_a ),
+ .addr0 (mem3_addr_a ),
+ .din0 (mem3_din_a ),
+ .dout0 (mem3_dout_a ),
+// Port 1: R
+ .clk1 (mem_clk_b[3] ),
+ .csb1 (mem_cen_b[3] ),
+ .addr1 (mem3_addr_b ),
+ .dout1 ( )
+ );
+
+
+/***
+sar_adc u_adc (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1),// User area 1 1.8V supply
+ .vssd1 (vssd1),// User area 1 digital ground
+ .vccd2 (vccd1), // (vccd2),// User area 2 1.8V supply (analog) - DOTO: Need Fix
+ .vssd2 (vssd1), // (vssd2),// User area 2 ground (analog) - DOTO: Need Fix
+`endif
+
+
+ .clk (wbd_clk_adc_rp ),// The clock (digital)
+ .reset_n (wbd_int_rst_n ),// Active low reset (digital)
+
+ // Reg Bus Interface Signal
+ .reg_cs (wbd_adc_stb_o ),
+ .reg_wr (wbd_adc_we_o ),
+ .reg_addr (wbd_adc_adr_o[7:0] ),
+ .reg_wdata (wbd_adc_dat_o ),
+ .reg_be (wbd_adc_sel_o ),
+
+ // Outputs
+ .reg_rdata (wbd_adc_dat_i ),
+ .reg_ack (wbd_adc_ack_i ),
+
+ .pulse1m_mclk (pulse1m_mclk),
+
+
+ // DAC I/F
+ .sar2dac (sar2dac ),
+ //.analog_dac_out (analog_dac_out) , // TODO: Need to connect to DAC O/P
+ .analog_dac_out (analog_io[6]) ,
+
+ // ADC Input
+ .analog_din(analog_io[5:0]) // (Analog)
+
+);
+***/
+
+/****
+* TODO: Need to uncomment the DAC
+DAC_8BIT u_dac (
+ `ifdef USE_POWER_PINS
+ .vdd(vccd2),
+ .gnd(vssd2),
+ `endif
+ .d0(sar2dac[0]),
+ .d1(sar2dac[1]),
+ .d2(sar2dac[2]),
+ .d3(sar2dac[3]),
+ .d4(sar2dac[4]),
+ .d5(sar2dac[5]),
+ .d6(sar2dac[6]),
+ .d7(sar2dac[7]),
+ .inp1(analog_io[6]),
+ .out_v(analog_dac_out)
+ );
+
+**/
+
+endmodule : user_project_wrapper
diff --git a/verilog/rtl/wb_host/src/wb_host.sv b/verilog/rtl/wb_host/src/wb_host.sv
new file mode 100644
index 0000000..4cf0005
--- /dev/null
+++ b/verilog/rtl/wb_host/src/wb_host.sv
@@ -0,0 +1,574 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Wishbone host Interface ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block does async Wishbone from one clock to other ////
+//// clock domain ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 25th Feb 2021, Dinesh A ////
+//// initial version ////
+//// 0.2 - Nov 14 2021, Dinesh A ////
+//// Reset connectivity bug fix clk_ctl in u_sdramclk ////
+//// u_cpuclk,u_rtcclk,u_usbclk ////
+//// 0.3 - Nov 16 2021, Dinesh A ////
+//// Wishbone out are register for better timing ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module wb_host (
+
+`ifdef USE_POWER_PINS
+ inout vccd1, // User area 1 1.8V supply
+ inout vssd1, // User area 1 digital ground
+`endif
+ input logic user_clock1 ,
+ input logic user_clock2 ,
+
+ output logic cpu_clk ,
+ output logic rtc_clk ,
+ output logic usb_clk ,
+ // Global Reset control
+ output logic wbd_int_rst_n ,
+ output logic cpu_rst_n ,
+ output logic qspim_rst_n ,
+ output logic sspim_rst_n ,
+ output logic uart_rst_n ,
+ output logic i2cm_rst_n ,
+ output logic usb_rst_n ,
+ output logic bist_rst_n ,
+
+ // Master Port
+ input logic wbm_rst_i , // Regular Reset signal
+ input logic wbm_clk_i , // System clock
+ input logic wbm_cyc_i , // strobe/request
+ input logic wbm_stb_i , // strobe/request
+ input logic [31:0] wbm_adr_i , // address
+ input logic wbm_we_i , // write
+ input logic [31:0] wbm_dat_i , // data output
+ input logic [3:0] wbm_sel_i , // byte enable
+ output logic [31:0] wbm_dat_o , // data input
+ output logic wbm_ack_o , // acknowlegement
+ output logic wbm_err_o , // error
+
+ // Clock Skew Adjust
+ input logic wbd_clk_int ,
+ output logic wbd_clk_wh ,
+ input logic [3:0] cfg_cska_wh , // clock skew adjust for web host
+
+ // Slave Port
+ output logic wbs_clk_out , // System clock
+ input logic wbs_clk_i , // System clock
+ output logic wbs_cyc_o , // strobe/request
+ output logic wbs_stb_o , // strobe/request
+ output logic [31:0] wbs_adr_o , // address
+ output logic wbs_we_o , // write
+ output logic [31:0] wbs_dat_o , // data output
+ output logic [3:0] wbs_sel_o , // byte enable
+ input logic [31:0] wbs_dat_i , // data input
+ input logic wbs_ack_i , // acknowlegement
+ input logic wbs_err_i , // error
+
+ output logic [31:0] cfg_clk_ctrl1 ,
+ output logic [31:0] cfg_clk_ctrl2 ,
+
+ input logic [17:0] la_data_in ,
+
+ input logic uartm_rxd ,
+ output logic uartm_txd
+
+ );
+
+
+//--------------------------------
+// local dec
+//
+//--------------------------------
+logic wbm_rst_n;
+logic wbs_rst_n;
+
+logic reg_sel ;
+logic [1:0] sw_addr ;
+logic sw_rd_en ;
+logic sw_wr_en ;
+logic [31:0] reg_rdata ;
+logic [31:0] reg_out ;
+logic reg_ack ;
+logic [7:0] config_reg ;
+logic [31:0] clk_ctrl1 ;
+logic [31:0] clk_ctrl2 ;
+logic sw_wr_en_0;
+logic sw_wr_en_1;
+logic sw_wr_en_2;
+logic sw_wr_en_3;
+logic [7:0] cfg_bank_sel;
+logic [31:0] reg_0; // Software_Reg_0
+
+logic [2:0] cfg_wb_clk_ctrl;
+logic [3:0] cfg_cpu_clk_ctrl;
+logic [7:0] cfg_rtc_clk_ctrl;
+logic [3:0] cfg_usb_clk_ctrl;
+logic [8:0] cfg_glb_ctrl;
+
+// uart Master Port
+logic wbm_uart_cyc_i ; // strobe/request
+logic wbm_uart_stb_i ; // strobe/request
+logic [31:0] wbm_uart_adr_i ; // address
+logic wbm_uart_we_i ; // write
+logic [31:0] wbm_uart_dat_i ; // data output
+logic [3:0] wbm_uart_sel_i ; // byte enable
+logic [31:0] wbm_uart_dat_o ; // data input
+logic wbm_uart_ack_o ; // acknowlegement
+logic wbm_uart_err_o ; // error
+
+// Selected Master Port
+logic wb_cyc_i ; // strobe/request
+logic wb_stb_i ; // strobe/request
+logic [31:0] wb_adr_i ; // address
+logic wb_we_i ; // write
+logic [31:0] wb_dat_i ; // data output
+logic [3:0] wb_sel_i ; // byte enable
+logic [31:0] wb_dat_o ; // data input
+logic wb_ack_o ; // acknowlegement
+logic wb_err_o ; // error
+logic [31:0] wb_adr_int ;
+logic wb_stb_int ;
+logic [31:0] wb_dat_int ; // data input
+logic wb_ack_int ; // acknowlegement
+logic wb_err_int ; // error
+
+
+ctech_buf u_buf_wb_rst (.A(cfg_glb_ctrl[0]),.X(wbd_int_rst_n));
+ctech_buf u_buf_cpu_rst (.A(cfg_glb_ctrl[1]),.X(cpu_rst_n));
+ctech_buf u_buf_qspim_rst (.A(cfg_glb_ctrl[2]),.X(qspim_rst_n));
+ctech_buf u_buf_sspim_rst (.A(cfg_glb_ctrl[3]),.X(sspim_rst_n));
+ctech_buf u_buf_uart_rst (.A(cfg_glb_ctrl[4]),.X(uart_rst_n));
+ctech_buf u_buf_i2cm_rst (.A(cfg_glb_ctrl[5]),.X(i2cm_rst_n));
+ctech_buf u_buf_usb_rst (.A(cfg_glb_ctrl[6]),.X(usb_rst_n));
+ctech_buf u_buf_bist_rst (.A(cfg_glb_ctrl[7]),.X(bist_rst_n));
+
+//--------------------------------------------------------------------------------
+// Look like wishbone reset removed early than user Power up sequence
+// To control the reset phase, we have added additional control through la[0]
+// ------------------------------------------------------------------------------
+wire arst_n = !wbm_rst_i & la_data_in[0];
+reset_sync u_wbm_rst (
+ .scan_mode (1'b0 ),
+ .dclk (wbm_clk_i ), // Destination clock domain
+ .arst_n (arst_n ), // active low async reset
+ .srst_n (wbm_rst_n )
+ );
+
+reset_sync u_wbs_rst (
+ .scan_mode (1'b0 ),
+ .dclk (wbs_clk_i ), // Destination clock domain
+ .arst_n (arst_n ), // active low async reset
+ .srst_n (wbs_rst_n )
+ );
+
+// UART Master
+uart2wb u_uart2wb (
+ .arst_n (wbm_rst_n ), // sync reset
+ .app_clk (wbm_clk_i ), // sys clock
+
+ // configuration control
+ .cfg_tx_enable (la_data_in[1] ), // Enable Transmit Path
+ .cfg_rx_enable (la_data_in[2] ), // Enable Received Path
+ .cfg_stop_bit (la_data_in[3] ), // 0 -> 1 Start , 1 -> 2 Stop Bits
+ .cfg_baud_16x (la_data_in[15:4] ), // 16x Baud clock generation
+ .cfg_pri_mod (la_data_in[17:16] ), // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+
+ // Master Port
+ .wbm_cyc_o (wbm_uart_cyc_i ), // strobe/request
+ .wbm_stb_o (wbm_uart_stb_i ), // strobe/request
+ .wbm_adr_o (wbm_uart_adr_i ), // address
+ .wbm_we_o (wbm_uart_we_i ), // write
+ .wbm_dat_o (wbm_uart_dat_i ), // data output
+ .wbm_sel_o (wbm_uart_sel_i ), // byte enable
+ .wbm_dat_i (wbm_uart_dat_o ), // data input
+ .wbm_ack_i (wbm_uart_ack_o ), // acknowlegement
+ .wbm_err_i (wbm_uart_err_o ), // error
+
+ // Status information
+ .frm_error (), // framing error
+ .par_error (), // par error
+
+ .baud_clk_16x (), // 16x Baud clock
+
+ // Line Interface
+ .rxd (uartm_rxd) , // uart rxd
+ .txd (uartm_txd) // uart txd
+
+ );
+
+
+// Arbitor to select between external wb vs uart wb
+wire [1:0] grnt;
+wb_arb u_arb(
+ .clk (wbm_clk_i),
+ .rstn (wbm_rst_n),
+ .req ({1'b0,wbm_uart_stb_i,wbm_stb_i}),
+ .gnt (grnt)
+ );
+
+// Select the master based on the grant
+assign wb_cyc_i = (grnt == 2'b00) ? wbm_cyc_i : wbm_uart_cyc_i;
+assign wb_stb_i = (grnt == 2'b00) ? wbm_stb_i : wbm_uart_stb_i;
+assign wb_adr_i = (grnt == 2'b00) ? wbm_adr_i : wbm_uart_adr_i;
+assign wb_we_i = (grnt == 2'b00) ? wbm_we_i : wbm_uart_we_i;
+assign wb_dat_i = (grnt == 2'b00) ? wbm_dat_i : wbm_uart_dat_i;
+assign wb_sel_i = (grnt == 2'b00) ? wbm_sel_i : wbm_uart_sel_i;
+
+assign wbm_dat_o = (grnt == 2'b00) ? wb_dat_o : 'h0;
+assign wbm_ack_o = (grnt == 2'b00) ? wb_ack_o : 'h0;
+assign wbm_err_o = (grnt == 2'b00) ? wb_err_o : 'h0;
+
+
+assign wbm_uart_dat_o = (grnt == 2'b01) ? wb_dat_o : 'h0;
+assign wbm_uart_ack_o = (grnt == 2'b01) ? wb_ack_o : 'h0;
+assign wbm_uart_err_o = (grnt == 2'b01) ? wb_err_o : 'h0;
+
+
+
+
+
+// wb_host clock skew control
+clk_skew_adjust u_skew_wh
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_wh ),
+ .clk_out (wbd_clk_wh )
+ );
+
+
+// To reduce the load/Timing Wishbone I/F, Strobe is register to create
+// multi-cycle
+wire [31:0] wb_dat_o1 = (reg_sel) ? reg_rdata : wb_dat_int; // data input
+wire wb_ack_o1 = (reg_sel) ? reg_ack : wb_ack_int; // acknowlegement
+wire wb_err_o1 = (reg_sel) ? 1'b0 : wb_err_int; // error
+
+logic wb_req;
+// Hold fix for STROBE
+wire wb_stb_d1,wb_stb_d2,wb_stb_d3;
+ctech_delay_buf u_delay1_stb0 (.X(wb_stb_d1),.A(wb_stb_i));
+ctech_delay_buf u_delay2_stb1 (.X(wb_stb_d2),.A(wb_stb_d1));
+ctech_delay_buf u_delay2_stb2 (.X(wb_stb_d3),.A(wb_stb_d2));
+always_ff @(negedge wbm_rst_n or posedge wbm_clk_i) begin
+ if ( wbm_rst_n == 1'b0 ) begin
+ wb_req <= '0;
+ wb_dat_o <= '0;
+ wb_ack_o <= '0;
+ wb_err_o <= '0;
+ end else begin
+ wb_req <= wb_stb_d3 && ((wb_ack_o == 0) && (wb_ack_o1 == 0)) ;
+ wb_ack_o <= wb_ack_o1;
+ wb_err_o <= wb_err_o1;
+ if(wb_ack_o1) // Keep last data in the bus
+ wb_dat_o <= wb_dat_o1;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// Local register decide based on address[31] == 1
+//
+// Locally there register are define to control the reset and clock for user
+// area
+//-----------------------------------------------------------------------
+// caravel user space is 0x3000_0000 to 0x30FF_FFFF
+// So we have allocated
+// 0x3080_0000 - 0x3080_00FF - Assigned to WB Host Address Space
+// Since We need more than 16MB Address space to access SDRAM/SPI we have
+// added indirect MSB 8 bit address select option
+// So Address will be {Bank_Sel[7:0], wbm_adr_i[23:0}
+// ---------------------------------------------------------------------
+assign reg_sel = wb_req & (wb_adr_i[23] == 1'b1);
+
+assign sw_addr = wb_adr_i [3:2];
+assign sw_rd_en = reg_sel & !wb_we_i;
+assign sw_wr_en = reg_sel & wb_we_i;
+
+assign sw_wr_en_0 = sw_wr_en && (sw_addr==0);
+assign sw_wr_en_1 = sw_wr_en && (sw_addr==1);
+assign sw_wr_en_2 = sw_wr_en && (sw_addr==2);
+assign sw_wr_en_3 = sw_wr_en && (sw_addr==3);
+
+always @ (posedge wbm_clk_i or negedge wbm_rst_n)
+begin : preg_out_Seq
+ if (wbm_rst_n == 1'b0)
+ begin
+ reg_rdata <= 'h0;
+ reg_ack <= 1'b0;
+ end
+ else if (sw_rd_en && !reg_ack)
+ begin
+ reg_rdata <= reg_out ;
+ reg_ack <= 1'b1;
+ end
+ else if (sw_wr_en && !reg_ack)
+ reg_ack <= 1'b1;
+ else
+ begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+//-------------------------------------
+// Global + Clock Control
+// -------------------------------------
+assign cfg_glb_ctrl = reg_0[8:0];
+assign cfg_wb_clk_ctrl = reg_0[11:9];
+assign cfg_rtc_clk_ctrl = reg_0[19:12];
+assign cfg_cpu_clk_ctrl = reg_0[23:20];
+assign cfg_usb_clk_ctrl = reg_0[31:28];
+
+
+always @( *)
+begin
+ reg_out [31:0] = 8'd0;
+
+ case (sw_addr [1:0])
+ 2'b00 : reg_out [31:0] = reg_0;
+ 2'b01 : reg_out [31:0] = {24'h0,cfg_bank_sel [7:0]};
+ 2'b10 : reg_out [31:0] = cfg_clk_ctrl1 [31:0];
+ 2'b11 : reg_out [31:0] = cfg_clk_ctrl2 [31:0];
+ default : reg_out [31:0] = 'h0;
+ endcase
+end
+
+
+
+generic_register #(32,0 ) u_glb_ctrl (
+ .we ({32{sw_wr_en_0}} ),
+ .data_in (wb_dat_i[31:0] ),
+ .reset_n (wbm_rst_n ),
+ .clk (wbm_clk_i ),
+
+ //List of Outs
+ .data_out (reg_0[31:0])
+ );
+
+generic_register #(8,8'h10 ) u_bank_sel (
+ .we ({8{sw_wr_en_1}} ),
+ .data_in (wb_dat_i[7:0] ),
+ .reset_n (wbm_rst_n ),
+ .clk (wbm_clk_i ),
+
+ //List of Outs
+ .data_out (cfg_bank_sel[7:0] )
+ );
+
+
+generic_register #(32,0 ) u_clk_ctrl1 (
+ .we ({32{sw_wr_en_2}} ),
+ .data_in (wb_dat_i[31:0] ),
+ .reset_n (wbm_rst_n ),
+ .clk (wbm_clk_i ),
+
+ //List of Outs
+ .data_out (cfg_clk_ctrl1[31:0])
+ );
+
+generic_register #(32,0 ) u_clk_ctrl2 (
+ .we ({32{sw_wr_en_3}} ),
+ .data_in (wb_dat_i[31:0] ),
+ .reset_n (wbm_rst_n ),
+ .clk (wbm_clk_i ),
+
+ //List of Outs
+ .data_out (cfg_clk_ctrl2[31:0])
+ );
+
+
+assign wb_stb_int = wb_req & !reg_sel;
+
+// Since design need more than 16MB address space, we have implemented
+// indirect access
+assign wb_adr_int = {cfg_bank_sel[7:0],wb_adr_i[23:0]};
+
+async_wb u_async_wb(
+// Master Port
+ .wbm_rst_n (wbm_rst_n ),
+ .wbm_clk_i (wbm_clk_i ),
+ .wbm_cyc_i (wb_cyc_i ),
+ .wbm_stb_i (wb_stb_int ),
+ .wbm_adr_i (wb_adr_int ),
+ .wbm_we_i (wb_we_i ),
+ .wbm_dat_i (wb_dat_i ),
+ .wbm_sel_i (wb_sel_i ),
+ .wbm_dat_o (wb_dat_int ),
+ .wbm_ack_o (wb_ack_int ),
+ .wbm_err_o (wb_err_int ),
+
+// Slave Port
+ .wbs_rst_n (wbs_rst_n ),
+ .wbs_clk_i (wbs_clk_i ),
+ .wbs_cyc_o (wbs_cyc_o ),
+ .wbs_stb_o (wbs_stb_o ),
+ .wbs_adr_o (wbs_adr_o ),
+ .wbs_we_o (wbs_we_o ),
+ .wbs_dat_o (wbs_dat_o ),
+ .wbs_sel_o (wbs_sel_o ),
+ .wbs_dat_i (wbs_dat_i ),
+ .wbs_ack_i (wbs_ack_i ),
+ .wbs_err_i (wbs_err_i )
+
+ );
+
+
+//----------------------------------
+// Generate Internal WishBone Clock
+//----------------------------------
+logic wb_clk_div;
+logic cfg_wb_clk_div;
+logic [1:0] cfg_wb_clk_ratio;
+
+assign cfg_wb_clk_ratio = cfg_wb_clk_ctrl[1:0];
+assign cfg_wb_clk_div = cfg_wb_clk_ctrl[2];
+
+
+//assign wbs_clk_out = (cfg_wb_clk_div) ? wb_clk_div : wbm_clk_i;
+ctech_mux2x1 u_wbs_clk_sel (.A0 (wbm_clk_i), .A1 (wb_clk_div), .S (cfg_wb_clk_div), .X (wbs_clk_out));
+
+
+clk_ctl #(1) u_wbclk (
+ // Outputs
+ .clk_o (wb_clk_div ),
+ // Inputs
+ .mclk (wbm_clk_i ),
+ .reset_n (wbm_rst_n ),
+ .clk_div_ratio (cfg_wb_clk_ratio )
+ );
+
+
+//----------------------------------
+// Generate CORE Clock Generation
+//----------------------------------
+wire cpu_clk_div;
+wire cpu_ref_clk;
+wire cpu_clk_int;
+
+wire cfg_cpu_clk_src_sel = cfg_cpu_clk_ctrl[3];
+wire cfg_cpu_clk_div = cfg_cpu_clk_ctrl[2];
+wire [1:0] cfg_cpu_clk_ratio = cfg_cpu_clk_ctrl[1:0];
+
+//assign cpu_ref_clk = (cfg_cpu_clk_src_sel) ? user_clock2 : user_clock1;
+//assign cpu_clk_int = (cfg_cpu_clk_div) ? cpu_clk_div : cpu_ref_clk;
+
+ctech_mux2x1 u_cpu_ref_sel (.A0 (user_clock1), .A1 (user_clock2), .S (cfg_cpu_clk_src_sel), .X (cpu_ref_clk));
+ctech_mux2x1 u_cpu_clk_sel (.A0 (cpu_ref_clk), .A1 (cpu_clk_div), .S (cfg_cpu_clk_div), .X (cpu_clk_int));
+
+ctech_clk_buf u_clkbuf_cpu (.A (cpu_clk_int), . X(cpu_clk));
+
+clk_ctl #(1) u_cpuclk (
+ // Outputs
+ .clk_o (cpu_clk_div ),
+ // Inputs
+ .mclk (cpu_ref_clk ),
+ .reset_n (wbm_rst_n ),
+ .clk_div_ratio (cfg_cpu_clk_ratio)
+ );
+
+//----------------------------------
+// Generate RTC Clock Generation
+//----------------------------------
+wire rtc_clk_div;
+wire [7:0] cfg_rtc_clk_ratio = cfg_rtc_clk_ctrl[7:0];
+
+
+ctech_clk_buf u_clkbuf_rtc (.A (rtc_clk_div), . X(rtc_clk));
+
+clk_ctl #(7) u_rtcclk (
+ // Outputs
+ .clk_o (rtc_clk_div ),
+ // Inputs
+ .mclk (user_clock2 ),
+ .reset_n (wbm_rst_n ),
+ .clk_div_ratio (cfg_rtc_clk_ratio)
+ );
+
+
+//----------------------------------
+// Generate USB Clock Generation
+//----------------------------------
+wire usb_clk_div;
+wire usb_ref_clk;
+wire usb_clk_int;
+
+wire cfg_usb_clk_div = cfg_usb_clk_ctrl[3];
+wire [2:0] cfg_usb_clk_ratio = cfg_usb_clk_ctrl[2:0];
+
+assign usb_ref_clk = user_clock2 ;
+//assign usb_clk_int = (cfg_usb_clk_div) ? usb_clk_div : usb_ref_clk;
+ctech_mux2x1 u_usb_clk_sel (.A0 (usb_ref_clk), .A1 (usb_clk_div), .S (cfg_usb_clk_div), .X (usb_clk_int));
+
+
+ctech_clk_buf u_clkbuf_usb (.A (usb_clk_int), . X(usb_clk));
+
+clk_ctl #(2) u_usbclk (
+ // Outputs
+ .clk_o (usb_clk_div ),
+ // Inputs
+ .mclk (usb_ref_clk ),
+ .reset_n (wbm_rst_n ),
+ .clk_div_ratio (cfg_usb_clk_ratio)
+ );
+
+endmodule
diff --git a/verilog/rtl/wb_interconnect/src/wb_arb.sv b/verilog/rtl/wb_interconnect/src/wb_arb.sv
new file mode 100644
index 0000000..aefac4a
--- /dev/null
+++ b/verilog/rtl/wb_interconnect/src/wb_arb.sv
@@ -0,0 +1,146 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Wishbone Arbitor ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This block implement simple round robine request ////
+// arbitor for wishbone interface. ////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module wb_arb(clk, rstn, req, gnt);
+
+input clk;
+input rstn;
+input [3:0] req; // Req input
+output [1:0] gnt; // Grant output
+
+///////////////////////////////////////////////////////////////////////
+//
+// Parameters
+//
+
+
+parameter [1:0]
+ grant0 = 3'h0,
+ grant1 = 3'h1,
+ grant2 = 3'h2,
+ grant3 = 3'h3;
+
+///////////////////////////////////////////////////////////////////////
+// Local Registers and Wires
+//////////////////////////////////////////////////////////////////////
+
+reg [1:0] state, next_state;
+
+///////////////////////////////////////////////////////////////////////
+// Misc Logic
+//////////////////////////////////////////////////////////////////////
+
+assign gnt = state;
+
+always@(posedge clk or negedge rstn)
+ if(!rstn) state <= grant0;
+ else state <= next_state;
+
+///////////////////////////////////////////////////////////////////////
+//
+// Next State Logic
+// - implements round robin arbitration algorithm
+// - switches grant if current req is dropped or next is asserted
+// - parks at last grant
+//////////////////////////////////////////////////////////////////////
+
+always@(state or req )
+ begin
+ next_state = state; // Default Keep State
+ case(state)
+ grant0:
+ // if this req is dropped or next is asserted, check for other req's
+ if(!req[0] ) begin
+ if(req[1]) next_state = grant1;
+ else if(req[2]) next_state = grant2;
+ else if(req[3]) next_state = grant3;
+ end
+ grant1:
+ // if this req is dropped or next is asserted, check for other req's
+ if(!req[1] ) begin
+ if(req[2]) next_state = grant2;
+ if(req[3]) next_state = grant3;
+ else if(req[0]) next_state = grant0;
+ end
+ grant2:
+ // if this req is dropped or next is asserted, check for other req's
+ if(!req[2] ) begin
+ if(req[0]) next_state = grant0;
+ else if(req[1]) next_state = grant1;
+ else if(req[3]) next_state = grant3;
+ end
+ grant3:
+ // if this req is dropped or next is asserted, check for other req's
+ if(!req[3] ) begin
+ if(req[0]) next_state = grant0;
+ else if(req[1]) next_state = grant1;
+ else if(req[2]) next_state = grant2;
+ end
+ endcase
+ end
+
+endmodule
+
diff --git a/verilog/rtl/wb_interconnect/src/wb_interconnect.sv b/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
new file mode 100644
index 0000000..ef22d72
--- /dev/null
+++ b/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
@@ -0,0 +1,609 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Wishbone Interconnect ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// 1. 3 masters and 3 slaves share bus Wishbone connection ////
+//// 2. This block implement simple round robine request ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 12th June 2021, Dinesh A ////
+//// 0.2 - 17th June 2021, Dinesh A ////
+//// Stagging FF added at Slave Interface to break ////
+//// path ////
+//// 0.3 - 21th June 2021, Dinesh A ////
+//// slave port 3 added for uart ////
+//// 0.4 - 25th June 2021, Dinesh A ////
+//// External Memory Map changed and made same as ////
+//// internal memory map ////
+//// 0.4 - 27th June 2021, Dinesh A ////
+//// unused tie off at digital core level brought inside ////
+//// to avoid core level power hook up ////
+//// 0.5 - 28th June 2021, Dinesh A ////
+//// interchange the Master port for better physical ////
+//// placement ////
+//// m0: external host ////
+//// m1: risc imem ////
+//// m2: risc dmem ////
+//// 0.6 - 06 Nov 2021, Dinesh A ////
+//// Push the clock skew logic inside the block due to ////
+//// global power hooking challanges for small block at ////
+//// top level ////
+//// 0.7 - 07 Dec 2021, Dinesh A ////
+//// Buffer channel are added insider wb_inter to simply ////
+//// global routing ////
+//// 0.8 -10 Dec 2021 , Dinesh A ////
+//// two more slave port added for MBIST and ADC port ////
+//// removed ////
+//// Memory remap added to move the RISC Program memory ////
+//// to SRAM Memory ////
+//// 0.9 - 15 Dec 2021, Dinesh A ////
+//// Consolidated 4 MBIST port into one 8KB Port ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+
+module wb_interconnect #(
+ parameter CH_CLK_WD = 7,
+ parameter CH_DATA_WD = 103
+ ) (
+`ifdef USE_POWER_PINS
+ input logic vccd1, // User area 1 1.8V supply
+ input logic vssd1, // User area 1 digital ground
+`endif
+ // Bus repeaters
+ input [CH_CLK_WD-1:0] ch_clk_in,
+ output [CH_CLK_WD-1:0] ch_clk_out,
+ input [CH_DATA_WD-1:0] ch_data_in,
+ output [CH_DATA_WD-1:0]ch_data_out,
+
+ // Clock Skew Adjust
+ input logic [3:0] cfg_cska_wi,
+ input logic wbd_clk_int,
+ output logic wbd_clk_wi,
+
+
+ input logic clk_i,
+ input logic rst_n,
+
+ input logic [3:0] boot_remap, // When remap is enabled
+ // [0] - 0x0000_0000 - 0x0000_07FF Map to MBIST1
+ // [1] - 0x0000_0800 - 0x0000_0FFF Map to MBIST2
+ // [2] - 0x0000_1000 - 0x0000_17FF Map to MBIST3
+ // [3] - 0x0000_1800 - 0x0000_1FFF Map to MBIST4
+ input logic [3:0] dcache_remap, // When dcache remap is enabled,
+ // [0] - 0x0800_0000 - 0x0800_07FF Map to MBIST1
+ // [1] - 0x0800_0800 - 0x0800_0FFF Map to MBIST2
+ // [2] - 0x0800_1000 - 0x0800_17FF Map to MBIST3
+ // [3] - 0x0800_1800 - 0x0800_1FFF Map to MBIST4
+
+ // Master 0 Interface
+ input logic [31:0] m0_wbd_dat_i,
+ input logic [31:0] m0_wbd_adr_i,
+ input logic [3:0] m0_wbd_sel_i,
+ input logic m0_wbd_we_i,
+ input logic m0_wbd_cyc_i,
+ input logic m0_wbd_stb_i,
+ output logic [31:0] m0_wbd_dat_o,
+ output logic m0_wbd_ack_o,
+ output logic m0_wbd_lack_o,
+ output logic m0_wbd_err_o,
+
+ // Master 1 Interface
+ input logic [31:0] m1_wbd_dat_i,
+ input logic [31:0] m1_wbd_adr_i,
+ input logic [3:0] m1_wbd_sel_i,
+ input logic m1_wbd_we_i,
+ input logic m1_wbd_cyc_i,
+ input logic m1_wbd_stb_i,
+ output logic [31:0] m1_wbd_dat_o,
+ output logic m1_wbd_ack_o,
+ output logic m1_wbd_lack_o,
+ output logic m1_wbd_err_o,
+
+ // Master 2 Interface
+ input logic [31:0] m2_wbd_dat_i,
+ input logic [31:0] m2_wbd_adr_i,
+ input logic [3:0] m2_wbd_sel_i,
+ input logic [9:0] m2_wbd_bl_i,
+ input logic m2_wbd_bry_i,
+ input logic m2_wbd_we_i,
+ input logic m2_wbd_cyc_i,
+ input logic m2_wbd_stb_i,
+ output logic [31:0] m2_wbd_dat_o,
+ output logic m2_wbd_ack_o,
+ output logic m2_wbd_lack_o,
+ output logic m2_wbd_err_o,
+
+ // Master 3 Interface
+ input logic [31:0] m3_wbd_adr_i,
+ input logic [3:0] m3_wbd_sel_i,
+ input logic [9:0] m3_wbd_bl_i,
+ input logic m3_wbd_bry_i,
+ input logic m3_wbd_we_i,
+ input logic m3_wbd_cyc_i,
+ input logic m3_wbd_stb_i,
+ output logic [31:0] m3_wbd_dat_o,
+ output logic m3_wbd_ack_o,
+ output logic m3_wbd_lack_o,
+ output logic m3_wbd_err_o,
+
+ // Slave 0 Interface
+ input logic [31:0] s0_wbd_dat_i,
+ input logic s0_wbd_ack_i,
+ input logic s0_wbd_lack_i,
+ //input logic s0_wbd_err_i, - unused
+ output logic [31:0] s0_wbd_dat_o,
+ output logic [31:0] s0_wbd_adr_o,
+ output logic [3:0] s0_wbd_sel_o,
+ output logic [9:0] s0_wbd_bl_o,
+ output logic s0_wbd_bry_o,
+ output logic s0_wbd_we_o,
+ output logic s0_wbd_cyc_o,
+ output logic s0_wbd_stb_o,
+
+ // Slave 1 Interface
+ input logic [31:0] s1_wbd_dat_i,
+ input logic s1_wbd_ack_i,
+ // input logic s1_wbd_err_i, - unused
+ output logic [31:0] s1_wbd_dat_o,
+ output logic [7:0] s1_wbd_adr_o,
+ output logic [3:0] s1_wbd_sel_o,
+ output logic s1_wbd_we_o,
+ output logic s1_wbd_cyc_o,
+ output logic s1_wbd_stb_o,
+
+ // Slave 2 Interface
+ input logic [31:0] s2_wbd_dat_i,
+ input logic s2_wbd_ack_i,
+ // input logic s2_wbd_err_i, - unused
+ output logic [31:0] s2_wbd_dat_o,
+ output logic [7:0] s2_wbd_adr_o, // glbl reg need only 8 bits
+ output logic [3:0] s2_wbd_sel_o,
+ output logic s2_wbd_we_o,
+ output logic s2_wbd_cyc_o,
+ output logic s2_wbd_stb_o,
+
+ // Slave 3 Interface
+ // MBIST
+ input logic [31:0] s3_wbd_dat_i,
+ input logic s3_wbd_ack_i,
+ input logic s3_wbd_lack_i,
+ // input logic s3_wbd_err_i,
+ output logic [31:0] s3_wbd_dat_o,
+ output logic [12:0] s3_wbd_adr_o,
+ output logic [3:0] s3_wbd_sel_o,
+ output logic [9:0] s3_wbd_bl_o,
+ output logic s3_wbd_bry_o,
+ output logic s3_wbd_we_o,
+ output logic s3_wbd_cyc_o,
+ output logic s3_wbd_stb_o
+ );
+
+////////////////////////////////////////////////////////////////////
+//
+// Type define
+//
+
+parameter TARGET_SPI_MEM = 4'b0000;
+parameter TARGET_SPI_REG = 4'b0000;
+parameter TARGET_UART = 4'b0001;
+parameter TARGET_PINMUX = 4'b0010;
+parameter TARGET_MBIST = 4'b0011;
+
+// WishBone Wr Interface
+typedef struct packed {
+ logic [31:0] wbd_dat;
+ logic [31:0] wbd_adr;
+ logic [3:0] wbd_sel;
+ logic [9:0] wbd_bl;
+ logic wbd_bry;
+ logic wbd_we;
+ logic wbd_cyc;
+ logic wbd_stb;
+ logic [3:0] wbd_tid; // target id
+} type_wb_wr_intf;
+
+// WishBone Rd Interface
+typedef struct packed {
+ logic [31:0] wbd_dat;
+ logic wbd_ack;
+ logic wbd_lack;
+ logic wbd_err;
+} type_wb_rd_intf;
+
+
+// Master Write Interface
+type_wb_wr_intf m0_wb_wr;
+type_wb_wr_intf m1_wb_wr;
+type_wb_wr_intf m2_wb_wr;
+type_wb_wr_intf m3_wb_wr;
+
+// Master Read Interface
+type_wb_rd_intf m0_wb_rd;
+type_wb_rd_intf m1_wb_rd;
+type_wb_rd_intf m2_wb_rd;
+type_wb_rd_intf m3_wb_rd;
+
+// Slave Write Interface
+type_wb_wr_intf s0_wb_wr;
+type_wb_wr_intf s1_wb_wr;
+type_wb_wr_intf s2_wb_wr;
+type_wb_wr_intf s3_wb_wr;
+
+// Slave Read Interface
+type_wb_rd_intf s0_wb_rd;
+type_wb_rd_intf s1_wb_rd;
+type_wb_rd_intf s2_wb_rd;
+type_wb_rd_intf s3_wb_rd;
+
+
+type_wb_wr_intf m_bus_wr; // Multiplexed Master I/F
+type_wb_rd_intf m_bus_rd; // Multiplexed Slave I/F
+
+type_wb_wr_intf s_bus_wr; // Multiplexed Master I/F
+type_wb_rd_intf s_bus_rd; // Multiplexed Slave I/F
+
+// channel repeater
+assign ch_clk_out = ch_clk_in;
+assign ch_data_out = ch_data_in;
+
+// Wishbone interconnect clock skew control
+clk_skew_adjust u_skew_wi
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_wi ),
+ .clk_out (wbd_clk_wi )
+ );
+
+//-------------------------------------------------------------------
+// EXTERNAL MEMORY MAP
+// 0x0000_0000 to 0x0FFF_FFFF - QSPI MEMORY
+// 0x1000_0000 to 0x1000_00FF - QSPIM REG
+// 0x1001_0000 to 0x1001_003F - UART
+// 0x1001_0040 to 0x1001_007F - I2C
+// 0x1001_0080 to 0x1001_00BF - USB
+// 0x1001_00C0 to 0x1001_00FF - SSPIM
+// 0x1002_0000 to 0x1002_00FF - PINMUX
+// 0x1003_0000 to 0x1003_07FF - SRAM-0 (2KB)
+// 0x1003_0800 to 0x1003_0FFF - SRAM-1 (2KB)
+// 0x1003_1000 to 0x1003_17FF - SRAM-2 (2KB)
+// 0x1003_1800 to 0x1003_1FFF - SRAM-3 (2KB)
+// 0x3080_0000 to 0x3080_00FF - WB HOST (This decoding happens at wb_host block)
+// ---------------------------------------------------------------------------
+//
+wire [3:0] m0_wbd_tid_i = (m0_wbd_adr_i[31:28] == 4'b0000 ) ? TARGET_SPI_MEM : // SPI
+ (m0_wbd_adr_i[31:16] == 16'h1000 ) ? TARGET_SPI_REG : // SPI REG
+ (m0_wbd_adr_i[31:16] == 16'h1001 ) ? TARGET_UART : // UART/I2C/USB/SPI
+ (m0_wbd_adr_i[31:16] == 16'h1002 ) ? TARGET_PINMUX : // PINMUX
+ (m0_wbd_adr_i[31:16] == 16'h1003 ) ? TARGET_MBIST : // MBIST
+ 4'b0000;
+
+//------------------------------
+// RISC Data Memory Map
+// 0x0000_0000 to 0x0FFF_FFFF - QSPIM MEMORY
+// 0x1000_0000 to 0x1000_00FF - QSPIM REG
+// 0x1001_0000 to 0x1001_003F - UART
+// 0x1001_0040 to 0x1001_007F - I2
+// 0x1001_0080 to 0x1001_00BF - USB
+// 0x1001_00C0 to 0x1001_00FF - SSPIM
+// 0x1002_0000 to 0x1002_00FF - PINMUX
+// 0x1003_0000 to 0x1003_07FF - SRAM-0 (2KB)
+// 0x1003_0800 to 0x1003_0FFF - SRAM-1 (2KB)
+// 0x1003_1000 to 0x1003_17FF - SRAM-2 (2KB)
+// 0x1003_1800 to 0x1003_1FFF - SRAM-3 (2KB)
+//-----------------------------
+//
+wire [3:0] m1_wbd_tid_i = (boot_remap[0] && m1_wbd_adr_i[31:11] == 21'h0) ? TARGET_MBIST:
+ (boot_remap[1] && m1_wbd_adr_i[31:11] == 21'h1) ? TARGET_MBIST:
+ (boot_remap[2] && m1_wbd_adr_i[31:11] == 21'h2) ? TARGET_MBIST:
+ (boot_remap[3] && m1_wbd_adr_i[31:11] == 21'h3) ? TARGET_MBIST:
+ (dcache_remap[0] && m1_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0000_0) ? TARGET_MBIST:
+ (dcache_remap[1] && m1_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0000_1) ? TARGET_MBIST:
+ (dcache_remap[2] && m1_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0001_0) ? TARGET_MBIST:
+ (dcache_remap[3] && m1_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0001_1) ? TARGET_MBIST:
+ (m1_wbd_adr_i[31:28] == 4'b0000 ) ? TARGET_SPI_MEM :
+ (m1_wbd_adr_i[31:16] == 16'h1000 ) ? TARGET_SPI_REG :
+ (m1_wbd_adr_i[31:16] == 16'h1001 ) ? TARGET_UART :
+ (m1_wbd_adr_i[31:16] == 16'h1002 ) ? TARGET_PINMUX :
+ (m1_wbd_adr_i[31:16] == 16'h1003 ) ? TARGET_MBIST :
+ 4'b0000;
+
+wire [3:0] m2_wbd_tid_i = (boot_remap[0] && m2_wbd_adr_i[31:11] == 21'h0) ? TARGET_MBIST:
+ (boot_remap[1] && m2_wbd_adr_i[31:11] == 21'h1) ? TARGET_MBIST:
+ (boot_remap[2] && m2_wbd_adr_i[31:11] == 21'h2) ? TARGET_MBIST:
+ (boot_remap[3] && m2_wbd_adr_i[31:11] == 21'h3) ? TARGET_MBIST:
+ (dcache_remap[0] && m2_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0000_0) ? TARGET_MBIST:
+ (dcache_remap[1] && m2_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0000_1) ? TARGET_MBIST:
+ (dcache_remap[2] && m2_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0001_0) ? TARGET_MBIST:
+ (dcache_remap[3] && m2_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0001_1) ? TARGET_MBIST:
+ (m2_wbd_adr_i[31:28] == 4'b0000 ) ? TARGET_SPI_MEM :
+ (m2_wbd_adr_i[31:16] == 16'h1000 ) ? TARGET_SPI_REG :
+ (m2_wbd_adr_i[31:16] == 16'h1001 ) ? TARGET_UART :
+ (m2_wbd_adr_i[31:16] == 16'h1002 ) ? TARGET_PINMUX :
+ (m2_wbd_adr_i[31:16] == 16'h1003 ) ? TARGET_MBIST :
+ 4'b0000;
+wire [3:0] m3_wbd_tid_i = (boot_remap[0] && m3_wbd_adr_i[31:11] == 21'h0) ? TARGET_MBIST:
+ (boot_remap[1] && m3_wbd_adr_i[31:11] == 21'h1) ? TARGET_MBIST:
+ (boot_remap[2] && m3_wbd_adr_i[31:11] == 21'h2) ? TARGET_MBIST:
+ (boot_remap[3] && m3_wbd_adr_i[31:11] == 21'h3) ? TARGET_MBIST:
+ (dcache_remap[0] && m3_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0000_0) ? TARGET_MBIST:
+ (dcache_remap[1] && m3_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0000_1) ? TARGET_MBIST:
+ (dcache_remap[2] && m3_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0001_0) ? TARGET_MBIST:
+ (dcache_remap[3] && m3_wbd_adr_i[31:11] == 21'b0000_1000_0000_0000_0001_1) ? TARGET_MBIST:
+ (m3_wbd_adr_i[31:28] == 4'b0000 ) ? TARGET_SPI_MEM :
+ (m3_wbd_adr_i[31:16] == 16'h1000 ) ? TARGET_SPI_REG :
+ (m3_wbd_adr_i[31:16] == 16'h1001 ) ? TARGET_UART :
+ (m3_wbd_adr_i[31:16] == 16'h1002 ) ? TARGET_PINMUX :
+ (m3_wbd_adr_i[31:16] == 16'h1003 ) ? TARGET_MBIST :
+ 4'b0000;
+//----------------------------------------
+// Master Mapping
+// -------------------------------------
+assign m0_wb_wr.wbd_dat = m0_wbd_dat_i;
+assign m0_wb_wr.wbd_adr = {m0_wbd_adr_i[31:2],2'b00};
+assign m0_wb_wr.wbd_sel = m0_wbd_sel_i;
+assign m0_wb_wr.wbd_bl = 'h1;
+assign m0_wb_wr.wbd_bry = 'b1;
+assign m0_wb_wr.wbd_we = m0_wbd_we_i;
+assign m0_wb_wr.wbd_cyc = m0_wbd_cyc_i;
+assign m0_wb_wr.wbd_stb = m0_wbd_stb_i;
+assign m0_wb_wr.wbd_tid = m0_wbd_tid_i;
+
+assign m1_wb_wr.wbd_dat = m1_wbd_dat_i;
+assign m1_wb_wr.wbd_adr = {m1_wbd_adr_i[31:2],2'b00};
+assign m1_wb_wr.wbd_sel = m1_wbd_sel_i;
+assign m1_wb_wr.wbd_bl = 'h1;
+assign m1_wb_wr.wbd_bry = 'b1;
+assign m1_wb_wr.wbd_we = m1_wbd_we_i;
+assign m1_wb_wr.wbd_cyc = m1_wbd_cyc_i;
+assign m1_wb_wr.wbd_stb = m1_wbd_stb_i;
+assign m1_wb_wr.wbd_tid = m1_wbd_tid_i;
+
+assign m2_wb_wr.wbd_dat = m2_wbd_dat_i;
+assign m2_wb_wr.wbd_adr = {m2_wbd_adr_i[31:2],2'b00};
+assign m2_wb_wr.wbd_sel = m2_wbd_sel_i;
+assign m2_wb_wr.wbd_bl = m2_wbd_bl_i;
+assign m2_wb_wr.wbd_bry = m2_wbd_bry_i;
+assign m2_wb_wr.wbd_we = m2_wbd_we_i;
+assign m2_wb_wr.wbd_cyc = m2_wbd_cyc_i;
+assign m2_wb_wr.wbd_stb = m2_wbd_stb_i;
+assign m2_wb_wr.wbd_tid = m2_wbd_tid_i;
+
+assign m3_wb_wr.wbd_dat = 'h0;
+assign m3_wb_wr.wbd_adr = {m3_wbd_adr_i[31:2],2'b00};
+assign m3_wb_wr.wbd_sel = m3_wbd_sel_i;
+assign m3_wb_wr.wbd_bl = m3_wbd_bl_i;
+assign m3_wb_wr.wbd_bry = m3_wbd_bry_i;
+assign m3_wb_wr.wbd_we = m3_wbd_we_i;
+assign m3_wb_wr.wbd_cyc = m3_wbd_cyc_i;
+assign m3_wb_wr.wbd_stb = m3_wbd_stb_i;
+assign m3_wb_wr.wbd_tid = m3_wbd_tid_i;
+
+assign m0_wbd_dat_o = m0_wb_rd.wbd_dat;
+assign m0_wbd_ack_o = m0_wb_rd.wbd_ack;
+assign m0_wbd_lack_o = m0_wb_rd.wbd_lack;
+assign m0_wbd_err_o = m0_wb_rd.wbd_err;
+
+assign m1_wbd_dat_o = m1_wb_rd.wbd_dat;
+assign m1_wbd_ack_o = m1_wb_rd.wbd_ack;
+assign m1_wbd_lack_o = m1_wb_rd.wbd_lack;
+assign m1_wbd_err_o = m1_wb_rd.wbd_err;
+
+assign m2_wbd_dat_o = m2_wb_rd.wbd_dat;
+assign m2_wbd_ack_o = m2_wb_rd.wbd_ack;
+assign m2_wbd_lack_o = m2_wb_rd.wbd_lack;
+assign m2_wbd_err_o = m2_wb_rd.wbd_err;
+
+assign m3_wbd_dat_o = m3_wb_rd.wbd_dat;
+assign m3_wbd_ack_o = m3_wb_rd.wbd_ack;
+assign m3_wbd_lack_o = m3_wb_rd.wbd_lack;
+assign m3_wbd_err_o = m3_wb_rd.wbd_err;
+
+//----------------------------------------
+// Slave Mapping
+// -------------------------------------
+// Masked Now and added stagging FF now
+ assign s0_wbd_dat_o = s0_wb_wr.wbd_dat ;
+ assign s0_wbd_adr_o = s0_wb_wr.wbd_adr ;
+ assign s0_wbd_sel_o = s0_wb_wr.wbd_sel ;
+ assign s0_wbd_bl_o = s0_wb_wr.wbd_bl ;
+ assign s0_wbd_bry_o = s0_wb_wr.wbd_bry ;
+ assign s0_wbd_we_o = s0_wb_wr.wbd_we ;
+ assign s0_wbd_cyc_o = s0_wb_wr.wbd_cyc ;
+ assign s0_wbd_stb_o = s0_wb_wr.wbd_stb ;
+
+ assign s1_wbd_dat_o = s1_wb_wr.wbd_dat ;
+ assign s1_wbd_adr_o = s1_wb_wr.wbd_adr[7:0] ;
+ assign s1_wbd_sel_o = s1_wb_wr.wbd_sel ;
+ assign s1_wbd_we_o = s1_wb_wr.wbd_we ;
+ assign s1_wbd_cyc_o = s1_wb_wr.wbd_cyc ;
+ assign s1_wbd_stb_o = s1_wb_wr.wbd_stb ;
+
+ assign s2_wbd_dat_o = s2_wb_wr.wbd_dat ;
+ assign s2_wbd_adr_o = s2_wb_wr.wbd_adr[7:0] ; // Global Reg Need 8 bit
+ assign s2_wbd_sel_o = s2_wb_wr.wbd_sel ;
+ assign s2_wbd_we_o = s2_wb_wr.wbd_we ;
+ assign s2_wbd_cyc_o = s2_wb_wr.wbd_cyc ;
+ assign s2_wbd_stb_o = s2_wb_wr.wbd_stb ;
+
+ assign s3_wbd_dat_o = s3_wb_wr.wbd_dat[31:0] ;
+ assign s3_wbd_adr_o = s3_wb_wr.wbd_adr[12:0] ; // MBIST Need 13 bit
+ assign s3_wbd_sel_o = s3_wb_wr.wbd_sel[3:0] ;
+ assign s3_wbd_bl_o = s3_wb_wr.wbd_bl ;
+ assign s3_wbd_bry_o = s3_wb_wr.wbd_bry ;
+ assign s3_wbd_we_o = s3_wb_wr.wbd_we ;
+ assign s3_wbd_cyc_o = s3_wb_wr.wbd_cyc ;
+ assign s3_wbd_stb_o = s3_wb_wr.wbd_stb ;
+
+
+ assign s0_wb_rd.wbd_dat = s0_wbd_dat_i ;
+ assign s0_wb_rd.wbd_ack = s0_wbd_ack_i ;
+ assign s0_wb_rd.wbd_lack = s0_wbd_lack_i ;
+ assign s0_wb_rd.wbd_err = 1'b0; // s0_wbd_err_i ; - unused
+
+ assign s1_wb_rd.wbd_dat = s1_wbd_dat_i ;
+ assign s1_wb_rd.wbd_ack = s1_wbd_ack_i ;
+ assign s1_wb_rd.wbd_lack = s1_wbd_ack_i ;
+ assign s1_wb_rd.wbd_err = 1'b0; // s1_wbd_err_i ; - unused
+
+ assign s2_wb_rd.wbd_dat = s2_wbd_dat_i ;
+ assign s2_wb_rd.wbd_ack = s2_wbd_ack_i ;
+ assign s2_wb_rd.wbd_lack = s2_wbd_ack_i ;
+ assign s2_wb_rd.wbd_err = 1'b0; // s2_wbd_err_i ; - unused
+
+ assign s3_wb_rd.wbd_dat = s3_wbd_dat_i ;
+ assign s3_wb_rd.wbd_ack = s3_wbd_ack_i ;
+ assign s3_wb_rd.wbd_lack = s3_wbd_lack_i ;
+ assign s3_wb_rd.wbd_err = 1'b0; // s3_wbd_err_i ; - unused
+
+//
+// arbitor
+//
+logic [1:0] gnt;
+
+wb_arb u_wb_arb(
+ .clk(clk_i),
+ .rstn(rst_n),
+ .req({ m3_wbd_stb_i & !m3_wbd_lack_o,
+ m2_wbd_stb_i & !m2_wbd_lack_o,
+ m1_wbd_stb_i & !m1_wbd_lack_o,
+ m0_wbd_stb_i & !m0_wbd_lack_o}),
+ .gnt(gnt)
+);
+
+
+// Generate Multiplexed Master Interface based on grant
+always_comb begin
+ case(gnt)
+ 3'h0: m_bus_wr = m0_wb_wr;
+ 3'h1: m_bus_wr = m1_wb_wr;
+ 3'h2: m_bus_wr = m2_wb_wr;
+ 3'h3: m_bus_wr = m3_wb_wr;
+ default: m_bus_wr = m0_wb_wr;
+ endcase
+end
+
+
+// Generate Multiplexed Slave Interface based on target Id
+wire [3:0] s_wbd_tid = s_bus_wr.wbd_tid; // to fix iverilog warning
+always_comb begin
+ case(s_wbd_tid)
+ 4'h0: s_bus_rd = s0_wb_rd;
+ 4'h1: s_bus_rd = s1_wb_rd;
+ 4'h2: s_bus_rd = s2_wb_rd;
+ 4'h3: s_bus_rd = s3_wb_rd;
+ default: s_bus_rd = s0_wb_rd;
+ endcase
+end
+
+
+// Connect Master => Slave
+assign s0_wb_wr = (s_wbd_tid == 3'b000) ? s_bus_wr : 'h0;
+assign s1_wb_wr = (s_wbd_tid == 3'b001) ? s_bus_wr : 'h0;
+assign s2_wb_wr = (s_wbd_tid == 3'b010) ? s_bus_wr : 'h0;
+assign s3_wb_wr = (s_wbd_tid == 3'b011) ? s_bus_wr : 'h0;
+
+// Connect Slave to Master
+assign m0_wb_rd = (gnt == 2'b00) ? m_bus_rd : 'h0;
+assign m1_wb_rd = (gnt == 2'b01) ? m_bus_rd : 'h0;
+assign m2_wb_rd = (gnt == 2'b10) ? m_bus_rd : 'h0;
+assign m3_wb_rd = (gnt == 2'b11) ? m_bus_rd : 'h0;
+
+
+// Stagging FF to break write and read timing path
+sync_wbb u_sync_wbb(
+ .clk_i (clk_i ),
+ .rst_n (rst_n ),
+ // WishBone Input master I/P
+ .wbm_dat_i (m_bus_wr.wbd_dat ),
+ .wbm_adr_i (m_bus_wr.wbd_adr ),
+ .wbm_sel_i (m_bus_wr.wbd_sel ),
+ .wbm_bl_i (m_bus_wr.wbd_bl ),
+ .wbm_bry_i (m_bus_wr.wbd_bry ),
+ .wbm_we_i (m_bus_wr.wbd_we ),
+ .wbm_cyc_i (m_bus_wr.wbd_cyc ),
+ .wbm_stb_i (m_bus_wr.wbd_stb ),
+ .wbm_tid_i (m_bus_wr.wbd_tid ),
+ .wbm_dat_o (m_bus_rd.wbd_dat ),
+ .wbm_ack_o (m_bus_rd.wbd_ack ),
+ .wbm_lack_o (m_bus_rd.wbd_lack ),
+ .wbm_err_o (m_bus_rd.wbd_err ),
+
+ // Slave Interface
+ .wbs_dat_i (s_bus_rd.wbd_dat ),
+ .wbs_ack_i (s_bus_rd.wbd_ack ),
+ .wbs_lack_i (s_bus_rd.wbd_lack ),
+ .wbs_err_i (s_bus_rd.wbd_err ),
+ .wbs_dat_o (s_bus_wr.wbd_dat ),
+ .wbs_adr_o (s_bus_wr.wbd_adr ),
+ .wbs_sel_o (s_bus_wr.wbd_sel ),
+ .wbs_bl_o (s_bus_wr.wbd_bl ),
+ .wbs_bry_o (s_bus_wr.wbd_bry ),
+ .wbs_we_o (s_bus_wr.wbd_we ),
+ .wbs_cyc_o (s_bus_wr.wbd_cyc ),
+ .wbs_stb_o (s_bus_wr.wbd_stb ),
+ .wbs_tid_o (s_bus_wr.wbd_tid )
+
+);
+
+
+endmodule
+