pull the git change from https://github.com/dineshannayya/riscduino.git on 15th Feb 2022 with SRAM
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..7c54d50
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "verilog/rtl/yifive/ycr1c"]
+	path = verilog/rtl/yifive/ycr1c
+	url = https://github.com/dineshannayya/ycr1c.git
+[submodule "verilog/rtl/qspim"]
+	path = verilog/rtl/qspim
+	url = https://github.com/dineshannayya/qspim.git
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..2067627
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,193 @@
+# 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_ROOT?=$(PWD)/caravel
+PRECHECK_ROOT?=${HOME}/mpw_precheck
+SIM ?= RTL
+DUMP ?= OFF
+
+# Install lite version of caravel, (1): caravel-lite, (0): caravel
+CARAVEL_LITE?=1
+
+ifeq ($(CARAVEL_LITE),1) 
+	CARAVEL_NAME := caravel-lite
+	CARAVEL_REPO := https://github.com/efabless/caravel-lite 
+	CARAVEL_TAG := 'mpw-5a'
+else
+	CARAVEL_NAME := caravel
+	CARAVEL_REPO := https://github.com/efabless/caravel 
+	CARAVEL_TAG := 'mpw-5a'
+endif
+
+# Install caravel as submodule, (1): submodule, (0): clone
+SUBMODULE?=1
+
+#RISCV COMPLIANCE test Environment
+COREMARK_DIR   = verilog/dv/riscv_regress/dependencies/coremark
+RISCV_COMP_DIR = verilog/dv/riscv_regress/dependencies/riscv-compliance
+RISCV_TEST_DIR = verilog/dv/riscv_regress/dependencies/riscv-tests
+
+COREMARK_REPO   =  https://github.com/eembc/coremark
+RISCV_COMP_REPO =  https://github.com/riscv/riscv-compliance
+RISCV_TEST_REPO =  https://github.com/riscv/riscv-tests
+
+COREMARK_BRANCH   =  7f420b6bdbff436810ef75381059944e2b0d79e8
+RISCV_COMP_BRANCH =  d51259b2a949be3af02e776c39e135402675ac9b
+RISCV_TEST_BRANCH =  e30978a71921159aec38eeefd848fca4ed39a826
+
+# Include Caravel Makefile Targets
+.PHONY: % : check-caravel
+%: 
+	export CARAVEL_ROOT=$(CARAVEL_ROOT) && $(MAKE) -f $(CARAVEL_ROOT)/Makefile $@
+
+# Verify Target for running simulations
+.PHONY: verify
+verify:
+	cd ./verilog/dv/ && \
+	export SIM=${SIM} DUMP=${DUMP} && \
+		$(MAKE) -j$(THREADS)
+
+# Install DV setup
+.PHONY: simenv
+simenv:
+	docker pull dineshannayya/dv_setup:latest
+
+PATTERNS=$(shell cd verilog/dv && find * -maxdepth 0 -type d)
+DV_PATTERNS = $(foreach dv, $(PATTERNS), verify-$(dv))
+TARGET_PATH=$(shell pwd)
+PDK_PATH=${PDK_ROOT}/sky130A
+VERIFY_COMMAND="cd ${TARGET_PATH}/verilog/dv/$* && export SIM=${SIM} DUMP=${DUMP} && make"
+$(DV_PATTERNS): verify-% : ./verilog/dv/% check-coremark_repo check-riscv_comp_repo check-riscv_test_repo
+	docker run -v ${TARGET_PATH}:${TARGET_PATH} -v ${PDK_PATH}:${PDK_PATH} \
+                -v ${CARAVEL_ROOT}:${CARAVEL_ROOT} \
+                -e TARGET_PATH=${TARGET_PATH} -e PDK_PATH=${PDK_PATH} \
+                -e CARAVEL_ROOT=${CARAVEL_ROOT} \
+                -u $(id -u $$USER):$(id -g $$USER) dineshannayya/dv_setup:mpw5 \
+                sh -c $(VERIFY_COMMAND)
+				
+# Openlane Makefile Targets
+BLOCKS = $(shell cd openlane && find * -maxdepth 0 -type d)
+.PHONY: $(BLOCKS)
+$(BLOCKS): %:
+	export CARAVEL_ROOT=$(CARAVEL_ROOT) && cd openlane && $(MAKE) $*
+
+# Install caravel
+.PHONY: install
+install:
+ifeq ($(SUBMODULE),1)
+	@echo "Installing $(CARAVEL_NAME) as a submodule.."
+# Convert CARAVEL_ROOT to relative path because .gitmodules doesn't accept '/'
+	$(eval CARAVEL_PATH := $(shell realpath --relative-to=$(shell pwd) $(CARAVEL_ROOT)))
+	@if [ ! -d $(CARAVEL_ROOT) ]; then git submodule add --name $(CARAVEL_NAME) $(CARAVEL_REPO) $(CARAVEL_PATH); fi
+	@git submodule update --init
+	@cd $(CARAVEL_ROOT); git checkout $(CARAVEL_BRANCH)
+	$(MAKE) simlink
+else
+	@echo "Installing $(CARAVEL_NAME).."
+	@git clone -b $(CARAVEL_TAG) $(CARAVEL_REPO) $(CARAVEL_ROOT)
+endif
+
+# Create symbolic links to caravel's main files
+.PHONY: simlink
+simlink: check-caravel
+### Symbolic links relative path to $CARAVEL_ROOT 
+	$(eval MAKEFILE_PATH := $(shell realpath --relative-to=openlane $(CARAVEL_ROOT)/openlane/Makefile))
+	$(eval PIN_CFG_PATH  := $(shell realpath --relative-to=openlane/user_project_wrapper $(CARAVEL_ROOT)/openlane/user_project_wrapper_empty/pin_order.cfg))
+	mkdir -p openlane
+	mkdir -p openlane/user_project_wrapper
+	cd openlane &&\
+	ln -sf $(MAKEFILE_PATH) Makefile
+	cd openlane/user_project_wrapper &&\
+	ln -sf $(PIN_CFG_PATH) pin_order.cfg
+
+# Update Caravel
+.PHONY: update_caravel
+update_caravel: check-caravel
+	cd $(CARAVEL_ROOT)/ && git checkout $(CARAVEL_TAG) && git pull
+
+# Uninstall Caravel
+.PHONY: uninstall
+uninstall: 
+	rm -rf $(CARAVEL_ROOT)
+
+# Install Openlane
+.PHONY: openlane
+openlane: 
+	cd openlane && $(MAKE) openlane
+
+# Install Pre-check
+# Default installs to the user home directory, override by "export PRECHECK_ROOT=<precheck-installation-path>"
+.PHONY: precheck
+precheck:
+	@git clone --depth=1 --branch mpw-5 https://github.com/efabless/mpw_precheck.git $(PRECHECK_ROOT)
+	@docker pull efabless/mpw_precheck:mpw5
+
+.PHONY: run-precheck
+run-precheck: check-precheck check-pdk check-caravel
+	$(eval INPUT_DIRECTORY := $(shell pwd))
+	cd $(PRECHECK_ROOT) && \
+	docker run -e INPUT_DIRECTORY=$(INPUT_DIRECTORY) -e PDK_ROOT=$(PDK_ROOT) -v $(PRECHECK_ROOT):$(PRECHECK_ROOT) -v $(INPUT_DIRECTORY):$(INPUT_DIRECTORY) -v $(PDK_ROOT):$(PDK_ROOT) \
+	-u $(shell id -u $(USER)):$(shell id -g $(USER)) efabless/mpw_precheck:latest bash -c "cd $(PRECHECK_ROOT) ; python3 mpw_precheck.py --pdk_root $(PDK_ROOT) --input_directory $(INPUT_DIRECTORY)"
+
+# Clean 
+.PHONY: clean
+clean:
+	cd ./verilog/dv/ && \
+		$(MAKE) -j$(THREADS) clean
+
+check-caravel:
+	@if [ ! -d "$(CARAVEL_ROOT)" ]; then \
+		echo "Caravel Root: "$(CARAVEL_ROOT)" doesn't exists, please export the correct path before running make. "; \
+		exit 1; \
+	fi
+
+check-precheck:
+	@if [ ! -d "$(PRECHECK_ROOT)" ]; then \
+		echo "Pre-check Root: "$(PRECHECK_ROOT)" doesn't exists, please export the correct path before running make. "; \
+		exit 1; \
+	fi
+
+check-pdk:
+	@if [ ! -d "$(PDK_ROOT)" ]; then \
+		echo "PDK Root: "$(PDK_ROOT)" doesn't exists, please export the correct path before running make. "; \
+		exit 1; \
+	fi
+
+check-coremark_repo:
+	@if [ ! -d "$(COREMARK_DIR)" ]; then \
+		echo "Installing Core Mark Repo.."; \
+		git clone $(COREMARK_REPO) $(COREMARK_DIR); \
+		cd $(COREMARK_DIR); git checkout $(COREMARK_BRANCH); \
+	fi
+
+check-riscv_comp_repo:
+	@if [ ! -d "$(RISCV_COMP_DIR)" ]; then \
+		echo "Installing Risc V Complance Repo.."; \
+		git clone $(RISCV_COMP_REPO) $(RISCV_COMP_DIR); \
+		cd $(RISCV_COMP_DIR); git checkout $(RISCV_COMP_BRANCH); \
+	fi
+
+check-riscv_test_repo:
+	@if [ ! -d "$(RISCV_TEST_DIR)" ]; then \
+		echo "Installing RiscV Test Repo.."; \
+		git clone $(RISCV_TEST_REPO) $(RISCV_TEST_DIR); \
+		cd $(RISCV_TEST_DIR); git checkout $(RISCV_TEST_BRANCH); \
+	fi
+
+.PHONY: help
+help:
+	cd $(CARAVEL_ROOT) && $(MAKE) help 
+	@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7271967
--- /dev/null
+++ b/README.md
@@ -0,0 +1,584 @@
+```
+  Riscduino SOC
+
+
+Permission to use, copy, modify, and/or distribute this soc 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 SOC IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOC 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 SOC.
+```
+
+# Table of contents
+- [Overview](#overview)
+- [Riscduino Block Diagram](#Riscduino-block-diagram)
+- [Key Feature](#key-features)
+- [Sub IP Feature](#sub-ip-features)
+- [SOC Memory Map](#soc-memory-map)
+- [Pin Mapping](#soc-pin-mapping)
+- [Repository contents](#repository-contents)
+- [Prerequisites](#prerequisites)
+- [Tests preparation](#tests-preparation)
+    - [Running Simuation](#running-simulation)
+- [Tool sets](#tool-sets)
+- [Documentation](#documentation)
+
+
+# Overview
+
+Riscduino is a 32 bit RISC V based SOC design pin compatible to arudino platform and this soc targetted for efabless Shuttle program.  This project uses only open source tool set for simulation,synthesis and backend tools.  The SOC flow follow the openlane methodology and SOC environment is compatible with efabless/carvel methodology.
+
+# Riscduino Block Diagram
+
+<table>
+  <tr>
+    <td  align="center"><img src="./docs/source/_static/Riscduino_Soc.png" ></td>
+  </tr>
+
+</table>
+
+
+# Key features
+```
+    * Open sourced under Apache-2.0 License (see LICENSE file) - unrestricted commercial use allowed.
+    * industry-grade and silicon-proven Open-Source RISC-V core from syntacore 
+    * 4KB SRAM for data memory
+    * 8KB SRAM for program memory
+    * Quad SPI Master
+    * UART with 16Byte FIFO
+    * USB 1.1 Host
+    * I2C Master
+    * Simple SPI Master
+    * MBIST controller for 8KB Program memory
+    * 6 Channel ADC (in Progress)
+    * 6 PWM
+    * Pin Compatbible to arudino uno
+    * Wishbone compatible design
+    * Written in System Verilog
+    * Open-source tool set
+       * simulation - iverilog
+       * synthesis  - yosys
+       * backend/sta - openlane tool set
+    * Verification suite provided.
+```
+
+# SOC Pin Mapping
+Carvel SOC provides 38 GPIO pins for user functionality. Riscduino SOC GPIO Pin Mapping as follows vs ATMEGA328 and Arudino
+<table>
+  <tr>
+    <td  align="center"><img src="./docs/source/_static/RiscDunio-PinMapping.png" ></td>
+  </tr>
+
+</table>
+
+<table>
+  <tr align="center"> <td> ATMGA328 Pin No</td> <td> Functionality           </td> <td> Arudino Pin Name</td> <td> Carvel Pin Mapping                   </td></tr>
+  <tr align="center"> <td> Pin-1           </td> <td> PC6/RESET              </td> <td>                 </td> <td> digital_io[0]                        </td></tr>
+  <tr align="center"> <td> Pin-2           </td> <td> PD0/RXD                </td> <td>  D0             </td> <td> digital_io[1]                        </td></tr>
+  <tr align="center"> <td> Pin-3           </td> <td> PD1/TXD                </td> <td>  D1             </td> <td> digital_io[2]                        </td></tr>
+  <tr align="center"> <td> Pin-4           </td> <td> PD2/INT0               </td> <td>  D2             </td> <td> digital_io[3]                        </td></tr>
+  <tr align="center"> <td> Pin-5           </td> <td> PD3/INT1/OC2B(PWM0)    </td> <td>  D3             </td> <td> digital_io[4]                        </td></tr>
+  <tr align="center"> <td> Pin-6           </td> <td> PD4                    </td> <td>  D4             </td> <td> digital_io[5]                        </td></tr>
+  <tr align="center"> <td> Pin-7           </td> <td> VCC                    </td> <td>                 </td> <td>  -                                   </td></tr>
+  <tr align="center"> <td> Pin-8           </td> <td> GND                    </td> <td>                 </td> <td>  -                                   </td></tr>
+  <tr align="center"> <td> Pin-9           </td> <td> PB6/XTAL1/TOSC1        </td> <td>                 </td> <td> digital_io[6]                        </td></tr>
+  <tr align="center"> <td> Pin-10          </td> <td> PB7/XTAL2/TOSC2        </td> <td>                 </td> <td> digital_io[7]                        </td></tr>
+  <tr align="center"> <td> Pin-11          </td> <td> PD5/OC0B(PWM1)/T1      </td> <td> D5              </td> <td> digital_io[8]                        </td></tr>
+  <tr align="center"> <td> Pin-12          </td> <td> PD6/OC0A(PWM2)/AIN0    </td> <td> D6              </td> <td> digital_io[9] /analog_io[2]          </td></tr>
+  <tr align="center"> <td> Pin-13          </td> <td> PD7/A1N1               </td> <td> D7              </td> <td> digital_io[10]/analog_io[3]          </td></tr>
+  <tr align="center"> <td> Pin-14          </td> <td> PB0/CLKO/ICP1          </td> <td> D8              </td> <td> digital_io[11]                       </td></tr>
+  <tr align="center"> <td> Pin-15          </td> <td> PB1/OC1A(PWM3)         </td> <td> D9              </td> <td> digital_io[12]                       </td></tr>
+  <tr align="center"> <td> Pin-16          </td> <td> PB2/SS/OC1B(PWM4)      </td> <td> D10             </td> <td> digital_io[13]                       </td></tr>
+  <tr align="center"> <td> Pin-17          </td> <td> PB3/MOSI/OC2A(PWM5)    </td> <td> D11             </td> <td> digital_io[14]                       </td></tr>
+  <tr align="center"> <td> Pin-18          </td> <td> PB4/MISO               </td> <td> D12             </td> <td> digital_io[15]                       </td></tr>
+  <tr align="center"> <td> Pin-19          </td> <td> PB5/SCK                </td> <td> D13             </td> <td> digital_io[16]                       </td></tr>
+  <tr align="center"> <td> Pin-20          </td> <td> AVCC                   </td> <td>                 </td> <td> -                                    </td></tr>
+  <tr align="center"> <td> Pin-21          </td> <td> AREF                   </td> <td>                 </td> <td> analog_io[10]                        </td></tr>
+  <tr align="center"> <td> Pin-22          </td> <td> GND                    </td> <td>                 </td> <td> -                                    </td></tr>
+  <tr align="center"> <td> Pin-23          </td> <td> PC0/ADC0               </td> <td>  A0             </td> <td> digital_io[18]/analog_io[11]         </td></tr>
+  <tr align="center"> <td> Pin-24          </td> <td> PC1/ADC1               </td> <td>  A1             </td> <td> digital_io[19]/analog_io[12]         </td></tr>
+  <tr align="center"> <td> Pin-25          </td> <td> PC2/ADC2               </td> <td>  A2             </td> <td> digital_io[20]/analog_io[13]         </td></tr>
+  <tr align="center"> <td> Pin-26          </td> <td> PC3/ADC3               </td> <td>  A3             </td> <td> digital_io[21]/analog_io[14]         </td></tr>
+  <tr align="center"> <td> Pin-27          </td> <td> PC4/ADC4/SDA           </td> <td>  A4             </td> <td> digital_io[22]/analog_io[15]         </td></tr>
+  <tr align="center"> <td> Pin-28          </td> <td> PC5/ADC5/SCL           </td> <td>  A5             </td> <td> digital_io[23]/analog_io[16]         </td></tr>
+  <tr align="center"> <td colspan="4">   Additional Pad used for Externam ROM/RAM/USB </td></tr>
+  <tr align="center"> <td> Sflash          </td> <td> sflash_sck             </td> <td>                 </td> <td> digital_io[24]                       </td></tr>
+  <tr align="center"> <td> SFlash          </td> <td> sflash_ss              </td> <td>                 </td> <td> digital_io[25]                       </td></tr>
+  <tr align="center"> <td> SFlash          </td> <td> sflash_io0             </td> <td>                 </td> <td> digital_io[26]                       </td></tr>
+  <tr align="center"> <td> SFlash          </td> <td> sflash_io1             </td> <td>                 </td> <td> digital_io[27]                       </td></tr>
+  <tr align="center"> <td> SFlash          </td> <td> sflash_io2             </td> <td>                 </td> <td> digital_io[28]                       </td></tr>
+  <tr align="center"> <td> SFlash          </td> <td> sflash_io3             </td> <td>                 </td> <td> digital_io[29]                       </td></tr>
+  <tr align="center"> <td> SSRAM           </td> <td> Reserved               </td> <td>                 </td> <td> digital_io[30]                       </td></tr>
+  <tr align="center"> <td> SSRAM           </td> <td> Reserved               </td> <td>                 </td> <td> digital_io[31]                       </td></tr>
+  <tr align="center"> <td> SSRAM           </td> <td> Reserved               </td> <td>                 </td> <td> digital_io[32]                       </td></tr>
+  <tr align="center"> <td> SSRAM           </td> <td> Reserved               </td> <td>                 </td> <td> digital_io[33]                       </td></tr>
+  <tr align="center"> <td> SSRAM           </td> <td> uartm rxd              </td> <td>                 </td> <td> digital_io[34]                       </td></tr>
+  <tr align="center"> <td> SSRAM           </td> <td> uartm txd              </td> <td>                 </td> <td> digital_io[35]                       </td></tr>
+  <tr align="center"> <td> usb1.1          </td> <td> usb_dp                 </td> <td>                 </td> <td> digital_io[36]                       </td></tr>
+  <tr align="center"> <td> usb1.1          </td> <td> usb_dn                 </td> <td>                 </td> <td> digital_io[37]                       </td></tr>
+</table>
+# Sub IP features
+
+## RISC V Core
+
+Riscduino SOC Integrated Syntacore SCR1 Open-source RISV-V compatible MCU-class core.
+It is industry-grade and silicon-proven IP. Git link: https://github.com/syntacore/scr1
+
+### Block Diagram
+<table>
+  <tr>
+    <td  align="center"><img src="./docs/source/_static/syntacore_blockdiagram.svg" ></td>
+  </tr>
+</table>
+
+### RISC V Core Key feature
+```
+   * RV32I or RV32E ISA base + optional RVM and RVC standard extensions
+   * Machine privilege mode only
+   * 2 to 4 stage pipeline
+   * Optional Integrated Programmable Interrupt Controller with 16 IRQ lines
+   * Optional RISC-V Debug subsystem with JTAG interface
+   * Optional on-chip Tightly-Coupled Memory
+```
+
+### RISC V core customization Riscduino SOC
+  
+
+* **Update**: Modified some of the system verilog syntax to basic verilog syntax to compile/synthesis in open source tool like simulator (iverilog) and synthesis (yosys).
+* **Modification**: Modified the AXI/AHB interface to wishbone interface towards instruction & data memory interface
+
+
+# SOC Memory Map
+
+<table>
+  <tr>
+    <td  align="center"> RISC IMEM</td> 
+    <td  align="center"> RISC DMEM</td>
+    <td  align="center"> EXT MAP</td>
+    <td  align="center"> Target IP</td>
+  </tr>
+  <tr>
+    <td  align="center"> 0x0000_0000 to 0x0FFF_FFFF  </td> 
+    <td  align="center"> 0x0000_0000 to 0x0FFF_FFFF  </td>
+    <td  align="center"> 0x0000_0000 to 0x0FFF_FFFF</td>
+    <td  align="center"> QSPI FLASH MEMORY</td>
+  </tr>
+  <tr>
+    <td  align="center"> 0x1000_0000 to 0x1000_00FF</td> 
+    <td  align="center"> 0x1000_0000 to 0x1000_00FF</td>
+    <td  align="center"> 0x1000_0000 to 0x1000_00FF</td>
+    <td  align="center"> QSPI Config Reg</td>
+  </tr>
+  <tr>
+    <td  align="center"> 0x1001_0000 to 0x1001_003F</td> 
+    <td  align="center"> 0x1001_0000 to 0x1001_003F</td>
+    <td  align="center"> 0x1001_0000 to 0x1001_003F</td>
+    <td  align="center"> UART</td>
+  </tr>
+  <tr>
+    <td  align="center"> 0x1001_0040 to 0x1001_007F</td> 
+    <td  align="center"> 0x1001_0040 to 0x1001_007F</td>
+    <td  align="center"> 0x1001_0040 to 0x1001_007F</td>
+    <td  align="center"> I2C</td>
+  </tr>
+  <tr>
+    <td  align="center"> 0x1001_0080 to 0x1001_00BF</td> 
+    <td  align="center"> 0x1001_0080 to 0x1001_00BF</td>
+    <td  align="center"> 0x1001_0080 to 0x1001_00BF</td>
+    <td  align="center"> USB</td>
+  </tr>
+  <tr>
+    <td  align="center"> 0x1001_00C0 to 0x1001_00FF</td> 
+    <td  align="center"> 0x1001_00C0 to 0x1001_00FF</td>
+    <td  align="center"> 0x1001_00C0 to 0x1001_00FF</td>
+    <td  align="center"> SSPI</td>
+  </tr>
+  <tr>
+    <td  align="center"> 0x1002_0080 to 0x1002_00FF</td> 
+    <td  align="center"> 0x1002_0080 to 0x1002_00FF</td>
+    <td  align="center"> 0x1002_0080 to 0x1002_00FF</td>
+    <td  align="center"> PINMUX</td>
+  </tr>
+  <tr>
+    <td  align="center"> 0x1003_0080 to 0x1003_07FF</td> 
+    <td  align="center"> 0x1003_0080 to 0x1003_07FF</td>
+    <td  align="center"> 0x1003_0080 to 0x1003_07FF</td>
+    <td  align="center"> SRAM-0 (2KB)</td>
+  </tr>
+  <tr>
+    <td  align="center"> 0x1003_0800 to 0x1003_0FFF</td> 
+    <td  align="center"> 0x1003_0800 to 0x1003_0FFF</td>
+    <td  align="center"> 0x1003_0800 to 0x1003_0FFF</td>
+    <td  align="center"> SRAM-1 (2KB)</td>
+  </tr>
+  <tr>
+    <td  align="center"> 0x1003_1000 to 0x1003_17FF</td> 
+    <td  align="center"> 0x1003_1000 to 0x1003_17FF</td>
+    <td  align="center"> 0x1003_1000 to 0x1003_17FF</td>
+    <td  align="center"> SRAM-2 (2KB)</td>
+  </tr>
+  <tr>
+    <td  align="center"> 0x1003_1800 to 0x1003_1FFF</td> 
+    <td  align="center"> 0x1003_1800 to 0x1003_1FFF</td>
+    <td  align="center"> 0x1003_1800 to 0x1003_1FFF</td>
+    <td  align="center"> SRAM-3 (2KB)</td>
+  </tr>
+  <tr>
+    <td  align="center"> -</td> 
+    <td  align="center"> -</td>
+    <td  align="center"> 0x3080_0000 to 0x3080_00FF</td>
+    <td  align="center"> WB HOST</td>
+  </tr>
+</table>
+
+# SOC Size
+
+| Block             | Total Cell | Seq      | Combo   |
+| ------            | ---------  | -------- | -----   |
+| RISC              | 20982      | 3164     | 17818   |
+| PINMUX            | 5693       | 1022     |  4671   |
+| SPI               | 7120       | 1281     |  5839   |
+| UART_I2C_USB_SPI  | 11196      | 2448     |  8748   |
+| WB_HOST           | 2796       | 588      |  2208   |
+| WB_INTC           | 1878       | 108      |  1770   |
+| SAR_ADC           | 118        |  18      |   100   |
+| MBIST             | 3125       | 543      |  2582   |
+|                   |            |          |         |
+| TOTAL             | 52908      | 9172     | 43736   |
+
+
+
+# SOC Register Map
+##### Register Map: Wishbone HOST
+
+| Offset | Name       | Description   |
+| ------ | ---------  | ------------- |
+| 0x00   | GLBL_CTRL  | [RW] Global Wishbone Access Control Register |
+| 0x04   | BANK_CTRL  | [RW] Bank Selection, MSB 8 bit Address |
+| 0x08   | CLK_SKEW_CTRL1| [RW] Clock Skew Control2 |
+| 0x0c   | CLK_SKEW_CTRL2 | [RW] Clock Skew Control2 |
+
+##### Register: GLBL_CTRL
+
+| Bits  | Name          | Description    |
+| ----  | ----          | -------------- |
+| 31:24 | Resevered     | Unsused |
+| 23:20 | RTC_CLK_CTRL  | RTC Clock Div Selection |
+| 19:16 | CPU_CLK_CTRL  | CPU Clock Div Selection |
+| 15:12 | SDARM_CLK_CTRL| SDRAM Clock Div Selection |
+| 10:8  | WB_CLK_CTRL   | Core Wishbone Clock Div Selection |
+|   7   | UART_I2C_SEL  | 0 - UART , 1 - I2C Master IO Selection |
+|   5   | I2C_RST       | I2C Reset Control |
+|   4   | UART_RST      | UART Reset Control |
+|   3   | SDRAM_RST     | SDRAM Reset Control |
+|   2   | SPI_RST       | SPI Reset Control |
+|   1   | CPU_RST       | CPU Reset Control |
+|   0   | WB_RST        | Wishbone Core Reset Control |
+
+##### Register: BANK_CTRL
+
+| Bits  | Name          | Description    |
+| ----  | ----          | -------------- |
+| 31:24 | Resevered     | Unsused |
+| 7:0   | BANK_SEL      | Holds the upper 8 bit address core Wishbone Address |
+
+##### Register: CLK_SKEW_CTRL1
+
+| Bits  | Name          | Description    |
+| ----  | ----          | -------------- |
+| 31:28 | Resevered     | Unsused |
+| 27:24 | CLK_SKEW_WB   | WishBone Core Clk Skew Control |
+| 23:20 | CLK_SKEW_GLBL | Glbal Register Clk Skew Control |
+| 19:16 | CLK_SKEW_SDRAM| SDRAM Clk Skew Control |
+| 15:12 | CLK_SKEW_SPI  | SPI Clk Skew Control |
+| 11:8  | CLK_SKEW_UART | UART/I2C Clk Skew Control |
+| 7:4   | CLK_SKEW_RISC | RISC Clk Skew Control |
+| 3:0   | CLK_SKEW_WI   | Wishbone Clk Skew Control |
+
+##### Register Map: SPI MASTER
+
+| Offset | Name       | Description   |
+| ------ | ---------  | ------------- |
+| 0x00   | GLBL_CTRL  | [RW] Global SPI Access Control Register |
+| 0x04   | DMEM_CTRL1 | [RW] Direct SPI Memory Access Control Register1 |
+| 0x08   | DMEM_CTRL2 | [RW] Direct SPI Memory Access Control Register2 |
+| 0x0c   | IMEM_CTRL1 | [RW] Indirect SPI Memory Access Control Register1 |
+| 0x10   | IMEM_CTRL2 | [RW] Indirect SPI Memory Access Control Register2 |
+| 0x14   | IMEM_ADDR  | [RW] Indirect SPI Memory Address  |
+| 0x18   | IMEM_WDATA | [W]  Indirect SPI Memory Write Data |
+| 0x1c   | IMEM_RDATA | [R]  Indirect SPI Memory Read Data |
+| 0x20   | SPI_STATUS | [R] SPI Debug Status |
+
+##### Register: GLBL_CTRL
+
+| Bits  | Name        | Description    |
+| ----  | ----        | -------------- |
+| 31:16 | Resevered   | Unsused |
+| 15:8  | SPI_CLK_DIV | SPI Clock Div Rato Selection |
+| 7:4   | Reserved    | Unused |
+| 3:2   | CS_LATE     | CS DE_ASSERTION CONTROL |
+| 1:0   | CS_EARLY    | CS ASSERTION CONTROL |
+
+##### Register: DMEM_CTRL1
+
+| Bits | Name       | Description    |
+| ---- | ----       | -------------- |
+| 31:9 | Resevered  | Unsused        |
+| 8    | FSM_RST    | Direct Mem State Machine Reset |
+| 7:6  | SPI_SWITCH | Phase at which SPI Mode need to switch |
+| 5:4  | SPI_MODE   | SPI Mode, 0 - Single, 1 - Dual, 2 - Quad, 3 - QDDR |
+| 3:0  | CS_SELECT  | CHIP SELECT |
+
+##### Register: DMEM_CTRL2
+
+| Bits | Name       | Description    |
+| ---- | ----       | -------------- |
+| 31:24 | DATA_CNT  | Total Data Byte Count        |
+| 23:22 | DUMMY_CNT | Total Dummy Byte Count |
+| 21:20 | ADDR_CNT  | Total Address Byte Count |
+| 19:16 | SPI_SEQ   | SPI Access Sequence |
+| 15:8  | MODE_REG  | Mode Register Value |
+| 7:0   | CMD_REG   | Command Register Value |
+
+##### Register: IMEM_CTRL1
+
+| Bits | Name       | Description    |
+| ---- | ----       | -------------- |
+| 31:9 | Resevered  | Unsused        |
+| 8    | FSM_RST    | InDirect Mem State Machine Reset |
+| 7:6  | SPI_SWITCH | Phase at which SPI Mode need to switch |
+| 5:4  | SPI_MODE   | SPI Mode, 0 - Single, 1 - Dual, 2 - Quad, 3 - QDDR |
+| 3:0  | CS_SELECT  | CHIP SELECT |
+
+##### Register: IMEM_CTRL2
+
+| Bits | Name       | Description    |
+| ---- | ----       | -------------- |
+| 31:24 | DATA_CNT  | Total Data Byte Count        |
+| 23:22 | DUMMY_CNT | Total Dummy Byte Count |
+| 21:20 | ADDR_CNT  | Total Address Byte Count |
+| 19:16 | SPI_SEQ   | SPI Access Sequence |
+| 15:8  | MODE_REG  | Mode Register Value |
+| 7:0   | CMD_REG   | Command Register Value |
+
+##### Register: IMEM_ADDR
+
+| Bits | Name       | Description    |
+| ---- | ----       | -------------- |
+| 31:0 | ADDR       | Indirect Memory Address  |
+
+##### Register: IMEM_WDATA
+
+| Bits | Name       | Description    |
+| ---- | ----       | -------------- |
+| 31:0 | WDATA      | Indirect Memory Write Data  |
+
+##### Register: IMEM_RDATA
+
+| Bits | Name       | Description    |
+| ---- | ----       | -------------- |
+| 31:0 | RDATA      | Indirect Memory Read Data  |
+
+##### Register: SPI_STATUS
+
+| Bits | Name       | Description    |
+| ---- | ----       | -------------- |
+| 31:0 | DEBUG      | SPI Debug Status  |
+
+
+##### Register Map: Global Register
+
+| Offset | Name        | Description   |
+| ------ | ---------   | ------------- |
+| 0x00   | SOFT_REG0   | [RW] Software Register0 |
+| 0x04   | RISC_FUSE   | [RW] Risc Fuse Value  |
+| 0x08   | SOFT_REG2   | [RW] Software Register2 |
+| 0x0c   | INTR_CTRL   | [RW] Interrupt Control |
+| 0x10   | SDRAM_CTRL1 | [RW] Indirect SPI Memory Access Control Register2 |
+| 0x14   | SDRAM_CTRL2 | [RW] Indirect SPI Memory Address  |
+| 0x18   | SOFT_REG6   | [RW] Software Register6 |
+| 0x1C   | SOFT_REG7   | [RW] Software Register7 |
+| 0x20   | SOFT_REG8   | [RW] Software Register8 |
+| 0x24   | SOFT_REG9   | [RW] Software Register9 |
+| 0x28   | SOFT_REG10  | [RW] Software Register10 |
+| 0x2C   | SOFT_REG11  | [RW] Software Register11 |
+| 0x30   | SOFT_REG12  | [RW] Software Register12 |
+| 0x34   | SOFT_REG13  | [RW] Software Register13 |
+| 0x38   | SOFT_REG14  | [RW] Software Register14 |
+| 0x3C   | SOFT_REG15  | [RW] Software Register15 |
+
+##### Register: RISC_FUSE
+
+| Bits  | Name        | Description    |
+| ----  | ----        | -------------- |
+| 31:0  | RISC_FUSE   | RISC Core Fuse Value |
+
+##### Register: INTR_CTRL
+
+| Bits  | Name        | Description    |
+| ----  | ----        | -------------- |
+| 31:20 | Reserved    | Unused         |
+| 19:17 | USER_IRQ    | User Interrupt generation toward riscv         |
+| 16    | SOFT_IRQ    | Software Interrupt generation toward riscv     |
+| 15:0  | EXT_IRQ     | External Interrupt generation toward riscv     |
+
+
+
+# Repository contents
+
+```
+|verilog
+|   ├─  rtl
+|   |     |-  syntacore
+|   |     |     |─  scr1
+|   |     |     |    ├─ **docs**                           | **SCR1 documentation**
+|   |     |     |    |      ├─ scr1_eas.pdf                | SCR1 External Architecture Specification
+|   |     |     |    |      └─ scr1_um.pdf                 | SCR1 User Manual
+|   |     |     |    |─  **src**                           | **SCR1 RTL source and testbench files**
+|   |     |     |    |   ├─ includes                       | Header files
+|   |     |     |    |   ├─ core                           | Core top source files
+|   |     |     |    |   ├─ top                            | Cluster source files
+|   |     |     |    |─  **synth**                         | **SCR1 RTL Synthesis files **
+|   |     |- Qspi_master
+|   |     |     |- src                                     | Qard SPI Master Source files
+|   |     |-wb_interconnect
+|   |     |     |- src                                     | 3x4 Wishbone Interconnect
+|   |     |- digital_core
+|   |     |     |- src                                     | Digital core Source files
+|   |     |- lib                                           | common library source files
+|   |- dv
+|   |   |- la_test1                                        | carevel LA test
+|   |   |- risc_boot                                       | user core risc boot test
+|   |   |- wb_port                                         | user wishbone test
+|   |   |- user_risc_boot                                  | user standalone test without carevel soc
+|   |- gl                                                  | ** GLS Source files **
+|
+|- openlane
+    |- spi_master                                          | spi_master openlane scripts   
+    |- syntacore                                           | Risc Core openlane scripts   
+    |- user_project_wrapper                                | carvel user project wrapper 
+
+```
+
+
+# Prerequisites
+   - Docker (ensure docker daemon is running) -- tested with version 19.03.12, but any recent version should suffice.
+## Step-1: Docker in ubuntu 20.04 version
+```bash
+   sudo apt update
+   sudo apt-get install apt-transport-https curl rtificates -agent software-properties-common
+   curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
+   sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
+   sudo apt update
+   apt-cache policy docker-ce
+   sudo apt install docker-ce
+
+   #Add User Name to docker
+   sudo usermod -aG docker <your user name>
+   # Reboot the system to enable the docker setup
+```
+##  Step-2: Update the Submodule, To to project area
+```bash
+   git submodule init
+   git submodule update
+```
+## Step-3: clone Openlane scripts under workarea
+```bash
+   git clone https://github.com/The-OpenROAD-Project/OpenLane.git
+```
+
+## Step-4: add Environment setting
+```bash
+    export CARAVEL_ROOT=<Carvel Installed Path>
+    export OPENLANE_ROOT=<OpenLane Installed Path>
+    export OPENLANE_IMAGE_NAME=efabless/openlane:latest
+    export PDK_ROOT=<PDK Installed PATH>
+    export PDK_PATH=<PDK Install Path>/sky130A
+```
+## Step-5: To install the PDK
+```bash
+   source ~/.bashrc
+   cd OpenLane
+   make pdk
+```
+
+# Tests preparation
+
+The simulation package includes the following tests:
+
+* **risc_boot**           - Simple User Risc core boot 
+* **wb_port**             - User Wishbone validation
+* **user_risc_boot**      - Standalone User Risc core boot
+* **user_mbist_test1**    - Standalone MBIST test
+* **user_spi**            - Standalone SPI test
+* **user_i2c**            - Standalone I2C test
+* **user_risc_soft_boot** - Standalone Risc with SRAM as Boot
+
+
+# Running Simulation
+
+Examples:
+``` sh
+    make verify-wb_port  
+    make verify-risc_boot
+    make verify-user_uart
+    make verify-user_spi
+    make verify-user_i2cm
+    make verify-user_risc_boot
+    make verify-wb_port SIM=RTL DUMP=OFF
+    make verify-wb_port SIM=RTL DUMP=ON
+    make verify-riscv_regress
+```
+
+# Tool Sets
+
+Riscduino Soc flow uses Openlane tool sets.
+
+1. **Synthesis**
+    1. `yosys` - Performs RTL synthesis
+    2. `abc` - Performs technology mapping
+    3. `OpenSTA` - Pefroms static timing analysis on the resulting netlist to generate timing reports
+2. **Floorplan and PDN**
+    1. `init_fp` - Defines the core area for the macro as well as the rows (used for placement) and the tracks (used for routing)
+    2. `ioplacer` - Places the macro input and output ports
+    3. `pdn` - Generates the power distribution network
+    4. `tapcell` - Inserts welltap and decap cells in the floorplan
+3. **Placement**
+    1. `RePLace` - Performs global placement
+    2. `Resizer` - Performs optional optimizations on the design
+    3. `OpenPhySyn` - Performs timing optimizations on the design
+    4. `OpenDP` - Perfroms detailed placement to legalize the globally placed components
+4. **CTS**
+    1. `TritonCTS` - Synthesizes the clock distribution network (the clock tree)
+5. **Routing**
+    1. `FastRoute` - Performs global routing to generate a guide file for the detailed router
+    2. `CU-GR` - Another option for performing global routing.
+    3. `TritonRoute` - Performs detailed routing
+    4. `SPEF-Extractor` - Performs SPEF extraction
+6. **GDSII Generation**
+    1. `Magic` - Streams out the final GDSII layout file from the routed def
+    2. `Klayout` - Streams out the final GDSII layout file from the routed def as a back-up
+7. **Checks**
+    1. `Magic` - Performs DRC Checks & Antenna Checks
+    2. `Klayout` - Performs DRC Checks
+    3. `Netgen` - Performs LVS Checks
+    4. `CVC` - Performs Circuit Validity Checks
+
+
+
+## Contacts
+
+Report an issue: <https://github.com/dineshannayya/riscduino/issues>
+
+# Documentation
+* **Syntacore Link** - https://github.com/syntacore/scr1
+
+
+
+
diff --git a/checks/erase_box_user_project_wrapper.gds.log b/checks/erase_box_user_project_wrapper.gds.log
new file mode 100644
index 0000000..2464ece
--- /dev/null
+++ b/checks/erase_box_user_project_wrapper.gds.log
@@ -0,0 +1,2867 @@
+/home/dinesha/workarea/opencore/git/yifive_r0/gds//user_project_wrapper.gds /home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper_erased.gds user_project_wrapper
+
+Magic 8.3 revision 182 - Compiled on Fri Jun 25 23:58:13 UTC 2021.
+Starting magic under Tcl interpreter
+Using the terminal as the console.
+Using NULL graphics device.
+Processing system .magicrc file
+Sourcing design .magicrc for technology sky130A ...
+2 Magic internal units = 1 Lambda
+Input style sky130(): scaleFactor=2, multiplier=2
+Scaled tech values by 2 / 1 to match internal grid scaling
+Loading sky130A Device Generator Menu ...
+Using technology "sky130A", version 1.0.116-4-g522a373
+Input style sky130(vendor): scaleFactor=2, multiplier=2
+CIF input style is now "sky130(vendor)"
+Warning: Calma reading is not undoable!  I hope that's OK.
+Library written using GDS-II Release 3.0
+Library name: user_project_wrapper
+Reading "sky130_fd_sc_hd__clkbuf_16".
+Reading "sky130_fd_sc_hd__buf_4".
+Reading "sky130_fd_sc_hd__a21o_4".
+Reading "sky130_fd_sc_hd__clkbuf_1".
+Reading "sky130_fd_sc_hd__dfstp_4".
+Reading "sky130_fd_sc_hd__or3_4".
+Reading "sky130_fd_sc_hd__a21boi_4".
+Reading "sky130_fd_sc_hd__or4_4".
+Reading "sky130_fd_sc_hd__a22oi_4".
+Reading "sky130_fd_sc_hd__and3_4".
+Reading "sky130_fd_sc_hd__o21ai_4".
+Reading "sky130_fd_sc_hd__o32a_4".
+Reading "sky130_fd_sc_hd__and2_4".
+Reading "sky130_fd_sc_hd__and4_4".
+Reading "sky130_fd_sc_hd__dfxtp_4".
+Reading "sky130_fd_sc_hd__or2_4".
+Reading "sky130_fd_sc_hd__diode_2".
+Reading "sky130_fd_sc_hd__o22a_4".
+Reading "sky130_fd_sc_hd__nor2_4".
+Reading "sky130_fd_sc_hd__o21a_4".
+Reading "sky130_fd_sc_hd__a32o_4".
+Reading "sky130_fd_sc_hd__buf_2".
+Reading "sky130_fd_sc_hd__a21oi_4".
+Reading "sky130_fd_sc_hd__nand2_4".
+Reading "sky130_fd_sc_hd__inv_2".
+Reading "sky130_fd_sc_hd__dfrtp_4".
+Reading "sky130_fd_sc_hd__decap_4".
+Reading "sky130_fd_sc_hd__a211o_4".
+Reading "sky130_fd_sc_hd__fill_2".
+Reading "sky130_fd_sc_hd__decap_8".
+Reading "sky130_fd_sc_hd__a2bb2o_4".
+Reading "sky130_fd_sc_hd__tapvpwrvgnd_1".
+Reading "sky130_fd_sc_hd__decap_12".
+Reading "sky130_fd_sc_hd__conb_1".
+Reading "sky130_fd_sc_hd__decap_6".
+Reading "sky130_fd_sc_hd__fill_1".
+Reading "sky130_fd_sc_hd__decap_3".
+Reading "sky130_fd_sc_hd__a2111o_4".
+Reading "sky130_fd_sc_hd__a21bo_4".
+Reading "sky130_fd_sc_hd__o41a_4".
+Reading "sky130_fd_sc_hd__buf_8".
+Reading "scr1_core_top".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+    13800 uses
+    13900 uses
+    14000 uses
+    14100 uses
+    14200 uses
+    14300 uses
+    14400 uses
+    14500 uses
+    14600 uses
+    14700 uses
+    14800 uses
+    14900 uses
+    15000 uses
+    15100 uses
+    15200 uses
+    15300 uses
+    15400 uses
+    15500 uses
+    15600 uses
+    15700 uses
+    15800 uses
+    15900 uses
+    16000 uses
+    16100 uses
+    16200 uses
+    16300 uses
+    16400 uses
+    16500 uses
+    16600 uses
+    16700 uses
+    16800 uses
+    16900 uses
+    17000 uses
+    17100 uses
+    17200 uses
+    17300 uses
+    17400 uses
+    17500 uses
+    17600 uses
+    17700 uses
+    17800 uses
+    17900 uses
+    18000 uses
+    18100 uses
+    18200 uses
+    18300 uses
+    18400 uses
+    18500 uses
+    18600 uses
+    18700 uses
+    18800 uses
+    18900 uses
+    19000 uses
+    19100 uses
+    19200 uses
+    19300 uses
+    19400 uses
+    19500 uses
+    19600 uses
+    19700 uses
+    19800 uses
+    19900 uses
+    20000 uses
+    20100 uses
+    20200 uses
+    20300 uses
+    20400 uses
+    20500 uses
+    20600 uses
+    20700 uses
+    20800 uses
+    20900 uses
+    21000 uses
+    21100 uses
+    21200 uses
+    21300 uses
+    21400 uses
+    21500 uses
+    21600 uses
+    21700 uses
+    21800 uses
+    21900 uses
+    22000 uses
+    22100 uses
+    22200 uses
+    22300 uses
+    22400 uses
+    22500 uses
+    22600 uses
+    22700 uses
+    22800 uses
+    22900 uses
+    23000 uses
+    23100 uses
+    23200 uses
+    23300 uses
+    23400 uses
+    23500 uses
+    23600 uses
+    23700 uses
+    23800 uses
+    23900 uses
+    24000 uses
+    24100 uses
+    24200 uses
+    24300 uses
+    24400 uses
+    24500 uses
+    24600 uses
+    24700 uses
+    24800 uses
+    24900 uses
+    25000 uses
+    25100 uses
+    25200 uses
+    25300 uses
+    25400 uses
+    25500 uses
+    25600 uses
+    25700 uses
+    25800 uses
+    25900 uses
+    26000 uses
+    26100 uses
+    26200 uses
+    26300 uses
+    26400 uses
+    26500 uses
+    26600 uses
+    26700 uses
+    26800 uses
+    26900 uses
+    27000 uses
+    27100 uses
+    27200 uses
+    27300 uses
+    27400 uses
+    27500 uses
+    27600 uses
+    27700 uses
+    27800 uses
+    27900 uses
+    28000 uses
+    28100 uses
+    28200 uses
+    28300 uses
+    28400 uses
+    28500 uses
+    28600 uses
+    28700 uses
+    28800 uses
+    28900 uses
+    29000 uses
+    29100 uses
+    29200 uses
+    29300 uses
+    29400 uses
+    29500 uses
+    29600 uses
+    29700 uses
+    29800 uses
+    29900 uses
+    30000 uses
+    30100 uses
+    30200 uses
+    30300 uses
+    30400 uses
+    30500 uses
+    30600 uses
+    30700 uses
+    30800 uses
+    30900 uses
+    31000 uses
+    31100 uses
+    31200 uses
+    31300 uses
+    31400 uses
+    31500 uses
+    31600 uses
+    31700 uses
+    31800 uses
+    31900 uses
+    32000 uses
+    32100 uses
+    32200 uses
+    32300 uses
+    32400 uses
+    32500 uses
+    32600 uses
+    32700 uses
+    32800 uses
+    32900 uses
+    33000 uses
+    33100 uses
+    33200 uses
+    33300 uses
+    33400 uses
+    33500 uses
+    33600 uses
+    33700 uses
+    33800 uses
+    33900 uses
+    34000 uses
+    34100 uses
+    34200 uses
+    34300 uses
+    34400 uses
+    34500 uses
+    34600 uses
+    34700 uses
+    34800 uses
+    34900 uses
+    35000 uses
+    35100 uses
+    35200 uses
+    35300 uses
+    35400 uses
+    35500 uses
+    35600 uses
+    35700 uses
+    35800 uses
+    35900 uses
+    36000 uses
+    36100 uses
+    36200 uses
+    36300 uses
+    36400 uses
+    36500 uses
+    36600 uses
+    36700 uses
+    36800 uses
+    36900 uses
+    37000 uses
+    37100 uses
+    37200 uses
+    37300 uses
+    37400 uses
+    37500 uses
+    37600 uses
+    37700 uses
+    37800 uses
+    37900 uses
+    38000 uses
+    38100 uses
+    38200 uses
+    38300 uses
+    38400 uses
+    38500 uses
+    38600 uses
+    38700 uses
+    38800 uses
+    38900 uses
+    39000 uses
+    39100 uses
+    39200 uses
+    39300 uses
+    39400 uses
+    39500 uses
+    39600 uses
+    39700 uses
+    39800 uses
+    39900 uses
+    40000 uses
+    40100 uses
+    40200 uses
+    40300 uses
+    40400 uses
+    40500 uses
+    40600 uses
+    40700 uses
+    40800 uses
+    40900 uses
+    41000 uses
+    41100 uses
+    41200 uses
+    41300 uses
+    41400 uses
+    41500 uses
+    41600 uses
+    41700 uses
+    41800 uses
+    41900 uses
+    42000 uses
+    42100 uses
+    42200 uses
+    42300 uses
+    42400 uses
+    42500 uses
+    42600 uses
+    42700 uses
+    42800 uses
+    42900 uses
+    43000 uses
+    43100 uses
+    43200 uses
+    43300 uses
+    43400 uses
+    43500 uses
+    43600 uses
+    43700 uses
+    43800 uses
+    43900 uses
+    44000 uses
+    44100 uses
+    44200 uses
+    44300 uses
+    44400 uses
+    44500 uses
+    44600 uses
+    44700 uses
+    44800 uses
+    44900 uses
+    45000 uses
+    45100 uses
+    45200 uses
+    45300 uses
+    45400 uses
+    45500 uses
+    45600 uses
+    45700 uses
+    45800 uses
+    45900 uses
+    46000 uses
+    46100 uses
+    46200 uses
+    46300 uses
+    46400 uses
+    46500 uses
+    46600 uses
+    46700 uses
+    46800 uses
+    46900 uses
+    47000 uses
+    47100 uses
+    47200 uses
+    47300 uses
+    47400 uses
+    47500 uses
+    47600 uses
+    47700 uses
+    47800 uses
+    47900 uses
+    48000 uses
+    48100 uses
+    48200 uses
+    48300 uses
+    48400 uses
+    48500 uses
+    48600 uses
+    48700 uses
+    48800 uses
+    48900 uses
+    49000 uses
+    49100 uses
+    49200 uses
+    49300 uses
+    49400 uses
+    49500 uses
+    49600 uses
+    49700 uses
+    49800 uses
+    49900 uses
+    50000 uses
+    50100 uses
+    50200 uses
+    50300 uses
+    50400 uses
+    50500 uses
+    50600 uses
+    50700 uses
+    50800 uses
+    50900 uses
+    51000 uses
+    51100 uses
+    51200 uses
+    51300 uses
+    51400 uses
+    51500 uses
+    51600 uses
+    51700 uses
+    51800 uses
+    51900 uses
+    52000 uses
+    52100 uses
+    52200 uses
+    52300 uses
+    52400 uses
+    52500 uses
+    52600 uses
+    52700 uses
+    52800 uses
+    52900 uses
+    53000 uses
+    53100 uses
+    53200 uses
+    53300 uses
+    53400 uses
+    53500 uses
+    53600 uses
+    53700 uses
+    53800 uses
+    53900 uses
+    54000 uses
+    54100 uses
+    54200 uses
+    54300 uses
+    54400 uses
+    54500 uses
+    54600 uses
+    54700 uses
+    54800 uses
+    54900 uses
+    55000 uses
+    55100 uses
+    55200 uses
+    55300 uses
+    55400 uses
+    55500 uses
+    55600 uses
+    55700 uses
+    55800 uses
+    55900 uses
+    56000 uses
+    56100 uses
+    56200 uses
+    56300 uses
+    56400 uses
+    56500 uses
+    56600 uses
+    56700 uses
+    56800 uses
+    56900 uses
+    57000 uses
+    57100 uses
+    57200 uses
+    57300 uses
+    57400 uses
+    57500 uses
+    57600 uses
+    57700 uses
+    57800 uses
+    57900 uses
+    58000 uses
+    58100 uses
+    58200 uses
+    58300 uses
+    58400 uses
+    58500 uses
+    58600 uses
+    58700 uses
+    58800 uses
+    58900 uses
+    59000 uses
+    59100 uses
+    59200 uses
+    59300 uses
+    59400 uses
+    59500 uses
+    59600 uses
+    59700 uses
+    59800 uses
+    59900 uses
+    60000 uses
+    60100 uses
+    60200 uses
+    60300 uses
+    60400 uses
+    60500 uses
+    60600 uses
+    60700 uses
+    60800 uses
+    60900 uses
+    61000 uses
+    61100 uses
+    61200 uses
+    61300 uses
+    61400 uses
+    61500 uses
+    61600 uses
+    61700 uses
+    61800 uses
+    61900 uses
+    62000 uses
+    62100 uses
+    62200 uses
+    62300 uses
+    62400 uses
+    62500 uses
+    62600 uses
+    62700 uses
+    62800 uses
+    62900 uses
+    63000 uses
+    63100 uses
+    63200 uses
+    63300 uses
+    63400 uses
+    63500 uses
+    63600 uses
+    63700 uses
+    63800 uses
+    63900 uses
+    64000 uses
+    64100 uses
+    64200 uses
+    64300 uses
+    64400 uses
+    64500 uses
+    64600 uses
+    64700 uses
+    64800 uses
+    64900 uses
+    65000 uses
+    65100 uses
+    65200 uses
+    65300 uses
+    65400 uses
+    65500 uses
+    65600 uses
+    65700 uses
+    65800 uses
+    65900 uses
+    66000 uses
+    66100 uses
+    66200 uses
+    66300 uses
+    66400 uses
+    66500 uses
+    66600 uses
+    66700 uses
+    66800 uses
+    66900 uses
+    67000 uses
+    67100 uses
+    67200 uses
+    67300 uses
+    67400 uses
+    67500 uses
+    67600 uses
+    67700 uses
+    67800 uses
+    67900 uses
+    68000 uses
+    68100 uses
+    68200 uses
+    68300 uses
+    68400 uses
+    68500 uses
+    68600 uses
+    68700 uses
+    68800 uses
+    68900 uses
+    69000 uses
+    69100 uses
+    69200 uses
+    69300 uses
+    69400 uses
+    69500 uses
+    69600 uses
+    69700 uses
+    69800 uses
+    69900 uses
+    70000 uses
+    70100 uses
+    70200 uses
+    70300 uses
+    70400 uses
+    70500 uses
+    70600 uses
+    70700 uses
+    70800 uses
+    70900 uses
+    71000 uses
+    71100 uses
+    71200 uses
+    71300 uses
+    71400 uses
+    71500 uses
+    71600 uses
+    71700 uses
+    71800 uses
+    71900 uses
+    72000 uses
+    72100 uses
+    72200 uses
+    72300 uses
+    72400 uses
+    72500 uses
+    72600 uses
+    72700 uses
+    72800 uses
+    72900 uses
+    73000 uses
+    73100 uses
+    73200 uses
+    73300 uses
+    73400 uses
+    73500 uses
+    73600 uses
+    73700 uses
+    73800 uses
+    73900 uses
+    74000 uses
+    74100 uses
+    74200 uses
+    74300 uses
+    74400 uses
+    74500 uses
+    74600 uses
+    74700 uses
+    74800 uses
+    74900 uses
+    75000 uses
+    75100 uses
+    75200 uses
+    75300 uses
+    75400 uses
+    75500 uses
+    75600 uses
+    75700 uses
+    75800 uses
+    75900 uses
+    76000 uses
+    76100 uses
+    76200 uses
+    76300 uses
+    76400 uses
+    76500 uses
+    76600 uses
+    76700 uses
+    76800 uses
+    76900 uses
+    77000 uses
+    77100 uses
+    77200 uses
+    77300 uses
+    77400 uses
+    77500 uses
+    77600 uses
+    77700 uses
+    77800 uses
+    77900 uses
+    78000 uses
+    78100 uses
+    78200 uses
+    78300 uses
+    78400 uses
+    78500 uses
+    78600 uses
+    78700 uses
+    78800 uses
+    78900 uses
+    79000 uses
+    79100 uses
+    79200 uses
+    79300 uses
+    79400 uses
+    79500 uses
+    79600 uses
+    79700 uses
+    79800 uses
+    79900 uses
+    80000 uses
+    80100 uses
+    80200 uses
+    80300 uses
+    80400 uses
+    80500 uses
+    80600 uses
+    80700 uses
+    80800 uses
+    80900 uses
+    81000 uses
+    81100 uses
+    81200 uses
+    81300 uses
+    81400 uses
+    81500 uses
+    81600 uses
+    81700 uses
+    81800 uses
+    81900 uses
+    82000 uses
+    82100 uses
+    82200 uses
+    82300 uses
+    82400 uses
+    82500 uses
+    82600 uses
+    82700 uses
+    82800 uses
+    82900 uses
+    83000 uses
+    83100 uses
+    83200 uses
+    83300 uses
+    83400 uses
+    83500 uses
+    83600 uses
+    83700 uses
+    83800 uses
+    83900 uses
+    84000 uses
+    84100 uses
+    84200 uses
+    84300 uses
+    84400 uses
+    84500 uses
+    84600 uses
+    84700 uses
+    84800 uses
+    84900 uses
+    85000 uses
+    85100 uses
+    85200 uses
+    85300 uses
+    85400 uses
+    85500 uses
+    85600 uses
+    85700 uses
+    85800 uses
+    85900 uses
+    86000 uses
+    86100 uses
+    86200 uses
+    86300 uses
+    86400 uses
+    86500 uses
+    86600 uses
+    86700 uses
+    86800 uses
+    86900 uses
+    87000 uses
+    87100 uses
+    87200 uses
+    87300 uses
+    87400 uses
+    87500 uses
+    87600 uses
+    87700 uses
+    87800 uses
+    87900 uses
+    88000 uses
+    88100 uses
+    88200 uses
+    88300 uses
+    88400 uses
+    88500 uses
+    88600 uses
+    88700 uses
+    88800 uses
+    88900 uses
+    89000 uses
+    89100 uses
+    89200 uses
+    89300 uses
+    89400 uses
+    89500 uses
+    89600 uses
+    89700 uses
+    89800 uses
+    89900 uses
+    90000 uses
+    90100 uses
+    90200 uses
+    90300 uses
+    90400 uses
+    90500 uses
+    90600 uses
+    90700 uses
+    90800 uses
+    90900 uses
+    91000 uses
+    91100 uses
+    91200 uses
+    91300 uses
+    91400 uses
+    91500 uses
+    91600 uses
+    91700 uses
+    91800 uses
+    91900 uses
+    92000 uses
+    92100 uses
+    92200 uses
+    92300 uses
+    92400 uses
+    92500 uses
+    92600 uses
+    92700 uses
+    92800 uses
+    92900 uses
+    93000 uses
+    93100 uses
+    93200 uses
+    93300 uses
+    93400 uses
+    93500 uses
+    93600 uses
+    93700 uses
+    93800 uses
+    93900 uses
+    94000 uses
+    94100 uses
+    94200 uses
+    94300 uses
+    94400 uses
+    94500 uses
+    94600 uses
+    94700 uses
+    94800 uses
+    94900 uses
+    95000 uses
+    95100 uses
+    95200 uses
+    95300 uses
+    95400 uses
+    95500 uses
+    95600 uses
+    95700 uses
+    95800 uses
+    95900 uses
+    96000 uses
+    96100 uses
+    96200 uses
+    96300 uses
+    96400 uses
+    96500 uses
+    96600 uses
+    96700 uses
+    96800 uses
+    96900 uses
+    97000 uses
+    97100 uses
+    97200 uses
+    97300 uses
+    97400 uses
+    97500 uses
+    97600 uses
+    97700 uses
+    97800 uses
+    97900 uses
+    98000 uses
+    98100 uses
+    98200 uses
+    98300 uses
+    98400 uses
+    98500 uses
+    98600 uses
+    98700 uses
+    98800 uses
+    98900 uses
+    99000 uses
+    99100 uses
+    99200 uses
+    99300 uses
+    99400 uses
+    99500 uses
+    99600 uses
+    99700 uses
+    99800 uses
+    99900 uses
+    100000 uses
+    100100 uses
+    100200 uses
+    100300 uses
+    100400 uses
+    100500 uses
+    100600 uses
+    100700 uses
+    100800 uses
+    100900 uses
+    101000 uses
+    101100 uses
+    101200 uses
+    101300 uses
+    101400 uses
+    101500 uses
+    101600 uses
+    101700 uses
+    101800 uses
+    101900 uses
+    102000 uses
+    102100 uses
+    102200 uses
+    102300 uses
+    102400 uses
+    102500 uses
+    102600 uses
+    102700 uses
+    102800 uses
+    102900 uses
+    103000 uses
+    103100 uses
+    103200 uses
+    103300 uses
+    103400 uses
+    103500 uses
+    103600 uses
+    103700 uses
+    103800 uses
+    103900 uses
+    104000 uses
+    104100 uses
+    104200 uses
+    104300 uses
+    104400 uses
+    104500 uses
+    104600 uses
+    104700 uses
+    104800 uses
+    104900 uses
+    105000 uses
+    105100 uses
+    105200 uses
+    105300 uses
+    105400 uses
+    105500 uses
+    105600 uses
+    105700 uses
+    105800 uses
+    105900 uses
+    106000 uses
+    106100 uses
+    106200 uses
+    106300 uses
+    106400 uses
+    106500 uses
+    106600 uses
+    106700 uses
+    106800 uses
+    106900 uses
+    107000 uses
+    107100 uses
+    107200 uses
+    107300 uses
+    107400 uses
+    107500 uses
+    107600 uses
+    107700 uses
+    107800 uses
+    107900 uses
+    108000 uses
+    108100 uses
+    108200 uses
+    108300 uses
+    108400 uses
+    108500 uses
+    108600 uses
+    108700 uses
+    108800 uses
+    108900 uses
+    109000 uses
+    109100 uses
+    109200 uses
+    109300 uses
+    109400 uses
+    109500 uses
+    109600 uses
+    109700 uses
+    109800 uses
+    109900 uses
+    110000 uses
+    110100 uses
+    110200 uses
+    110300 uses
+    110400 uses
+    110500 uses
+    110600 uses
+    110700 uses
+    110800 uses
+    110900 uses
+    111000 uses
+    111100 uses
+    111200 uses
+    111300 uses
+    111400 uses
+    111500 uses
+    111600 uses
+    111700 uses
+    111800 uses
+    111900 uses
+    112000 uses
+    112100 uses
+    112200 uses
+    112300 uses
+    112400 uses
+    112500 uses
+    112600 uses
+    112700 uses
+    112800 uses
+    112900 uses
+    113000 uses
+    113100 uses
+    113200 uses
+    113300 uses
+    113400 uses
+    113500 uses
+    113600 uses
+    113700 uses
+    113800 uses
+    113900 uses
+    114000 uses
+    114100 uses
+    114200 uses
+    114300 uses
+    114400 uses
+    114500 uses
+    114600 uses
+    114700 uses
+    114800 uses
+    114900 uses
+    115000 uses
+    115100 uses
+    115200 uses
+    115300 uses
+    115400 uses
+    115500 uses
+    115600 uses
+    115700 uses
+    115800 uses
+    115900 uses
+    116000 uses
+    116100 uses
+    116200 uses
+    116300 uses
+    116400 uses
+    116500 uses
+    116600 uses
+    116700 uses
+    116800 uses
+    116900 uses
+    117000 uses
+    117100 uses
+    117200 uses
+    117300 uses
+    117400 uses
+    117500 uses
+    117600 uses
+    117700 uses
+    117800 uses
+    117900 uses
+    118000 uses
+    118100 uses
+    118200 uses
+    118300 uses
+    118400 uses
+    118500 uses
+    118600 uses
+    118700 uses
+    118800 uses
+    118900 uses
+    119000 uses
+    119100 uses
+    119200 uses
+    119300 uses
+    119400 uses
+    119500 uses
+    119600 uses
+    119700 uses
+    119800 uses
+    119900 uses
+    120000 uses
+    120100 uses
+    120200 uses
+    120300 uses
+    120400 uses
+    120500 uses
+    120600 uses
+    120700 uses
+    120800 uses
+    120900 uses
+    121000 uses
+    121100 uses
+    121200 uses
+    121300 uses
+    121400 uses
+    121500 uses
+    121600 uses
+    121700 uses
+    121800 uses
+Reading "sky130_fd_sc_hd__clkdlybuf4s15_2".
+Reading "sky130_fd_sc_hd__mux2_1".
+Reading "sky130_fd_sc_hd__mux2_4".
+Reading "clk_skew_adjust".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+Reading "sky130_ef_sc_hd__fakediode_2".
+Reading "sky130_fd_sc_hd__bufbuf_16".
+Reading "wb_host".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+Reading "scr1_intf".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+    13800 uses
+    13900 uses
+    14000 uses
+    14100 uses
+    14200 uses
+    14300 uses
+    14400 uses
+    14500 uses
+    14600 uses
+    14700 uses
+    14800 uses
+    14900 uses
+    15000 uses
+    15100 uses
+    15200 uses
+    15300 uses
+    15400 uses
+    15500 uses
+    15600 uses
+    15700 uses
+    15800 uses
+    15900 uses
+    16000 uses
+    16100 uses
+    16200 uses
+    16300 uses
+    16400 uses
+    16500 uses
+    16600 uses
+    16700 uses
+    16800 uses
+    16900 uses
+    17000 uses
+    17100 uses
+    17200 uses
+    17300 uses
+    17400 uses
+    17500 uses
+    17600 uses
+    17700 uses
+    17800 uses
+    17900 uses
+    18000 uses
+    18100 uses
+    18200 uses
+    18300 uses
+    18400 uses
+    18500 uses
+    18600 uses
+    18700 uses
+    18800 uses
+    18900 uses
+    19000 uses
+    19100 uses
+    19200 uses
+    19300 uses
+    19400 uses
+    19500 uses
+    19600 uses
+    19700 uses
+    19800 uses
+    19900 uses
+    20000 uses
+    20100 uses
+    20200 uses
+    20300 uses
+    20400 uses
+    20500 uses
+    20600 uses
+    20700 uses
+    20800 uses
+    20900 uses
+    21000 uses
+    21100 uses
+    21200 uses
+    21300 uses
+    21400 uses
+    21500 uses
+    21600 uses
+    21700 uses
+    21800 uses
+    21900 uses
+    22000 uses
+    22100 uses
+    22200 uses
+    22300 uses
+    22400 uses
+    22500 uses
+    22600 uses
+    22700 uses
+    22800 uses
+    22900 uses
+    23000 uses
+    23100 uses
+    23200 uses
+    23300 uses
+    23400 uses
+    23500 uses
+    23600 uses
+    23700 uses
+    23800 uses
+    23900 uses
+    24000 uses
+    24100 uses
+    24200 uses
+    24300 uses
+    24400 uses
+    24500 uses
+    24600 uses
+    24700 uses
+    24800 uses
+    24900 uses
+    25000 uses
+    25100 uses
+    25200 uses
+Reading "uart_core".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+Reading "wb_interconnect".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+    13800 uses
+    13900 uses
+    14000 uses
+    14100 uses
+    14200 uses
+    14300 uses
+    14400 uses
+    14500 uses
+    14600 uses
+    14700 uses
+    14800 uses
+    14900 uses
+    15000 uses
+    15100 uses
+    15200 uses
+    15300 uses
+    15400 uses
+    15500 uses
+    15600 uses
+    15700 uses
+    15800 uses
+    15900 uses
+    16000 uses
+    16100 uses
+    16200 uses
+    16300 uses
+    16400 uses
+    16500 uses
+    16600 uses
+    16700 uses
+    16800 uses
+    16900 uses
+    17000 uses
+    17100 uses
+    17200 uses
+    17300 uses
+    17400 uses
+    17500 uses
+    17600 uses
+    17700 uses
+    17800 uses
+    17900 uses
+    18000 uses
+    18100 uses
+    18200 uses
+    18300 uses
+    18400 uses
+    18500 uses
+    18600 uses
+    18700 uses
+    18800 uses
+    18900 uses
+    19000 uses
+    19100 uses
+    19200 uses
+    19300 uses
+    19400 uses
+    19500 uses
+    19600 uses
+    19700 uses
+    19800 uses
+    19900 uses
+    20000 uses
+    20100 uses
+    20200 uses
+    20300 uses
+    20400 uses
+    20500 uses
+    20600 uses
+    20700 uses
+    20800 uses
+    20900 uses
+    21000 uses
+    21100 uses
+    21200 uses
+    21300 uses
+    21400 uses
+    21500 uses
+    21600 uses
+    21700 uses
+    21800 uses
+    21900 uses
+    22000 uses
+    22100 uses
+    22200 uses
+    22300 uses
+    22400 uses
+    22500 uses
+    22600 uses
+    22700 uses
+    22800 uses
+    22900 uses
+    23000 uses
+    23100 uses
+    23200 uses
+    23300 uses
+    23400 uses
+    23500 uses
+    23600 uses
+    23700 uses
+    23800 uses
+    23900 uses
+    24000 uses
+    24100 uses
+    24200 uses
+    24300 uses
+    24400 uses
+    24500 uses
+    24600 uses
+    24700 uses
+    24800 uses
+    24900 uses
+    25000 uses
+    25100 uses
+    25200 uses
+    25300 uses
+    25400 uses
+    25500 uses
+    25600 uses
+    25700 uses
+    25800 uses
+    25900 uses
+    26000 uses
+    26100 uses
+    26200 uses
+    26300 uses
+    26400 uses
+    26500 uses
+    26600 uses
+Reading "sdrc_top".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+    13800 uses
+    13900 uses
+    14000 uses
+    14100 uses
+    14200 uses
+    14300 uses
+    14400 uses
+    14500 uses
+    14600 uses
+    14700 uses
+    14800 uses
+    14900 uses
+    15000 uses
+    15100 uses
+    15200 uses
+    15300 uses
+    15400 uses
+    15500 uses
+    15600 uses
+    15700 uses
+    15800 uses
+    15900 uses
+    16000 uses
+    16100 uses
+    16200 uses
+    16300 uses
+    16400 uses
+    16500 uses
+    16600 uses
+    16700 uses
+    16800 uses
+    16900 uses
+    17000 uses
+    17100 uses
+    17200 uses
+    17300 uses
+    17400 uses
+    17500 uses
+    17600 uses
+    17700 uses
+    17800 uses
+    17900 uses
+    18000 uses
+    18100 uses
+    18200 uses
+    18300 uses
+    18400 uses
+    18500 uses
+    18600 uses
+    18700 uses
+    18800 uses
+    18900 uses
+    19000 uses
+    19100 uses
+    19200 uses
+    19300 uses
+    19400 uses
+    19500 uses
+    19600 uses
+    19700 uses
+    19800 uses
+    19900 uses
+    20000 uses
+    20100 uses
+    20200 uses
+    20300 uses
+    20400 uses
+    20500 uses
+    20600 uses
+    20700 uses
+    20800 uses
+    20900 uses
+    21000 uses
+    21100 uses
+    21200 uses
+    21300 uses
+    21400 uses
+    21500 uses
+    21600 uses
+    21700 uses
+    21800 uses
+    21900 uses
+    22000 uses
+    22100 uses
+    22200 uses
+    22300 uses
+    22400 uses
+    22500 uses
+    22600 uses
+    22700 uses
+    22800 uses
+    22900 uses
+    23000 uses
+    23100 uses
+    23200 uses
+    23300 uses
+    23400 uses
+    23500 uses
+    23600 uses
+    23700 uses
+    23800 uses
+    23900 uses
+    24000 uses
+    24100 uses
+    24200 uses
+    24300 uses
+    24400 uses
+    24500 uses
+    24600 uses
+    24700 uses
+    24800 uses
+    24900 uses
+    25000 uses
+    25100 uses
+    25200 uses
+    25300 uses
+    25400 uses
+    25500 uses
+    25600 uses
+    25700 uses
+    25800 uses
+    25900 uses
+    26000 uses
+    26100 uses
+    26200 uses
+    26300 uses
+    26400 uses
+    26500 uses
+    26600 uses
+    26700 uses
+    26800 uses
+    26900 uses
+    27000 uses
+    27100 uses
+    27200 uses
+    27300 uses
+    27400 uses
+    27500 uses
+    27600 uses
+    27700 uses
+    27800 uses
+    27900 uses
+    28000 uses
+    28100 uses
+    28200 uses
+    28300 uses
+    28400 uses
+    28500 uses
+    28600 uses
+    28700 uses
+    28800 uses
+    28900 uses
+    29000 uses
+    29100 uses
+    29200 uses
+    29300 uses
+    29400 uses
+    29500 uses
+    29600 uses
+    29700 uses
+    29800 uses
+    29900 uses
+    30000 uses
+    30100 uses
+    30200 uses
+    30300 uses
+    30400 uses
+    30500 uses
+    30600 uses
+    30700 uses
+    30800 uses
+    30900 uses
+    31000 uses
+    31100 uses
+    31200 uses
+    31300 uses
+    31400 uses
+    31500 uses
+    31600 uses
+    31700 uses
+    31800 uses
+    31900 uses
+    32000 uses
+    32100 uses
+    32200 uses
+    32300 uses
+    32400 uses
+    32500 uses
+    32600 uses
+    32700 uses
+    32800 uses
+    32900 uses
+    33000 uses
+    33100 uses
+    33200 uses
+    33300 uses
+    33400 uses
+    33500 uses
+    33600 uses
+    33700 uses
+    33800 uses
+    33900 uses
+    34000 uses
+    34100 uses
+    34200 uses
+    34300 uses
+    34400 uses
+    34500 uses
+    34600 uses
+    34700 uses
+    34800 uses
+    34900 uses
+    35000 uses
+    35100 uses
+Reading "glbl_cfg".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+    13800 uses
+    13900 uses
+    14000 uses
+    14100 uses
+Reading "sky130_fd_sc_hd__dlygate4sd3_1".
+Reading "spim_top".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+    13800 uses
+    13900 uses
+    14000 uses
+    14100 uses
+    14200 uses
+    14300 uses
+    14400 uses
+    14500 uses
+    14600 uses
+    14700 uses
+    14800 uses
+    14900 uses
+    15000 uses
+    15100 uses
+    15200 uses
+    15300 uses
+    15400 uses
+    15500 uses
+    15600 uses
+    15700 uses
+    15800 uses
+    15900 uses
+    16000 uses
+    16100 uses
+    16200 uses
+    16300 uses
+    16400 uses
+    16500 uses
+    16600 uses
+    16700 uses
+    16800 uses
+    16900 uses
+    17000 uses
+    17100 uses
+    17200 uses
+    17300 uses
+    17400 uses
+    17500 uses
+    17600 uses
+    17700 uses
+    17800 uses
+    17900 uses
+    18000 uses
+    18100 uses
+    18200 uses
+    18300 uses
+    18400 uses
+    18500 uses
+    18600 uses
+    18700 uses
+    18800 uses
+    18900 uses
+    19000 uses
+    19100 uses
+    19200 uses
+    19300 uses
+    19400 uses
+    19500 uses
+    19600 uses
+    19700 uses
+    19800 uses
+    19900 uses
+    20000 uses
+    20100 uses
+    20200 uses
+    20300 uses
+    20400 uses
+    20500 uses
+    20600 uses
+    20700 uses
+    20800 uses
+    20900 uses
+    21000 uses
+    21100 uses
+    21200 uses
+    21300 uses
+    21400 uses
+    21500 uses
+    21600 uses
+    21700 uses
+    21800 uses
+    21900 uses
+    22000 uses
+    22100 uses
+    22200 uses
+    22300 uses
+    22400 uses
+    22500 uses
+    22600 uses
+    22700 uses
+    22800 uses
+    22900 uses
+    23000 uses
+    23100 uses
+    23200 uses
+    23300 uses
+    23400 uses
+    23500 uses
+    23600 uses
+    23700 uses
+    23800 uses
+    23900 uses
+    24000 uses
+    24100 uses
+    24200 uses
+    24300 uses
+    24400 uses
+    24500 uses
+    24600 uses
+    24700 uses
+    24800 uses
+    24900 uses
+    25000 uses
+    25100 uses
+    25200 uses
+    25300 uses
+    25400 uses
+    25500 uses
+    25600 uses
+    25700 uses
+    25800 uses
+    25900 uses
+    26000 uses
+    26100 uses
+    26200 uses
+    26300 uses
+    26400 uses
+    26500 uses
+    26600 uses
+    26700 uses
+    26800 uses
+    26900 uses
+    27000 uses
+    27100 uses
+    27200 uses
+    27300 uses
+Reading "user_project_wrapper".
+Root cell box:
+           width x height  (   llx,  lly  ), (   urx,  ury  )  area (units^2)
+
+microns:   20.00 x 3520.00  (-20.00,  0.00 ), (  0.00,  3520.00)  70400.00  
+lambda:   2000.00 x 352000.00  (-2000.00,  0.00 ), (  0.00,  352000.00)  704000000.00
+internal:   4000 x 704000  ( -4000,  0    ), (     0,  704000)  2816000000
+Root cell box:
+           width x height  (   llx,  lly  ), (   urx,  ury  )  area (units^2)
+
+microns:   20.00 x 3520.00  ( 2920.00,  0.00 ), ( 2940.00,  3520.00)  70400.00  
+lambda:   2000.00 x 352000.00  ( 292000.00,  0.00 ), ( 294000.00,  352000.00)  704000000.00
+internal:   4000 x 704000  ( 584000,  0    ), ( 588000,  704000)  2816000000
+Root cell box:
+           width x height  (   llx,  lly  ), (   urx,  ury  )  area (units^2)
+
+microns:  2960.00 x 20.00   (-20.00, -20.00), ( 2940.00,  0.00 )  59200.00  
+lambda:   296000.00 x 2000.00  (-2000.00, -2000.00), ( 294000.00,  0.00 )  592000000.00
+internal: 592000 x 4000    ( -4000, -4000 ), ( 588000,  0    )  2368000000
+Root cell box:
+           width x height  (   llx,  lly  ), (   urx,  ury  )  area (units^2)
+
+microns:  2960.00 x 20.00   (-20.00,  3520.00), ( 2940.00,  3540.00)  59200.00  
+lambda:   296000.00 x 2000.00  (-2000.00,  352000.00), ( 294000.00,  354000.00)  592000000.00
+internal: 592000 x 4000    ( -4000,  704000), ( 588000,  708000)  2368000000
+   Generating output for cell xor_target
+/home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper_erased.gds
diff --git a/checks/erase_box_user_project_wrapper_empty.gds.log b/checks/erase_box_user_project_wrapper_empty.gds.log
new file mode 100644
index 0000000..a2e47b6
--- /dev/null
+++ b/checks/erase_box_user_project_wrapper_empty.gds.log
@@ -0,0 +1,45 @@
+/home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper_empty.gds /home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper_empty_erased.gds user_project_wrapper
+
+Magic 8.3 revision 182 - Compiled on Fri Jun 25 23:58:13 UTC 2021.
+Starting magic under Tcl interpreter
+Using the terminal as the console.
+Using NULL graphics device.
+Processing system .magicrc file
+Sourcing design .magicrc for technology sky130A ...
+2 Magic internal units = 1 Lambda
+Input style sky130(): scaleFactor=2, multiplier=2
+Scaled tech values by 2 / 1 to match internal grid scaling
+Loading sky130A Device Generator Menu ...
+Using technology "sky130A", version 1.0.116-4-g522a373
+Input style sky130(vendor): scaleFactor=2, multiplier=2
+CIF input style is now "sky130(vendor)"
+Warning: Calma reading is not undoable!  I hope that's OK.
+Library written using GDS-II Release 3.0
+Library name: user_project_wrapper
+Reading "user_project_wrapper".
+Root cell box:
+           width x height  (   llx,  lly  ), (   urx,  ury  )  area (units^2)
+
+microns:   20.00 x 3520.00  (-20.00,  0.00 ), (  0.00,  3520.00)  70400.00  
+lambda:   2000.00 x 352000.00  (-2000.00,  0.00 ), (  0.00,  352000.00)  704000000.00
+internal:   4000 x 704000  ( -4000,  0    ), (     0,  704000)  2816000000
+Root cell box:
+           width x height  (   llx,  lly  ), (   urx,  ury  )  area (units^2)
+
+microns:   20.00 x 3520.00  ( 2920.00,  0.00 ), ( 2940.00,  3520.00)  70400.00  
+lambda:   2000.00 x 352000.00  ( 292000.00,  0.00 ), ( 294000.00,  352000.00)  704000000.00
+internal:   4000 x 704000  ( 584000,  0    ), ( 588000,  704000)  2816000000
+Root cell box:
+           width x height  (   llx,  lly  ), (   urx,  ury  )  area (units^2)
+
+microns:  2960.00 x 20.00   (-20.00, -20.00), ( 2940.00,  0.00 )  59200.00  
+lambda:   296000.00 x 2000.00  (-2000.00, -2000.00), ( 294000.00,  0.00 )  592000000.00
+internal: 592000 x 4000    ( -4000, -4000 ), ( 588000,  0    )  2368000000
+Root cell box:
+           width x height  (   llx,  lly  ), (   urx,  ury  )  area (units^2)
+
+microns:  2960.00 x 20.00   (-20.00,  3520.00), ( 2940.00,  3540.00)  59200.00  
+lambda:   296000.00 x 2000.00  (-2000.00,  352000.00), ( 294000.00,  354000.00)  592000000.00
+internal: 592000 x 4000    ( -4000,  704000), ( 588000,  708000)  2368000000
+   Generating output for cell xor_target
+/home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper_empty_erased.gds
diff --git a/checks/full_log.log b/checks/full_log.log
new file mode 100644
index 0000000..6b9756a
--- /dev/null
+++ b/checks/full_log.log
@@ -0,0 +1,43 @@
+FULL RUN LOG:
+ Executing Step 0 of 8: Extracting GDS Files
+Step 0 done without fatal errors.
+ Executing Step 1 of 8: Project License Check
+{{LICENSE COMPLIANCE PASSED}} Apache-2.0 LICENSE file was found in project root
+ SPDX COMPLIANCE Found 1110 non-compliant files with the SPDX Standard. Check full log for more information
+SPDX COMPLIANCE: NON-COMPLIANT FILES PREVIEW: ['/home/dinesha/workarea/opencore/git/yifive_r0/README.md', '/home/dinesha/workarea/opencore/git/yifive_r0/spef/user_project_wrapper.spef', '/home/dinesha/workarea/opencore/git/yifive_r0/spef/wb_host.spef', '/home/dinesha/workarea/opencore/git/yifive_r0/spef/sdrc_top.spef', '/home/dinesha/workarea/opencore/git/yifive_r0/spef/wb_interconnect.spef', '/home/dinesha/workarea/opencore/git/yifive_r0/spef/scr1_top_wb.spef', '/home/dinesha/workarea/opencore/git/yifive_r0/spef/glbl_cfg.spef', '/home/dinesha/workarea/opencore/git/yifive_r0/spef/test.spef', '/home/dinesha/workarea/opencore/git/yifive_r0/spef/uart_core.spef', '/home/dinesha/workarea/opencore/git/yifive_r0/spef/clk_skew_adjust.spef', '/home/dinesha/workarea/opencore/git/yifive_r0/spef/clk_buf.spef', '/home/dinesha/workarea/opencore/git/yifive_r0/spef/spim_top.spef', '/home/dinesha/workarea/opencore/git/yifive_r0/openlane/default.cvcrc', '/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/aa', '/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/config.tcl', '/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic_spice.tcl', '/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/opt.lib', '/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/trimmed.lib', '/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/tracks_copy.info', '/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib']
+ Executing Step 2 of 8: YAML File Check
+ YAML file valid!
+Step 2 done without fatal errors.
+ Detected Project Type is "digital"
+ Executing Step 3 of 8: Project Compliance Checks
+b'Going into /home/dinesha/workarea/opencore/git/yifive_r0/caravel'
+b'Removing manifest'
+b'Fetching manifest'
+b'Running sha1sum checks'
+ Manifest Checks Passed. Caravel Version Matches.
+ Makefile Checks Passed.
+ Documentation Checks Passed.
+ Executing Step 4 of 8: Fuzzy Consistency Checks
+instance caravel found
+instance user_project_wrapper found
+Design is complex and contains: 47 modules
+Design is complex and contains: 20 modules
+verilog Consistency Checks Passed.
+ Basic Hierarchy Checks Passed.
+{PROGRESS} Running Pins and Power Checks...
+Pins check passed
+Internal Power Checks Passed!
+Power Checks Passed
+ Fuzzy Consistency Checks Passed!
+Step 4 done without fatal errors.
+ Executing Step 5 of 8: XOR Consistency Checks
+ Running XOR Checks...
+Total XOR differences = 2488
+ XOR Checks on GDS Failed, Reason: XOR Differences count is 2488. Please view /home/dinesha/workarea/opencore/git/yifive_r0/checks/*.xor.* for more details.
+TEST FAILED AT STEP 5
+ Executing Step 6 of 8: DRC Violations Checks
+ Running Magic DRC Checks...
+Violation Message "All nwells must contain metal-connected N+ taps (nwell.4) "found 1 Times.
+ DRC Checks on GDS Failed, Reason: Total # of DRC violations is 1
+TEST FAILED AT STEP 6
+ SOME Checks FAILED !!!
diff --git a/checks/magic_drc.log b/checks/magic_drc.log
new file mode 100644
index 0000000..b91926b
--- /dev/null
+++ b/checks/magic_drc.log
@@ -0,0 +1,2847 @@
+
+Magic 8.3 revision 182 - Compiled on Fri Jun 25 23:58:13 UTC 2021.
+Starting magic under Tcl interpreter
+Using the terminal as the console.
+Using NULL graphics device.
+Processing system .magicrc file
+Sourcing design .magicrc for technology sky130A ...
+2 Magic internal units = 1 Lambda
+Input style sky130(): scaleFactor=2, multiplier=2
+Scaled tech values by 2 / 1 to match internal grid scaling
+Loading sky130A Device Generator Menu ...
+Loading "/usr/local/bin/drc_checks/magic_drc_check.tcl" from command line.
+Warning: Calma reading is not undoable!  I hope that's OK.
+Library written using GDS-II Release 3.0
+Library name: user_project_wrapper
+Reading "sky130_fd_sc_hd__clkbuf_16".
+Reading "sky130_fd_sc_hd__buf_4".
+Reading "sky130_fd_sc_hd__a21o_4".
+Reading "sky130_fd_sc_hd__clkbuf_1".
+Reading "sky130_fd_sc_hd__dfstp_4".
+Reading "sky130_fd_sc_hd__or3_4".
+Reading "sky130_fd_sc_hd__a21boi_4".
+Reading "sky130_fd_sc_hd__or4_4".
+Reading "sky130_fd_sc_hd__a22oi_4".
+Reading "sky130_fd_sc_hd__and3_4".
+Reading "sky130_fd_sc_hd__o21ai_4".
+Reading "sky130_fd_sc_hd__o32a_4".
+Reading "sky130_fd_sc_hd__and2_4".
+Reading "sky130_fd_sc_hd__and4_4".
+Reading "sky130_fd_sc_hd__dfxtp_4".
+Reading "sky130_fd_sc_hd__or2_4".
+Reading "sky130_fd_sc_hd__diode_2".
+Reading "sky130_fd_sc_hd__o22a_4".
+Reading "sky130_fd_sc_hd__nor2_4".
+Reading "sky130_fd_sc_hd__o21a_4".
+Reading "sky130_fd_sc_hd__a32o_4".
+Reading "sky130_fd_sc_hd__buf_2".
+Reading "sky130_fd_sc_hd__a21oi_4".
+Reading "sky130_fd_sc_hd__nand2_4".
+Reading "sky130_fd_sc_hd__inv_2".
+Reading "sky130_fd_sc_hd__dfrtp_4".
+Reading "sky130_fd_sc_hd__decap_4".
+Reading "sky130_fd_sc_hd__a211o_4".
+Reading "sky130_fd_sc_hd__fill_2".
+Reading "sky130_fd_sc_hd__decap_8".
+Reading "sky130_fd_sc_hd__a2bb2o_4".
+Reading "sky130_fd_sc_hd__tapvpwrvgnd_1".
+Reading "sky130_fd_sc_hd__decap_12".
+Reading "sky130_fd_sc_hd__conb_1".
+Reading "sky130_fd_sc_hd__decap_6".
+Reading "sky130_fd_sc_hd__fill_1".
+Reading "sky130_fd_sc_hd__decap_3".
+Reading "sky130_fd_sc_hd__a2111o_4".
+Reading "sky130_fd_sc_hd__a21bo_4".
+Reading "sky130_fd_sc_hd__o41a_4".
+Reading "sky130_fd_sc_hd__buf_8".
+Reading "scr1_core_top".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+    13800 uses
+    13900 uses
+    14000 uses
+    14100 uses
+    14200 uses
+    14300 uses
+    14400 uses
+    14500 uses
+    14600 uses
+    14700 uses
+    14800 uses
+    14900 uses
+    15000 uses
+    15100 uses
+    15200 uses
+    15300 uses
+    15400 uses
+    15500 uses
+    15600 uses
+    15700 uses
+    15800 uses
+    15900 uses
+    16000 uses
+    16100 uses
+    16200 uses
+    16300 uses
+    16400 uses
+    16500 uses
+    16600 uses
+    16700 uses
+    16800 uses
+    16900 uses
+    17000 uses
+    17100 uses
+    17200 uses
+    17300 uses
+    17400 uses
+    17500 uses
+    17600 uses
+    17700 uses
+    17800 uses
+    17900 uses
+    18000 uses
+    18100 uses
+    18200 uses
+    18300 uses
+    18400 uses
+    18500 uses
+    18600 uses
+    18700 uses
+    18800 uses
+    18900 uses
+    19000 uses
+    19100 uses
+    19200 uses
+    19300 uses
+    19400 uses
+    19500 uses
+    19600 uses
+    19700 uses
+    19800 uses
+    19900 uses
+    20000 uses
+    20100 uses
+    20200 uses
+    20300 uses
+    20400 uses
+    20500 uses
+    20600 uses
+    20700 uses
+    20800 uses
+    20900 uses
+    21000 uses
+    21100 uses
+    21200 uses
+    21300 uses
+    21400 uses
+    21500 uses
+    21600 uses
+    21700 uses
+    21800 uses
+    21900 uses
+    22000 uses
+    22100 uses
+    22200 uses
+    22300 uses
+    22400 uses
+    22500 uses
+    22600 uses
+    22700 uses
+    22800 uses
+    22900 uses
+    23000 uses
+    23100 uses
+    23200 uses
+    23300 uses
+    23400 uses
+    23500 uses
+    23600 uses
+    23700 uses
+    23800 uses
+    23900 uses
+    24000 uses
+    24100 uses
+    24200 uses
+    24300 uses
+    24400 uses
+    24500 uses
+    24600 uses
+    24700 uses
+    24800 uses
+    24900 uses
+    25000 uses
+    25100 uses
+    25200 uses
+    25300 uses
+    25400 uses
+    25500 uses
+    25600 uses
+    25700 uses
+    25800 uses
+    25900 uses
+    26000 uses
+    26100 uses
+    26200 uses
+    26300 uses
+    26400 uses
+    26500 uses
+    26600 uses
+    26700 uses
+    26800 uses
+    26900 uses
+    27000 uses
+    27100 uses
+    27200 uses
+    27300 uses
+    27400 uses
+    27500 uses
+    27600 uses
+    27700 uses
+    27800 uses
+    27900 uses
+    28000 uses
+    28100 uses
+    28200 uses
+    28300 uses
+    28400 uses
+    28500 uses
+    28600 uses
+    28700 uses
+    28800 uses
+    28900 uses
+    29000 uses
+    29100 uses
+    29200 uses
+    29300 uses
+    29400 uses
+    29500 uses
+    29600 uses
+    29700 uses
+    29800 uses
+    29900 uses
+    30000 uses
+    30100 uses
+    30200 uses
+    30300 uses
+    30400 uses
+    30500 uses
+    30600 uses
+    30700 uses
+    30800 uses
+    30900 uses
+    31000 uses
+    31100 uses
+    31200 uses
+    31300 uses
+    31400 uses
+    31500 uses
+    31600 uses
+    31700 uses
+    31800 uses
+    31900 uses
+    32000 uses
+    32100 uses
+    32200 uses
+    32300 uses
+    32400 uses
+    32500 uses
+    32600 uses
+    32700 uses
+    32800 uses
+    32900 uses
+    33000 uses
+    33100 uses
+    33200 uses
+    33300 uses
+    33400 uses
+    33500 uses
+    33600 uses
+    33700 uses
+    33800 uses
+    33900 uses
+    34000 uses
+    34100 uses
+    34200 uses
+    34300 uses
+    34400 uses
+    34500 uses
+    34600 uses
+    34700 uses
+    34800 uses
+    34900 uses
+    35000 uses
+    35100 uses
+    35200 uses
+    35300 uses
+    35400 uses
+    35500 uses
+    35600 uses
+    35700 uses
+    35800 uses
+    35900 uses
+    36000 uses
+    36100 uses
+    36200 uses
+    36300 uses
+    36400 uses
+    36500 uses
+    36600 uses
+    36700 uses
+    36800 uses
+    36900 uses
+    37000 uses
+    37100 uses
+    37200 uses
+    37300 uses
+    37400 uses
+    37500 uses
+    37600 uses
+    37700 uses
+    37800 uses
+    37900 uses
+    38000 uses
+    38100 uses
+    38200 uses
+    38300 uses
+    38400 uses
+    38500 uses
+    38600 uses
+    38700 uses
+    38800 uses
+    38900 uses
+    39000 uses
+    39100 uses
+    39200 uses
+    39300 uses
+    39400 uses
+    39500 uses
+    39600 uses
+    39700 uses
+    39800 uses
+    39900 uses
+    40000 uses
+    40100 uses
+    40200 uses
+    40300 uses
+    40400 uses
+    40500 uses
+    40600 uses
+    40700 uses
+    40800 uses
+    40900 uses
+    41000 uses
+    41100 uses
+    41200 uses
+    41300 uses
+    41400 uses
+    41500 uses
+    41600 uses
+    41700 uses
+    41800 uses
+    41900 uses
+    42000 uses
+    42100 uses
+    42200 uses
+    42300 uses
+    42400 uses
+    42500 uses
+    42600 uses
+    42700 uses
+    42800 uses
+    42900 uses
+    43000 uses
+    43100 uses
+    43200 uses
+    43300 uses
+    43400 uses
+    43500 uses
+    43600 uses
+    43700 uses
+    43800 uses
+    43900 uses
+    44000 uses
+    44100 uses
+    44200 uses
+    44300 uses
+    44400 uses
+    44500 uses
+    44600 uses
+    44700 uses
+    44800 uses
+    44900 uses
+    45000 uses
+    45100 uses
+    45200 uses
+    45300 uses
+    45400 uses
+    45500 uses
+    45600 uses
+    45700 uses
+    45800 uses
+    45900 uses
+    46000 uses
+    46100 uses
+    46200 uses
+    46300 uses
+    46400 uses
+    46500 uses
+    46600 uses
+    46700 uses
+    46800 uses
+    46900 uses
+    47000 uses
+    47100 uses
+    47200 uses
+    47300 uses
+    47400 uses
+    47500 uses
+    47600 uses
+    47700 uses
+    47800 uses
+    47900 uses
+    48000 uses
+    48100 uses
+    48200 uses
+    48300 uses
+    48400 uses
+    48500 uses
+    48600 uses
+    48700 uses
+    48800 uses
+    48900 uses
+    49000 uses
+    49100 uses
+    49200 uses
+    49300 uses
+    49400 uses
+    49500 uses
+    49600 uses
+    49700 uses
+    49800 uses
+    49900 uses
+    50000 uses
+    50100 uses
+    50200 uses
+    50300 uses
+    50400 uses
+    50500 uses
+    50600 uses
+    50700 uses
+    50800 uses
+    50900 uses
+    51000 uses
+    51100 uses
+    51200 uses
+    51300 uses
+    51400 uses
+    51500 uses
+    51600 uses
+    51700 uses
+    51800 uses
+    51900 uses
+    52000 uses
+    52100 uses
+    52200 uses
+    52300 uses
+    52400 uses
+    52500 uses
+    52600 uses
+    52700 uses
+    52800 uses
+    52900 uses
+    53000 uses
+    53100 uses
+    53200 uses
+    53300 uses
+    53400 uses
+    53500 uses
+    53600 uses
+    53700 uses
+    53800 uses
+    53900 uses
+    54000 uses
+    54100 uses
+    54200 uses
+    54300 uses
+    54400 uses
+    54500 uses
+    54600 uses
+    54700 uses
+    54800 uses
+    54900 uses
+    55000 uses
+    55100 uses
+    55200 uses
+    55300 uses
+    55400 uses
+    55500 uses
+    55600 uses
+    55700 uses
+    55800 uses
+    55900 uses
+    56000 uses
+    56100 uses
+    56200 uses
+    56300 uses
+    56400 uses
+    56500 uses
+    56600 uses
+    56700 uses
+    56800 uses
+    56900 uses
+    57000 uses
+    57100 uses
+    57200 uses
+    57300 uses
+    57400 uses
+    57500 uses
+    57600 uses
+    57700 uses
+    57800 uses
+    57900 uses
+    58000 uses
+    58100 uses
+    58200 uses
+    58300 uses
+    58400 uses
+    58500 uses
+    58600 uses
+    58700 uses
+    58800 uses
+    58900 uses
+    59000 uses
+    59100 uses
+    59200 uses
+    59300 uses
+    59400 uses
+    59500 uses
+    59600 uses
+    59700 uses
+    59800 uses
+    59900 uses
+    60000 uses
+    60100 uses
+    60200 uses
+    60300 uses
+    60400 uses
+    60500 uses
+    60600 uses
+    60700 uses
+    60800 uses
+    60900 uses
+    61000 uses
+    61100 uses
+    61200 uses
+    61300 uses
+    61400 uses
+    61500 uses
+    61600 uses
+    61700 uses
+    61800 uses
+    61900 uses
+    62000 uses
+    62100 uses
+    62200 uses
+    62300 uses
+    62400 uses
+    62500 uses
+    62600 uses
+    62700 uses
+    62800 uses
+    62900 uses
+    63000 uses
+    63100 uses
+    63200 uses
+    63300 uses
+    63400 uses
+    63500 uses
+    63600 uses
+    63700 uses
+    63800 uses
+    63900 uses
+    64000 uses
+    64100 uses
+    64200 uses
+    64300 uses
+    64400 uses
+    64500 uses
+    64600 uses
+    64700 uses
+    64800 uses
+    64900 uses
+    65000 uses
+    65100 uses
+    65200 uses
+    65300 uses
+    65400 uses
+    65500 uses
+    65600 uses
+    65700 uses
+    65800 uses
+    65900 uses
+    66000 uses
+    66100 uses
+    66200 uses
+    66300 uses
+    66400 uses
+    66500 uses
+    66600 uses
+    66700 uses
+    66800 uses
+    66900 uses
+    67000 uses
+    67100 uses
+    67200 uses
+    67300 uses
+    67400 uses
+    67500 uses
+    67600 uses
+    67700 uses
+    67800 uses
+    67900 uses
+    68000 uses
+    68100 uses
+    68200 uses
+    68300 uses
+    68400 uses
+    68500 uses
+    68600 uses
+    68700 uses
+    68800 uses
+    68900 uses
+    69000 uses
+    69100 uses
+    69200 uses
+    69300 uses
+    69400 uses
+    69500 uses
+    69600 uses
+    69700 uses
+    69800 uses
+    69900 uses
+    70000 uses
+    70100 uses
+    70200 uses
+    70300 uses
+    70400 uses
+    70500 uses
+    70600 uses
+    70700 uses
+    70800 uses
+    70900 uses
+    71000 uses
+    71100 uses
+    71200 uses
+    71300 uses
+    71400 uses
+    71500 uses
+    71600 uses
+    71700 uses
+    71800 uses
+    71900 uses
+    72000 uses
+    72100 uses
+    72200 uses
+    72300 uses
+    72400 uses
+    72500 uses
+    72600 uses
+    72700 uses
+    72800 uses
+    72900 uses
+    73000 uses
+    73100 uses
+    73200 uses
+    73300 uses
+    73400 uses
+    73500 uses
+    73600 uses
+    73700 uses
+    73800 uses
+    73900 uses
+    74000 uses
+    74100 uses
+    74200 uses
+    74300 uses
+    74400 uses
+    74500 uses
+    74600 uses
+    74700 uses
+    74800 uses
+    74900 uses
+    75000 uses
+    75100 uses
+    75200 uses
+    75300 uses
+    75400 uses
+    75500 uses
+    75600 uses
+    75700 uses
+    75800 uses
+    75900 uses
+    76000 uses
+    76100 uses
+    76200 uses
+    76300 uses
+    76400 uses
+    76500 uses
+    76600 uses
+    76700 uses
+    76800 uses
+    76900 uses
+    77000 uses
+    77100 uses
+    77200 uses
+    77300 uses
+    77400 uses
+    77500 uses
+    77600 uses
+    77700 uses
+    77800 uses
+    77900 uses
+    78000 uses
+    78100 uses
+    78200 uses
+    78300 uses
+    78400 uses
+    78500 uses
+    78600 uses
+    78700 uses
+    78800 uses
+    78900 uses
+    79000 uses
+    79100 uses
+    79200 uses
+    79300 uses
+    79400 uses
+    79500 uses
+    79600 uses
+    79700 uses
+    79800 uses
+    79900 uses
+    80000 uses
+    80100 uses
+    80200 uses
+    80300 uses
+    80400 uses
+    80500 uses
+    80600 uses
+    80700 uses
+    80800 uses
+    80900 uses
+    81000 uses
+    81100 uses
+    81200 uses
+    81300 uses
+    81400 uses
+    81500 uses
+    81600 uses
+    81700 uses
+    81800 uses
+    81900 uses
+    82000 uses
+    82100 uses
+    82200 uses
+    82300 uses
+    82400 uses
+    82500 uses
+    82600 uses
+    82700 uses
+    82800 uses
+    82900 uses
+    83000 uses
+    83100 uses
+    83200 uses
+    83300 uses
+    83400 uses
+    83500 uses
+    83600 uses
+    83700 uses
+    83800 uses
+    83900 uses
+    84000 uses
+    84100 uses
+    84200 uses
+    84300 uses
+    84400 uses
+    84500 uses
+    84600 uses
+    84700 uses
+    84800 uses
+    84900 uses
+    85000 uses
+    85100 uses
+    85200 uses
+    85300 uses
+    85400 uses
+    85500 uses
+    85600 uses
+    85700 uses
+    85800 uses
+    85900 uses
+    86000 uses
+    86100 uses
+    86200 uses
+    86300 uses
+    86400 uses
+    86500 uses
+    86600 uses
+    86700 uses
+    86800 uses
+    86900 uses
+    87000 uses
+    87100 uses
+    87200 uses
+    87300 uses
+    87400 uses
+    87500 uses
+    87600 uses
+    87700 uses
+    87800 uses
+    87900 uses
+    88000 uses
+    88100 uses
+    88200 uses
+    88300 uses
+    88400 uses
+    88500 uses
+    88600 uses
+    88700 uses
+    88800 uses
+    88900 uses
+    89000 uses
+    89100 uses
+    89200 uses
+    89300 uses
+    89400 uses
+    89500 uses
+    89600 uses
+    89700 uses
+    89800 uses
+    89900 uses
+    90000 uses
+    90100 uses
+    90200 uses
+    90300 uses
+    90400 uses
+    90500 uses
+    90600 uses
+    90700 uses
+    90800 uses
+    90900 uses
+    91000 uses
+    91100 uses
+    91200 uses
+    91300 uses
+    91400 uses
+    91500 uses
+    91600 uses
+    91700 uses
+    91800 uses
+    91900 uses
+    92000 uses
+    92100 uses
+    92200 uses
+    92300 uses
+    92400 uses
+    92500 uses
+    92600 uses
+    92700 uses
+    92800 uses
+    92900 uses
+    93000 uses
+    93100 uses
+    93200 uses
+    93300 uses
+    93400 uses
+    93500 uses
+    93600 uses
+    93700 uses
+    93800 uses
+    93900 uses
+    94000 uses
+    94100 uses
+    94200 uses
+    94300 uses
+    94400 uses
+    94500 uses
+    94600 uses
+    94700 uses
+    94800 uses
+    94900 uses
+    95000 uses
+    95100 uses
+    95200 uses
+    95300 uses
+    95400 uses
+    95500 uses
+    95600 uses
+    95700 uses
+    95800 uses
+    95900 uses
+    96000 uses
+    96100 uses
+    96200 uses
+    96300 uses
+    96400 uses
+    96500 uses
+    96600 uses
+    96700 uses
+    96800 uses
+    96900 uses
+    97000 uses
+    97100 uses
+    97200 uses
+    97300 uses
+    97400 uses
+    97500 uses
+    97600 uses
+    97700 uses
+    97800 uses
+    97900 uses
+    98000 uses
+    98100 uses
+    98200 uses
+    98300 uses
+    98400 uses
+    98500 uses
+    98600 uses
+    98700 uses
+    98800 uses
+    98900 uses
+    99000 uses
+    99100 uses
+    99200 uses
+    99300 uses
+    99400 uses
+    99500 uses
+    99600 uses
+    99700 uses
+    99800 uses
+    99900 uses
+    100000 uses
+    100100 uses
+    100200 uses
+    100300 uses
+    100400 uses
+    100500 uses
+    100600 uses
+    100700 uses
+    100800 uses
+    100900 uses
+    101000 uses
+    101100 uses
+    101200 uses
+    101300 uses
+    101400 uses
+    101500 uses
+    101600 uses
+    101700 uses
+    101800 uses
+    101900 uses
+    102000 uses
+    102100 uses
+    102200 uses
+    102300 uses
+    102400 uses
+    102500 uses
+    102600 uses
+    102700 uses
+    102800 uses
+    102900 uses
+    103000 uses
+    103100 uses
+    103200 uses
+    103300 uses
+    103400 uses
+    103500 uses
+    103600 uses
+    103700 uses
+    103800 uses
+    103900 uses
+    104000 uses
+    104100 uses
+    104200 uses
+    104300 uses
+    104400 uses
+    104500 uses
+    104600 uses
+    104700 uses
+    104800 uses
+    104900 uses
+    105000 uses
+    105100 uses
+    105200 uses
+    105300 uses
+    105400 uses
+    105500 uses
+    105600 uses
+    105700 uses
+    105800 uses
+    105900 uses
+    106000 uses
+    106100 uses
+    106200 uses
+    106300 uses
+    106400 uses
+    106500 uses
+    106600 uses
+    106700 uses
+    106800 uses
+    106900 uses
+    107000 uses
+    107100 uses
+    107200 uses
+    107300 uses
+    107400 uses
+    107500 uses
+    107600 uses
+    107700 uses
+    107800 uses
+    107900 uses
+    108000 uses
+    108100 uses
+    108200 uses
+    108300 uses
+    108400 uses
+    108500 uses
+    108600 uses
+    108700 uses
+    108800 uses
+    108900 uses
+    109000 uses
+    109100 uses
+    109200 uses
+    109300 uses
+    109400 uses
+    109500 uses
+    109600 uses
+    109700 uses
+    109800 uses
+    109900 uses
+    110000 uses
+    110100 uses
+    110200 uses
+    110300 uses
+    110400 uses
+    110500 uses
+    110600 uses
+    110700 uses
+    110800 uses
+    110900 uses
+    111000 uses
+    111100 uses
+    111200 uses
+    111300 uses
+    111400 uses
+    111500 uses
+    111600 uses
+    111700 uses
+    111800 uses
+    111900 uses
+    112000 uses
+    112100 uses
+    112200 uses
+    112300 uses
+    112400 uses
+    112500 uses
+    112600 uses
+    112700 uses
+    112800 uses
+    112900 uses
+    113000 uses
+    113100 uses
+    113200 uses
+    113300 uses
+    113400 uses
+    113500 uses
+    113600 uses
+    113700 uses
+    113800 uses
+    113900 uses
+    114000 uses
+    114100 uses
+    114200 uses
+    114300 uses
+    114400 uses
+    114500 uses
+    114600 uses
+    114700 uses
+    114800 uses
+    114900 uses
+    115000 uses
+    115100 uses
+    115200 uses
+    115300 uses
+    115400 uses
+    115500 uses
+    115600 uses
+    115700 uses
+    115800 uses
+    115900 uses
+    116000 uses
+    116100 uses
+    116200 uses
+    116300 uses
+    116400 uses
+    116500 uses
+    116600 uses
+    116700 uses
+    116800 uses
+    116900 uses
+    117000 uses
+    117100 uses
+    117200 uses
+    117300 uses
+    117400 uses
+    117500 uses
+    117600 uses
+    117700 uses
+    117800 uses
+    117900 uses
+    118000 uses
+    118100 uses
+    118200 uses
+    118300 uses
+    118400 uses
+    118500 uses
+    118600 uses
+    118700 uses
+    118800 uses
+    118900 uses
+    119000 uses
+    119100 uses
+    119200 uses
+    119300 uses
+    119400 uses
+    119500 uses
+    119600 uses
+    119700 uses
+    119800 uses
+    119900 uses
+    120000 uses
+    120100 uses
+    120200 uses
+    120300 uses
+    120400 uses
+    120500 uses
+    120600 uses
+    120700 uses
+    120800 uses
+    120900 uses
+    121000 uses
+    121100 uses
+    121200 uses
+    121300 uses
+    121400 uses
+    121500 uses
+    121600 uses
+    121700 uses
+    121800 uses
+Reading "sky130_fd_sc_hd__clkdlybuf4s15_2".
+Reading "sky130_fd_sc_hd__mux2_1".
+Reading "sky130_fd_sc_hd__mux2_4".
+Reading "clk_skew_adjust".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+Reading "sky130_ef_sc_hd__fakediode_2".
+Reading "sky130_fd_sc_hd__bufbuf_16".
+Reading "wb_host".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+Reading "scr1_intf".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+    13800 uses
+    13900 uses
+    14000 uses
+    14100 uses
+    14200 uses
+    14300 uses
+    14400 uses
+    14500 uses
+    14600 uses
+    14700 uses
+    14800 uses
+    14900 uses
+    15000 uses
+    15100 uses
+    15200 uses
+    15300 uses
+    15400 uses
+    15500 uses
+    15600 uses
+    15700 uses
+    15800 uses
+    15900 uses
+    16000 uses
+    16100 uses
+    16200 uses
+    16300 uses
+    16400 uses
+    16500 uses
+    16600 uses
+    16700 uses
+    16800 uses
+    16900 uses
+    17000 uses
+    17100 uses
+    17200 uses
+    17300 uses
+    17400 uses
+    17500 uses
+    17600 uses
+    17700 uses
+    17800 uses
+    17900 uses
+    18000 uses
+    18100 uses
+    18200 uses
+    18300 uses
+    18400 uses
+    18500 uses
+    18600 uses
+    18700 uses
+    18800 uses
+    18900 uses
+    19000 uses
+    19100 uses
+    19200 uses
+    19300 uses
+    19400 uses
+    19500 uses
+    19600 uses
+    19700 uses
+    19800 uses
+    19900 uses
+    20000 uses
+    20100 uses
+    20200 uses
+    20300 uses
+    20400 uses
+    20500 uses
+    20600 uses
+    20700 uses
+    20800 uses
+    20900 uses
+    21000 uses
+    21100 uses
+    21200 uses
+    21300 uses
+    21400 uses
+    21500 uses
+    21600 uses
+    21700 uses
+    21800 uses
+    21900 uses
+    22000 uses
+    22100 uses
+    22200 uses
+    22300 uses
+    22400 uses
+    22500 uses
+    22600 uses
+    22700 uses
+    22800 uses
+    22900 uses
+    23000 uses
+    23100 uses
+    23200 uses
+    23300 uses
+    23400 uses
+    23500 uses
+    23600 uses
+    23700 uses
+    23800 uses
+    23900 uses
+    24000 uses
+    24100 uses
+    24200 uses
+    24300 uses
+    24400 uses
+    24500 uses
+    24600 uses
+    24700 uses
+    24800 uses
+    24900 uses
+    25000 uses
+    25100 uses
+    25200 uses
+Reading "uart_core".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+Reading "wb_interconnect".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+    13800 uses
+    13900 uses
+    14000 uses
+    14100 uses
+    14200 uses
+    14300 uses
+    14400 uses
+    14500 uses
+    14600 uses
+    14700 uses
+    14800 uses
+    14900 uses
+    15000 uses
+    15100 uses
+    15200 uses
+    15300 uses
+    15400 uses
+    15500 uses
+    15600 uses
+    15700 uses
+    15800 uses
+    15900 uses
+    16000 uses
+    16100 uses
+    16200 uses
+    16300 uses
+    16400 uses
+    16500 uses
+    16600 uses
+    16700 uses
+    16800 uses
+    16900 uses
+    17000 uses
+    17100 uses
+    17200 uses
+    17300 uses
+    17400 uses
+    17500 uses
+    17600 uses
+    17700 uses
+    17800 uses
+    17900 uses
+    18000 uses
+    18100 uses
+    18200 uses
+    18300 uses
+    18400 uses
+    18500 uses
+    18600 uses
+    18700 uses
+    18800 uses
+    18900 uses
+    19000 uses
+    19100 uses
+    19200 uses
+    19300 uses
+    19400 uses
+    19500 uses
+    19600 uses
+    19700 uses
+    19800 uses
+    19900 uses
+    20000 uses
+    20100 uses
+    20200 uses
+    20300 uses
+    20400 uses
+    20500 uses
+    20600 uses
+    20700 uses
+    20800 uses
+    20900 uses
+    21000 uses
+    21100 uses
+    21200 uses
+    21300 uses
+    21400 uses
+    21500 uses
+    21600 uses
+    21700 uses
+    21800 uses
+    21900 uses
+    22000 uses
+    22100 uses
+    22200 uses
+    22300 uses
+    22400 uses
+    22500 uses
+    22600 uses
+    22700 uses
+    22800 uses
+    22900 uses
+    23000 uses
+    23100 uses
+    23200 uses
+    23300 uses
+    23400 uses
+    23500 uses
+    23600 uses
+    23700 uses
+    23800 uses
+    23900 uses
+    24000 uses
+    24100 uses
+    24200 uses
+    24300 uses
+    24400 uses
+    24500 uses
+    24600 uses
+    24700 uses
+    24800 uses
+    24900 uses
+    25000 uses
+    25100 uses
+    25200 uses
+    25300 uses
+    25400 uses
+    25500 uses
+    25600 uses
+    25700 uses
+    25800 uses
+    25900 uses
+    26000 uses
+    26100 uses
+    26200 uses
+    26300 uses
+    26400 uses
+    26500 uses
+    26600 uses
+Reading "sdrc_top".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+    13800 uses
+    13900 uses
+    14000 uses
+    14100 uses
+    14200 uses
+    14300 uses
+    14400 uses
+    14500 uses
+    14600 uses
+    14700 uses
+    14800 uses
+    14900 uses
+    15000 uses
+    15100 uses
+    15200 uses
+    15300 uses
+    15400 uses
+    15500 uses
+    15600 uses
+    15700 uses
+    15800 uses
+    15900 uses
+    16000 uses
+    16100 uses
+    16200 uses
+    16300 uses
+    16400 uses
+    16500 uses
+    16600 uses
+    16700 uses
+    16800 uses
+    16900 uses
+    17000 uses
+    17100 uses
+    17200 uses
+    17300 uses
+    17400 uses
+    17500 uses
+    17600 uses
+    17700 uses
+    17800 uses
+    17900 uses
+    18000 uses
+    18100 uses
+    18200 uses
+    18300 uses
+    18400 uses
+    18500 uses
+    18600 uses
+    18700 uses
+    18800 uses
+    18900 uses
+    19000 uses
+    19100 uses
+    19200 uses
+    19300 uses
+    19400 uses
+    19500 uses
+    19600 uses
+    19700 uses
+    19800 uses
+    19900 uses
+    20000 uses
+    20100 uses
+    20200 uses
+    20300 uses
+    20400 uses
+    20500 uses
+    20600 uses
+    20700 uses
+    20800 uses
+    20900 uses
+    21000 uses
+    21100 uses
+    21200 uses
+    21300 uses
+    21400 uses
+    21500 uses
+    21600 uses
+    21700 uses
+    21800 uses
+    21900 uses
+    22000 uses
+    22100 uses
+    22200 uses
+    22300 uses
+    22400 uses
+    22500 uses
+    22600 uses
+    22700 uses
+    22800 uses
+    22900 uses
+    23000 uses
+    23100 uses
+    23200 uses
+    23300 uses
+    23400 uses
+    23500 uses
+    23600 uses
+    23700 uses
+    23800 uses
+    23900 uses
+    24000 uses
+    24100 uses
+    24200 uses
+    24300 uses
+    24400 uses
+    24500 uses
+    24600 uses
+    24700 uses
+    24800 uses
+    24900 uses
+    25000 uses
+    25100 uses
+    25200 uses
+    25300 uses
+    25400 uses
+    25500 uses
+    25600 uses
+    25700 uses
+    25800 uses
+    25900 uses
+    26000 uses
+    26100 uses
+    26200 uses
+    26300 uses
+    26400 uses
+    26500 uses
+    26600 uses
+    26700 uses
+    26800 uses
+    26900 uses
+    27000 uses
+    27100 uses
+    27200 uses
+    27300 uses
+    27400 uses
+    27500 uses
+    27600 uses
+    27700 uses
+    27800 uses
+    27900 uses
+    28000 uses
+    28100 uses
+    28200 uses
+    28300 uses
+    28400 uses
+    28500 uses
+    28600 uses
+    28700 uses
+    28800 uses
+    28900 uses
+    29000 uses
+    29100 uses
+    29200 uses
+    29300 uses
+    29400 uses
+    29500 uses
+    29600 uses
+    29700 uses
+    29800 uses
+    29900 uses
+    30000 uses
+    30100 uses
+    30200 uses
+    30300 uses
+    30400 uses
+    30500 uses
+    30600 uses
+    30700 uses
+    30800 uses
+    30900 uses
+    31000 uses
+    31100 uses
+    31200 uses
+    31300 uses
+    31400 uses
+    31500 uses
+    31600 uses
+    31700 uses
+    31800 uses
+    31900 uses
+    32000 uses
+    32100 uses
+    32200 uses
+    32300 uses
+    32400 uses
+    32500 uses
+    32600 uses
+    32700 uses
+    32800 uses
+    32900 uses
+    33000 uses
+    33100 uses
+    33200 uses
+    33300 uses
+    33400 uses
+    33500 uses
+    33600 uses
+    33700 uses
+    33800 uses
+    33900 uses
+    34000 uses
+    34100 uses
+    34200 uses
+    34300 uses
+    34400 uses
+    34500 uses
+    34600 uses
+    34700 uses
+    34800 uses
+    34900 uses
+    35000 uses
+    35100 uses
+Reading "glbl_cfg".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+    13800 uses
+    13900 uses
+    14000 uses
+    14100 uses
+Reading "sky130_fd_sc_hd__dlygate4sd3_1".
+Reading "spim_top".
+    100 uses
+    200 uses
+    300 uses
+    400 uses
+    500 uses
+    600 uses
+    700 uses
+    800 uses
+    900 uses
+    1000 uses
+    1100 uses
+    1200 uses
+    1300 uses
+    1400 uses
+    1500 uses
+    1600 uses
+    1700 uses
+    1800 uses
+    1900 uses
+    2000 uses
+    2100 uses
+    2200 uses
+    2300 uses
+    2400 uses
+    2500 uses
+    2600 uses
+    2700 uses
+    2800 uses
+    2900 uses
+    3000 uses
+    3100 uses
+    3200 uses
+    3300 uses
+    3400 uses
+    3500 uses
+    3600 uses
+    3700 uses
+    3800 uses
+    3900 uses
+    4000 uses
+    4100 uses
+    4200 uses
+    4300 uses
+    4400 uses
+    4500 uses
+    4600 uses
+    4700 uses
+    4800 uses
+    4900 uses
+    5000 uses
+    5100 uses
+    5200 uses
+    5300 uses
+    5400 uses
+    5500 uses
+    5600 uses
+    5700 uses
+    5800 uses
+    5900 uses
+    6000 uses
+    6100 uses
+    6200 uses
+    6300 uses
+    6400 uses
+    6500 uses
+    6600 uses
+    6700 uses
+    6800 uses
+    6900 uses
+    7000 uses
+    7100 uses
+    7200 uses
+    7300 uses
+    7400 uses
+    7500 uses
+    7600 uses
+    7700 uses
+    7800 uses
+    7900 uses
+    8000 uses
+    8100 uses
+    8200 uses
+    8300 uses
+    8400 uses
+    8500 uses
+    8600 uses
+    8700 uses
+    8800 uses
+    8900 uses
+    9000 uses
+    9100 uses
+    9200 uses
+    9300 uses
+    9400 uses
+    9500 uses
+    9600 uses
+    9700 uses
+    9800 uses
+    9900 uses
+    10000 uses
+    10100 uses
+    10200 uses
+    10300 uses
+    10400 uses
+    10500 uses
+    10600 uses
+    10700 uses
+    10800 uses
+    10900 uses
+    11000 uses
+    11100 uses
+    11200 uses
+    11300 uses
+    11400 uses
+    11500 uses
+    11600 uses
+    11700 uses
+    11800 uses
+    11900 uses
+    12000 uses
+    12100 uses
+    12200 uses
+    12300 uses
+    12400 uses
+    12500 uses
+    12600 uses
+    12700 uses
+    12800 uses
+    12900 uses
+    13000 uses
+    13100 uses
+    13200 uses
+    13300 uses
+    13400 uses
+    13500 uses
+    13600 uses
+    13700 uses
+    13800 uses
+    13900 uses
+    14000 uses
+    14100 uses
+    14200 uses
+    14300 uses
+    14400 uses
+    14500 uses
+    14600 uses
+    14700 uses
+    14800 uses
+    14900 uses
+    15000 uses
+    15100 uses
+    15200 uses
+    15300 uses
+    15400 uses
+    15500 uses
+    15600 uses
+    15700 uses
+    15800 uses
+    15900 uses
+    16000 uses
+    16100 uses
+    16200 uses
+    16300 uses
+    16400 uses
+    16500 uses
+    16600 uses
+    16700 uses
+    16800 uses
+    16900 uses
+    17000 uses
+    17100 uses
+    17200 uses
+    17300 uses
+    17400 uses
+    17500 uses
+    17600 uses
+    17700 uses
+    17800 uses
+    17900 uses
+    18000 uses
+    18100 uses
+    18200 uses
+    18300 uses
+    18400 uses
+    18500 uses
+    18600 uses
+    18700 uses
+    18800 uses
+    18900 uses
+    19000 uses
+    19100 uses
+    19200 uses
+    19300 uses
+    19400 uses
+    19500 uses
+    19600 uses
+    19700 uses
+    19800 uses
+    19900 uses
+    20000 uses
+    20100 uses
+    20200 uses
+    20300 uses
+    20400 uses
+    20500 uses
+    20600 uses
+    20700 uses
+    20800 uses
+    20900 uses
+    21000 uses
+    21100 uses
+    21200 uses
+    21300 uses
+    21400 uses
+    21500 uses
+    21600 uses
+    21700 uses
+    21800 uses
+    21900 uses
+    22000 uses
+    22100 uses
+    22200 uses
+    22300 uses
+    22400 uses
+    22500 uses
+    22600 uses
+    22700 uses
+    22800 uses
+    22900 uses
+    23000 uses
+    23100 uses
+    23200 uses
+    23300 uses
+    23400 uses
+    23500 uses
+    23600 uses
+    23700 uses
+    23800 uses
+    23900 uses
+    24000 uses
+    24100 uses
+    24200 uses
+    24300 uses
+    24400 uses
+    24500 uses
+    24600 uses
+    24700 uses
+    24800 uses
+    24900 uses
+    25000 uses
+    25100 uses
+    25200 uses
+    25300 uses
+    25400 uses
+    25500 uses
+    25600 uses
+    25700 uses
+    25800 uses
+    25900 uses
+    26000 uses
+    26100 uses
+    26200 uses
+    26300 uses
+    26400 uses
+    26500 uses
+    26600 uses
+    26700 uses
+    26800 uses
+    26900 uses
+    27000 uses
+    27100 uses
+    27200 uses
+    27300 uses
+Reading "user_project_wrapper".
+[INFO]: Loading user_project_wrapper
+
+DRC style is now "drc(full)"
+Loading DRC CIF style.
+[INFO]: COUNT: 1
+[INFO]: Should be divided by 3 or 4
+[INFO]: DRC Checking DONE (/home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper.magic.drc)
+[INFO]: Saving mag view with DRC errors(/home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper.magic.drc.mag)
+[INFO]: Saved
diff --git a/checks/manifest_check.log b/checks/manifest_check.log
new file mode 100644
index 0000000..13005a7
--- /dev/null
+++ b/checks/manifest_check.log
@@ -0,0 +1,47 @@
+verilog/rtl/DFFRAM.v: OK
+verilog/rtl/DFFRAMBB.v: OK
+verilog/rtl/__uprj_analog_netlists.v: OK
+verilog/rtl/__uprj_netlists.v: OK
+verilog/rtl/__user_analog_project_wrapper.v: OK
+verilog/rtl/__user_project_wrapper.v: OK
+verilog/rtl/caravan.v: OK
+verilog/rtl/caravan_netlists.v: OK
+verilog/rtl/caravel.v: OK
+verilog/rtl/caravel_clocking.v: OK
+verilog/rtl/chip_io.v: OK
+verilog/rtl/chip_io_alt.v: OK
+verilog/rtl/clock_div.v: OK
+verilog/rtl/convert_gpio_sigs.v: OK
+verilog/rtl/counter_timer_high.v: OK
+verilog/rtl/counter_timer_low.v: OK
+verilog/rtl/digital_pll.v: OK
+verilog/rtl/digital_pll_controller.v: OK
+verilog/rtl/gpio_control_block.v: OK
+verilog/rtl/gpio_wb.v: OK
+verilog/rtl/housekeeping_spi.v: OK
+verilog/rtl/la_wb.v: OK
+verilog/rtl/mem_wb.v: OK
+verilog/rtl/mgmt_core.v: OK
+verilog/rtl/mgmt_protect.v: OK
+verilog/rtl/mgmt_protect_hv.v: OK
+verilog/rtl/mgmt_soc.v: OK
+verilog/rtl/mprj2_logic_high.v: OK
+verilog/rtl/mprj_ctrl.v: OK
+verilog/rtl/mprj_io.v: OK
+verilog/rtl/mprj_logic_high.v: OK
+verilog/rtl/pads.v: OK
+verilog/rtl/picorv32.v: OK
+verilog/rtl/ring_osc2x13.v: OK
+verilog/rtl/simple_por.v: OK
+verilog/rtl/simple_spi_master.v: OK
+verilog/rtl/simpleuart.v: OK
+verilog/rtl/sky130_fd_sc_hvl__lsbufhv2lv_1_wrapped.v: OK
+verilog/rtl/spimemio.v: OK
+verilog/rtl/sram_1rw1r_32_256_8_sky130.v: OK
+verilog/rtl/storage.v: OK
+verilog/rtl/storage_bridge_wb.v: OK
+verilog/rtl/sysctrl.v: OK
+verilog/rtl/wb_intercon.v: OK
+scripts/set_user_id.py: OK
+scripts/generate_fill.py: OK
+scripts/compositor.py: OK
diff --git a/checks/spdx_compliance_report.log b/checks/spdx_compliance_report.log
new file mode 100644
index 0000000..8cdfdef
--- /dev/null
+++ b/checks/spdx_compliance_report.log
@@ -0,0 +1,1112 @@
+FULL RUN LOG:
+SPDX NON-COMPLIANT FILES
+/home/dinesha/workarea/opencore/git/yifive_r0/README.md
+/home/dinesha/workarea/opencore/git/yifive_r0/spef/user_project_wrapper.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/spef/wb_host.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/spef/sdrc_top.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/spef/wb_interconnect.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/spef/scr1_top_wb.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/spef/glbl_cfg.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/spef/test.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/spef/uart_core.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/spef/clk_skew_adjust.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/spef/clk_buf.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/spef/spim_top.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/default.cvcrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/aa
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic_spice.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/routing/20-fastroute_4.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/routing/24-tritonRoute.param
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/routing/17-fastroute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/routing/21-fastroute_5.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/routing/24-tritonRoute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/routing/19-fastroute_3.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/routing/18-fastroute_2.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__inv_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__conb_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__nor2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__and2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/scr1_core_top.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__a21oi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__fill_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__a32o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__or2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__clkbuf_16.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__decap_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__diode_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__buf_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__buf_8.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__nand2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__a211o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__a21o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__a21boi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__buf_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__or3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__decap_12.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__a2bb2o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__and4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__decap_3.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__o21ai_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__a22oi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__dfrtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__dfxtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__tapvpwrvgnd_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__a2111o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__o41a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__fill_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__clkbuf_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__o32a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__decap_6.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__or4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__a21bo_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__decap_8.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__inv_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__o21a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__o22a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__and3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/magic/sky130_fd_sc_hd__dfstp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/tmp/lvs/setup_file.lef.lvs
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/runtime_summary_report.rpt.parsable
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/runtime_summary_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/manufacturability_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/2-opensta.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/2-opensta_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/11-opensta_post_openphysyn.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/11-opensta_post_openphysyn.slew.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/11-opensta_post_openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/27-opensta_spef_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/11-opensta_post_openphysyn.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/11-opensta_post_openphysyn.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/27-opensta_spef.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/2-opensta_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/27-opensta_spef_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/2-opensta.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/27-opensta_spef.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/2-opensta.slew.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/2-opensta.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/11-opensta_post_openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/27-opensta_spef.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/routing/45-antenna.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/floorplan/3-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/floorplan/3-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/klayout/37-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/klayout/39-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/klayout/43-klayout.magic.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/placement/9-openphysyn_allchecks.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/placement/9-openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/placement/9-openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/reports/placement/9-openphysyn_violators.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/results/synthesis/scr1_core_top.synthesis_optimized.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/results/synthesis/scr1_core_top.synthesis_preroute.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/results/synthesis/scr1_core_top.synthesis_cts.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/results/synthesis/scr1_core_top.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/results/routing/scr1_core_top.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/results/routing/scr1_core_top.def.ref
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/results/magic/.magicrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/results/magic/scr1_core_top.gds.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/results/lvs/scr1_core_top.lvs.lef.json
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/results/lvs/scr1_core_top.lvs.powered.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_core/runs/scr_core/results/klayout/scr1_core_top.lyp
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/unconstraints.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/routing/25-tritonRoute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/routing/20-fastroute_4.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/routing/17-fastroute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/routing/21-fastroute_5.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/routing/22-fastroute_6.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/routing/19-fastroute_3.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/routing/18-fastroute_2.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/tmp/routing/25-tritonRoute.param
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/2-opensta.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/2-opensta_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/11-opensta_post_openphysyn.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/11-opensta_post_openphysyn.slew.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/11-opensta_post_openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/11-opensta_post_openphysyn.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/11-opensta_post_openphysyn.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/2-opensta_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/2-opensta.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/2-opensta.slew.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/2-opensta.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/11-opensta_post_openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/floorplan/3-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/floorplan/3-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/placement/9-openphysyn_allchecks.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/placement/9-openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/reports/placement/9-openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/results/synthesis/scr1_top_wb.synthesis_preroute.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/results/synthesis/scr1_top_wb.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/results/synthesis/scr1_top_wb.synthesis_cts.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/results/synthesis/scr1_top_wb.synthesis_optimized.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/syntacore/runs/syntacore/results/routing/scr1_top_wb.def.ref
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic_spice.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/routing/23-tritonRoute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/routing/23-tritonRoute.param
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/routing/21-fastroute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__nor2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__and2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__fill_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__a32o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__or2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__clkbuf_16.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__decap_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__diode_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__nand2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__buf_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__or3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__decap_12.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__a2bb2o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__and4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__decap_3.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__dfrtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__tapvpwrvgnd_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__fill_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__clkbuf_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__decap_6.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__or4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__decap_8.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__inv_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/glbl_cfg.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__o21a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__o22a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__and3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/magic/sky130_fd_sc_hd__dfstp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/tmp/lvs/setup_file.lef.lvs
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/runtime_summary_report.rpt.parsable
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/runtime_summary_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/manufacturability_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/26-opensta_spef_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/26-opensta_spef.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/26-opensta_spef_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/2-opensta.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/2-opensta_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/11-opensta_post_openphysyn.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/11-opensta_post_openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/11-opensta_post_openphysyn.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/11-opensta_post_openphysyn.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/2-opensta_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/2-opensta.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/26-opensta_spef.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/2-opensta.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/26-opensta_spef.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/11-opensta_post_openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/routing/44-antenna.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/floorplan/3-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/floorplan/3-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/klayout/36-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/klayout/38-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/klayout/42-klayout.magic.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/placement/9-openphysyn_allchecks.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/placement/9-openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/placement/9-openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/reports/placement/9-openphysyn_violators.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/results/synthesis/glbl_cfg.synthesis_preroute.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/results/synthesis/glbl_cfg.synthesis_optimized.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/results/synthesis/glbl_cfg.synthesis_cts.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/results/synthesis/glbl_cfg.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/results/synthesis/glbl_cfg.synthesis_diodes.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/results/routing/glbl_cfg.def.ref
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/results/routing/glbl_cfg.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/results/magic/.magicrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/results/magic/glbl_cfg.gds.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/results/lvs/glbl_cfg.lvs.powered.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/results/lvs/glbl_cfg.lvs.lef.json
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/glbl_cfg/runs/glbl_cfg/results/klayout/glbl_cfg.lyp
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/magic_spice.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/routing/13-fastroute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/routing/16-tritonRoute.param
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/routing/16-tritonRoute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/magic/sky130_fd_sc_hd__mux2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/magic/clk_skew_adjust.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/magic/sky130_fd_sc_hd__clkdlybuf4s15_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/magic/sky130_fd_sc_hd__mux2_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/magic/sky130_fd_sc_hd__fill_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/magic/sky130_fd_sc_hd__decap_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/magic/sky130_fd_sc_hd__decap_12.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/magic/sky130_fd_sc_hd__decap_3.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/magic/sky130_fd_sc_hd__tapvpwrvgnd_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/magic/sky130_fd_sc_hd__fill_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/magic/sky130_fd_sc_hd__decap_6.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/magic/sky130_fd_sc_hd__decap_8.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/tmp/lvs/setup_file.lef.lvs
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/runtime_summary_report.rpt.parsable
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/runtime_summary_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/manufacturability_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/routing/36-antenna.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/floorplan/2-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/floorplan/2-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/klayout/30-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/klayout/28-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/klayout/34-klayout.magic.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/placement/8-openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/placement/8-openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/reports/placement/8-openphysyn_allchecks.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/synthesis/clk_skew_adjust.synthesis_preroute.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/synthesis/clk_skew_adjust.synthesis_optimized.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/synthesis/clk_skew_adjust.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/cvc/cvc_clk_skew_adjust.error
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/cvc/cvc_clk_skew_adjust.debug
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/cvc/clk_skew_adjust.cdl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/cvc/clk_skew_adjust.power
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/routing/clk_skew_adjust.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/routing/clk_skew_adjust.def.ref
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/magic/.magicrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/magic/clk_skew_adjust.gds.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/lvs/clk_skew_adjust.lvs.powered.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/lvs/clk_skew_adjust.lvs.lef.json
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_skew_adjust/runs/clk_skew_adjust/results/klayout/clk_skew_adjust.lyp
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/a
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic_spice.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/routing/20-fastroute_4.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/routing/24-tritonRoute.param
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/routing/17-fastroute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/routing/21-fastroute_5.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/routing/24-tritonRoute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/routing/19-fastroute_3.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/routing/18-fastroute_2.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__conb_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__nor2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__and2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__a21oi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__fill_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__a32o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__or2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__clkbuf_16.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__decap_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__diode_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__buf_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__nand2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__a211o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__a21o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__a21boi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__buf_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__or3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__decap_12.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__a2bb2o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__and4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__decap_3.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__o21ai_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__a22oi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__dfrtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__dfxtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__tapvpwrvgnd_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__fill_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__clkbuf_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__o32a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__decap_6.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__or4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__decap_8.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__inv_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__o21a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__o22a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__and3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/sky130_fd_sc_hd__dfstp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/magic/scr1_intf.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/tmp/lvs/setup_file.lef.lvs
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/runtime_summary_report.rpt.parsable
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/runtime_summary_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/manufacturability_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/2-opensta.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/2-opensta_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/11-opensta_post_openphysyn.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/11-opensta_post_openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/27-opensta_spef_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/11-opensta_post_openphysyn.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/11-opensta_post_openphysyn.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/27-opensta_spef.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/2-opensta_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/27-opensta_spef_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/2-opensta.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/27-opensta_spef.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/2-opensta.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/11-opensta_post_openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/27-opensta_spef.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/routing/45-antenna.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/floorplan/3-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/floorplan/3-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/klayout/37-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/klayout/39-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/klayout/43-klayout.magic.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/placement/9-openphysyn_allchecks.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/placement/9-openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/placement/9-openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/reports/placement/9-openphysyn_violators.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/results/synthesis/scr1_intf.synthesis_optimized.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/results/synthesis/scr1_intf.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/results/synthesis/scr1_intf.synthesis_preroute.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/results/synthesis/scr1_intf.synthesis_cts.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/results/routing/scr1_intf.def.ref
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/results/routing/scr1_intf.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/results/magic/.magicrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/results/magic/scr1_intf.gds.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/results/lvs/scr1_intf.lvs.lef.json
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/results/lvs/scr1_intf.lvs.powered.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/scr_intf/runs/scr_intf/results/klayout/scr1_intf.lyp
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic_spice.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/routing/23-tritonRoute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/routing/23-tritonRoute.param
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/routing/21-fastroute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__nor2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__and2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__a21oi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__fill_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__a32o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__or2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__clkbuf_16.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__decap_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__diode_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__a211o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__a21o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__buf_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__or3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__decap_12.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_ef_sc_hd__fakediode_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__a2bb2o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__and4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/wb_host.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__decap_3.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__o21ai_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__dfrtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__dfxtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__tapvpwrvgnd_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__a2111o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__fill_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__clkbuf_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__decap_6.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__or4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__a21bo_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__bufbuf_16.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__decap_8.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__inv_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__o21a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__o22a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__and3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/magic/sky130_fd_sc_hd__dfstp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/tmp/lvs/setup_file.lef.lvs
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/runtime_summary_report.rpt.parsable
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/runtime_summary_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/manufacturability_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/26-opensta_spef_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/26-opensta_spef.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/26-opensta_spef_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/2-opensta.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/2-opensta_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/11-opensta_post_openphysyn.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/11-opensta_post_openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/11-opensta_post_openphysyn.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/11-opensta_post_openphysyn.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/2-opensta_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/2-opensta.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/26-opensta_spef.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/2-opensta.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/26-opensta_spef.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/11-opensta_post_openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/routing/46-antenna.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/routing/28-antenna.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/floorplan/3-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/floorplan/3-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/klayout/40-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/klayout/38-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/klayout/44-klayout.magic.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/placement/9-openphysyn_allchecks.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/placement/9-openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/reports/placement/9-openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/results/synthesis/wb_host.synthesis_cts.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/results/synthesis/wb_host.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/results/synthesis/wb_host.synthesis_preroute.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/results/synthesis/wb_host.synthesis_diodes.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/results/synthesis/wb_host.synthesis_optimized.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/results/routing/wb_host.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/results/routing/wb_host.def.ref
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/results/magic/.magicrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/results/magic/wb_host.gds.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/results/lvs/wb_host.lvs.powered.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/results/lvs/wb_host.lvs.lef.json
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_host/runs/wb_host/results/klayout/wb_host.lyp
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/reports/runtime_summary_report.rpt.parsable
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/reports/runtime_summary_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/reports/manufacturability_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/reports/floorplan/2-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/reports/floorplan/2-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/clk_buf/runs/clk_buf/results/synthesis/clk_buf.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/unconstraints.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic_spice.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/routing/23-tritonRoute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/routing/23-tritonRoute.param
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/routing/21-fastroute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__conb_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__nor2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__and2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__a21oi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__fill_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__a32o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__or2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__clkbuf_16.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__decap_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__diode_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__buf_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__buf_8.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__nand2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__a211o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__a21o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__a21boi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__buf_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__or3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__decap_12.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__a2bb2o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__and4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/uart_core.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__decap_3.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__o21ai_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__a22oi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__dfrtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__dfxtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__tapvpwrvgnd_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__a2111o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__fill_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__clkbuf_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__decap_6.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__or4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__a21bo_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__decap_8.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__inv_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__o21a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__o22a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__and3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/magic/sky130_fd_sc_hd__dfstp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/tmp/lvs/setup_file.lef.lvs
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/runtime_summary_report.rpt.parsable
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/runtime_summary_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/manufacturability_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/26-opensta_spef_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/26-opensta_spef.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/26-opensta_spef_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/2-opensta.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/2-opensta_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/11-opensta_post_openphysyn.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/11-opensta_post_openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/11-opensta_post_openphysyn.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/11-opensta_post_openphysyn.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/2-opensta_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/2-opensta.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/26-opensta_spef.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/2-opensta.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/26-opensta_spef.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/11-opensta_post_openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/routing/44-antenna.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/floorplan/3-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/floorplan/3-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/klayout/36-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/klayout/38-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/klayout/42-klayout.magic.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/placement/9-openphysyn_allchecks.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/placement/9-openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/reports/placement/9-openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/results/synthesis/uart_core.synthesis_cts.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/results/synthesis/uart_core.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/results/synthesis/uart_core.synthesis_diodes.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/results/synthesis/uart_core.synthesis_optimized.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/results/synthesis/uart_core.synthesis_preroute.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/results/routing/uart_core.def.ref
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/results/routing/uart_core.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/results/magic/.magicrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/results/magic/uart_core.gds.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/results/lvs/uart_core.lvs.lef.json
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/results/lvs/uart_core.lvs.powered.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/uart/runs/uart/results/klayout/uart_core.lyp
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/unconstraints.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/runtime_summary_report.rpt.parsable
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/runtime_summary_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/manufacturability_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/synthesis/2-opensta.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/synthesis/2-opensta_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/synthesis/2-opensta_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/synthesis/2-opensta.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/synthesis/2-opensta.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/floorplan/3-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/reports/floorplan/3-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/temp/results/synthesis/test.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic_spice.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/routing/20-tritonRoute.param
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/routing/20-tritonRoute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/routing/17-fastroute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__conb_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__nor2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__and2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__a21oi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__fill_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__a32o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__or2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__clkbuf_16.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__decap_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__buf_8.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__nand2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__a211o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__a21o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__a21boi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__buf_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__or3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__decap_12.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__a2bb2o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__and4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__decap_3.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__o21ai_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__a22oi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__dfrtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__dfxtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__tapvpwrvgnd_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__a2111o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__dlygate4sd3_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__fill_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__clkbuf_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__o32a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__decap_6.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__or4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__a21bo_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/test.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__bufbuf_16.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__decap_8.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__inv_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__o21a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__o22a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__and3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/magic/sky130_fd_sc_hd__dfstp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/tmp/lvs/setup_file.lef.lvs
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/runtime_summary_report.rpt.parsable
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/runtime_summary_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/manufacturability_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/2-opensta.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/2-opensta_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/11-opensta_post_openphysyn.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/11-opensta_post_openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/23-opensta_spef_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/23-opensta_spef.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/11-opensta_post_openphysyn.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/11-opensta_post_openphysyn.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/23-opensta_spef.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/2-opensta_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/2-opensta.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/23-opensta_spef_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/2-opensta.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/23-opensta_spef.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/11-opensta_post_openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/routing/41-antenna.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/floorplan/3-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/floorplan/3-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/klayout/39-klayout.magic.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/klayout/35-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/klayout/33-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/placement/9-openphysyn_allchecks.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/placement/9-openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/placement/9-openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/reports/placement/9-openphysyn_violators.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/results/synthesis/test.synthesis_optimized.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/results/synthesis/test.synthesis_preroute.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/results/synthesis/test.synthesis_cts.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/results/synthesis/test.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/results/routing/test.def.ref
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/results/routing/test.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/results/magic/.magicrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/results/magic/test.gds.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/results/lvs/test.lvs.lef.json
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/results/lvs/test.lvs.powered.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/test/runs/test/results/klayout/test.lyp
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/unconstraints.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/tmp/routing/23-tritonRoute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/tmp/routing/23-tritonRoute.param
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/tmp/routing/21-fastroute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/runtime_summary_report.rpt.parsable
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/runtime_summary_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/manufacturability_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/2-opensta.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/2-opensta_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/11-opensta_post_openphysyn.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/11-opensta_post_openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/11-opensta_post_openphysyn.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/11-opensta_post_openphysyn.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/2-opensta_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/2-opensta.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/2-opensta.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/11-opensta_post_openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/floorplan/3-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/floorplan/3-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/placement/9-openphysyn_allchecks.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/placement/9-openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/reports/placement/9-openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/results/synthesis/wb_interconnect.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/results/synthesis/wb_interconnect.synthesis_diodes.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/results/synthesis/wb_interconnect.synthesis_cts.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/results/synthesis/wb_interconnect.synthesis_preroute.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/results/synthesis/wb_interconnect.synthesis_optimized.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/wb_interconnect/runs/wb_interconnect/results/routing/wb_interconnect.def.ref
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/unconstraints.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic_spice.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/routing/21-tritonRoute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/routing/17-fastroute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/routing/21-tritonRoute.param
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/routing/18-fastroute_2.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__conb_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__nor2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__and2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__a21oi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__fill_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__a32o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__or2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__clkbuf_16.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__decap_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__diode_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__buf_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__nand2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__a211o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__a21o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__a21boi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__buf_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__or3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__decap_12.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__a2bb2o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__and4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__decap_3.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__o21ai_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/spim_top.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__a22oi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__dfrtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__dfxtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__tapvpwrvgnd_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__a2111o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__dlygate4sd3_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__fill_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__clkbuf_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__o32a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__decap_6.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__or4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__a21bo_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__decap_8.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__inv_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__o21a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__o22a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__and3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/magic/sky130_fd_sc_hd__dfstp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/tmp/lvs/setup_file.lef.lvs
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/runtime_summary_report.rpt.parsable
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/runtime_summary_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/manufacturability_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/24-opensta_spef.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/2-opensta.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/2-opensta_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/11-opensta_post_openphysyn.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/11-opensta_post_openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/24-opensta_spef.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/11-opensta_post_openphysyn.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/11-opensta_post_openphysyn.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/2-opensta_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/2-opensta.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/2-opensta.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/24-opensta_spef_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/24-opensta_spef_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/11-opensta_post_openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/24-opensta_spef.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/routing/42-antenna.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/floorplan/3-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/floorplan/3-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/klayout/36-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/klayout/34-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/klayout/40-klayout.magic.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/placement/9-openphysyn_allchecks.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/placement/9-openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/placement/9-openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/reports/placement/9-openphysyn_violators.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/results/synthesis/spim_top.synthesis_optimized.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/results/synthesis/spim_top.synthesis_preroute.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/results/synthesis/spim_top.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/results/synthesis/spim_top.synthesis_cts.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/results/routing/spim_top.def.ref
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/results/routing/spim_top.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/results/magic/.magicrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/results/magic/spim_top.gds.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/results/lvs/spim_top.lvs.powered.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/results/lvs/spim_top.lvs.lef.json
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/spi_master/runs/spi_master/results/klayout/spim_top.lyp
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/spef/wb_host.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/spef/sdrc_top.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/spef/wb_interconnect.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/spef/scr1_top_wb.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/spef/glbl_cfg.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/spef/uart_core.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/spef/clk_skew_adjust.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/spef/yifive.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/spef/spim_top.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/magic_spice.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/synthesis/yosys.pg_define.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/routing/20-fastroute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/routing/22-tritonRoute.param
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/routing/22-tritonRoute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/magic/clk_skew_adjust.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/magic/scr1_top_wb.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/magic/yifive.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/magic/uart_core.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/magic/wb_host.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/magic/spim_top.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/magic/wb_interconnect.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/magic/sdrc_top.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/magic/glbl_cfg.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/tmp/lvs/setup_file.lef.lvs
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/runtime_summary_report.rpt.parsable
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/runtime_summary_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/manufacturability_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/25-opensta_spef.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/2-opensta.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/2-opensta_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/15-opensta_post_openphysyn.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/3-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/25-opensta_spef_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/25-opensta_spef.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/15-opensta_post_openphysyn.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/25-opensta_spef.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/2-opensta_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/15-opensta_post_openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/2-opensta.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/3-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/25-opensta_spef_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/15-opensta_post_openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/2-opensta.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/15-opensta_post_openphysyn.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/3-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/3-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/routing/42-antenna.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/floorplan/4-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/floorplan/4-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/klayout/37-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/klayout/35-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/placement/13-openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/placement/13-openphysyn_allchecks.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/reports/placement/13-openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/results/synthesis/yifive.synthesis_preroute.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/results/synthesis/yifive.synthesis_optimized.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/results/synthesis/yifive.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/results/routing/yifive.def.ref
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/results/routing/yifive.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/results/magic/.magicrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/results/lvs/yifive.lvs.lef.json
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/results/lvs/yifive.lvs.powered.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/runs/yifive/results/klayout/yifive.lyp
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/netlist/uart.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/netlist/yifive.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/netlist/sdram.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/netlist/wb_host.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/netlist/wb_interconnect.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/netlist/clk_skew_adjust.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/netlist/user_project_wrapper.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/netlist/syntacore.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/netlist/glbl_cfg.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/yifive/netlist/spi_master.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/interactive.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/gen_pdn.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/pdn.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/tmp/synthesis/yosys.pg_define.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/tmp/routing/19-tritonRoute.param
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/tmp/routing/17-fastroute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/tmp/routing/19-tritonRoute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/2-opensta.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/2-opensta_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/3-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/12-opensta_post_openphysyn.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/12-opensta_post_openphysyn.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/2-opensta_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/2-opensta.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/12-opensta_post_openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/3-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/2-opensta.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/3-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/12-opensta_post_openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/12-opensta_post_openphysyn.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/3-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/floorplan/4-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/floorplan/4-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/placement/10-openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/placement/10-openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/reports/placement/10-openphysyn_allchecks.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/results/synthesis/user_project_wrapper.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/results/synthesis/user_project_wrapper.synthesis_preroute.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/results/synthesis/user_project_wrapper.synthesis_optimized.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/runs/user_project_wrapper/results/routing/user_project_wrapper.def.ref
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/netlist/uart.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/netlist/sdram.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/netlist/wb_host.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/netlist/wb_interconnect.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/netlist/clk_buf.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/netlist/clk_skew_adjust.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/netlist/user_project_wrapper.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/netlist/syntacore.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/netlist/glbl_cfg.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/user_project_wrapper/netlist/spi_master.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/unconstraints.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/config.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic_spice.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/opt.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/tracks_copy.info
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/sky130_fd_sc_hd__tt_025C_1v80.no_pg.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/synthesis/yosys.sdc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/routing/21-tritonRoute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/routing/17-fastroute.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/routing/21-tritonRoute.param
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/routing/18-fastroute_2.guide
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__conb_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__nor2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__and2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__a21oi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__fill_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__a32o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__or2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__clkbuf_16.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__decap_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__diode_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__nand2_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__a211o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__a21o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__buf_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__or3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__decap_12.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__a2bb2o_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__and4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__decap_3.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__o21ai_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__a22oi_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__dfrtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__dfxtp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__tapvpwrvgnd_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__fill_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__clkbuf_1.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__o32a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__decap_6.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__or4_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__a21bo_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sdrc_top.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__decap_8.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__inv_2.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__o21a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__o22a_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__and3_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/magic/sky130_fd_sc_hd__dfstp_4.ext
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/tmp/lvs/setup_file.lef.lvs
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/runtime_summary_report.rpt.parsable
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/runtime_summary_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/manufacturability_report.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/1-yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/24-opensta_spef.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/2-opensta.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/1-yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/2-opensta_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/11-opensta_post_openphysyn.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/11-opensta_post_openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/1-yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/24-opensta_spef.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/11-opensta_post_openphysyn.min_max.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/11-opensta_post_openphysyn.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/2-opensta_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/2-opensta.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/2-opensta.timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/24-opensta_spef_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/24-opensta_spef_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/11-opensta_post_openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/24-opensta_spef.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/synthesis/1-yosys_4.stat.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/routing/42-antenna.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/floorplan/3-verilog2def.die_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/floorplan/3-verilog2def.core_area.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/klayout/36-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/klayout/34-klayout.xor.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/klayout/40-klayout.magic.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/placement/9-openphysyn_allchecks.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/placement/9-openphysyn_tns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/placement/9-openphysyn_wns.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/reports/placement/9-openphysyn_violators.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/results/synthesis/sdrc_top.synthesis_optimized.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/results/synthesis/sdrc_top.synthesis_cts.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/results/synthesis/sdrc_top.synthesis.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/results/synthesis/sdrc_top.synthesis_preroute.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/results/routing/sdrc_top.spef
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/results/routing/sdrc_top.def.ref
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/results/magic/.magicrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/results/magic/sdrc_top.gds.lydrc
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/results/lvs/sdrc_top.lvs.powered.v
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/results/lvs/sdrc_top.lvs.lef.json
+/home/dinesha/workarea/opencore/git/yifive_r0/openlane/sdram/runs/sdram/results/klayout/sdrc_top.lyp
+/home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper.magic.drc.tcl
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/dv/user_spi/user_risc_boot.dump
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/dv/user_spi/user_spi.vvp
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/dv/model/s25fl256s.sv
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/dv/risc_boot/user_uart.dump
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/dv/risc_boot/risc_boot.vvp
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/dv/user_risc_boot/user_risc_boot.dump
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/dv/user_risc_boot/user_risc_boot.vvp
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/dv/user_uart/user_uart.dump
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/dv/user_uart/golden.gtkw
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/dv/user_uart/user_uart.vvp
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/dv/wb_port/run_verilog
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/rtl/syntacore/scr1/README.md
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/rtl/syntacore/scr1/src/aa
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/rtl/syntacore/scr1/synth/unconstraints.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/rtl/syntacore/scr1/synth/timing.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/rtl/syntacore/scr1/synth/tmp/trimmed.lib
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/rtl/syntacore/scr1/synth/tmp/synthesis/hierarchy.dot
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/rtl/syntacore/scr1/synth/reports/yosys_4.chk.rpt
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/rtl/syntacore/scr1/synth/reports/yosys_dff.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/rtl/syntacore/scr1/synth/reports/yosys_pre.stat
+/home/dinesha/workarea/opencore/git/yifive_r0/verilog/rtl/syntacore/scr1/synth/netlist/scr1_top_wb.gv
diff --git a/checks/user_project_wrapper.magic.drc b/checks/user_project_wrapper.magic.drc
new file mode 100644
index 0000000..ef51034
--- /dev/null
+++ b/checks/user_project_wrapper.magic.drc
@@ -0,0 +1,9 @@
+user_project_wrapper
+----------------------------------------
+All nwells must contain metal-connected N+ taps (nwell.4)
+----------------------------------------
+ 443.710 1740.610 445.470 1742.215
+----------------------------------------
+[INFO]: COUNT: 1
+[INFO]: Should be divided by 3 or 4
+
diff --git a/checks/user_project_wrapper.xor.gds.png b/checks/user_project_wrapper.xor.gds.png
new file mode 100644
index 0000000..cd63482
--- /dev/null
+++ b/checks/user_project_wrapper.xor.gds.png
Binary files differ
diff --git a/checks/user_project_wrapper.xor.xml b/checks/user_project_wrapper.xor.xml
new file mode 100644
index 0000000..ad44b6d
--- /dev/null
+++ b/checks/user_project_wrapper.xor.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<report-database>
+ <description>XOR /home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper_empty_erased.gds vs. /home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper_erased.gds</description>
+ <original-file/>
+ <generator>drc: script='/usr/local/bin/xor_checks/xor.drc'</generator>
+ <top-cell>user_project_wrapper</top-cell>
+ <tags>
+ </tags>
+ <categories>
+  <category>
+   <name>235/4</name>
+   <description>XOR results for layer 235/4 </description>
+   <categories>
+   </categories>
+  </category>
+  <category>
+   <name>69/20</name>
+   <description>XOR results for layer 69/20 </description>
+   <categories>
+   </categories>
+  </category>
+  <category>
+   <name>70/20</name>
+   <description>XOR results for layer 70/20 </description>
+   <categories>
+   </categories>
+  </category>
+  <category>
+   <name>71/20</name>
+   <description>XOR results for layer 71/20 </description>
+   <categories>
+   </categories>
+  </category>
+  <category>
+   <name>71/44</name>
+   <description>XOR results for layer 71/44 </description>
+   <categories>
+   </categories>
+  </category>
+  <category>
+   <name>72/20</name>
+   <description>XOR results for layer 72/20 </description>
+   <categories>
+   </categories>
+  </category>
+  <category>
+   <name>81/14</name>
+   <description>XOR results for layer 81/14 </description>
+   <categories>
+   </categories>
+  </category>
+ </categories>
+ <cells>
+  <cell>
+   <name>user_project_wrapper</name>
+   <variant/>
+   <references>
+   </references>
+  </cell>
+ </cells>
+ <items>
+ </items>
+</report-database>
diff --git a/checks/xor.log b/checks/xor.log
new file mode 100644
index 0000000..833cc24
--- /dev/null
+++ b/checks/xor.log
@@ -0,0 +1,68 @@
+First Layout: /home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper_empty_erased.gds
+Second Layout: /home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper_erased.gds
+Design Name: xor_target
+Output GDS will be: /home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper.xor.gds
+Reading /home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper_empty_erased.gds ..
+Reading /home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper_erased.gds ..
+--- Running XOR for 69/20 ---
+"_input" in: xor.drc:38
+Elapsed: 0.010s
+"_input" in: xor.drc:38
+Elapsed: 0.010s
+"^" in: xor.drc:38
+Elapsed: 0.000s
+XOR differences: 0
+"_output" in: xor.drc:41
+Elapsed: 0.010s
+--- Running XOR for 70/20 ---
+"_input" in: xor.drc:38
+Elapsed: 0.010s
+"_input" in: xor.drc:38
+Elapsed: 0.000s
+"^" in: xor.drc:38
+Elapsed: 0.010s
+XOR differences: 0
+"_output" in: xor.drc:41
+Elapsed: 0.000s
+--- Running XOR for 71/20 ---
+"_input" in: xor.drc:38
+Elapsed: 0.010s
+"_input" in: xor.drc:38
+Elapsed: 0.000s
+"^" in: xor.drc:38
+Elapsed: 0.010s
+XOR differences: 358
+"_output" in: xor.drc:41
+Elapsed: 0.010s
+--- Running XOR for 71/44 ---
+"_input" in: xor.drc:38
+Elapsed: 0.000s
+"_input" in: xor.drc:38
+Elapsed: 0.010s
+"^" in: xor.drc:38
+Elapsed: 0.010s
+XOR differences: 1144
+"_output" in: xor.drc:41
+Elapsed: 0.000s
+--- Running XOR for 72/20 ---
+"_input" in: xor.drc:38
+Elapsed: 0.010s
+"_input" in: xor.drc:38
+Elapsed: 0.000s
+"^" in: xor.drc:38
+Elapsed: 0.010s
+XOR differences: 984
+"_output" in: xor.drc:41
+Elapsed: 0.010s
+--- Running XOR for 81/14 ---
+"_input" in: xor.drc:38
+Elapsed: 0.010s
+"_input" in: xor.drc:38
+Elapsed: 0.000s
+"^" in: xor.drc:38
+Elapsed: 0.010s
+XOR differences: 2
+"_output" in: xor.drc:41
+Elapsed: 0.000s
+Writing layout file: /home/dinesha/workarea/opencore/git/yifive_r0/checks/user_project_wrapper.xor.gds ..
+Total run time: 0.160s
diff --git a/checks/xor_total.txt b/checks/xor_total.txt
new file mode 100644
index 0000000..a8b880e
--- /dev/null
+++ b/checks/xor_total.txt
@@ -0,0 +1 @@
+Total XOR differences = 2488
\ No newline at end of file
diff --git a/docs/source/_static/RiscDunio-PinMapping.png b/docs/source/_static/RiscDunio-PinMapping.png
new file mode 100644
index 0000000..04ff440
--- /dev/null
+++ b/docs/source/_static/RiscDunio-PinMapping.png
Binary files differ
diff --git a/docs/source/_static/Riscduino_Soc.png b/docs/source/_static/Riscduino_Soc.png
new file mode 100644
index 0000000..cf6c825
--- /dev/null
+++ b/docs/source/_static/Riscduino_Soc.png
Binary files differ
diff --git a/docs/source/_static/sdram_controller.jpg b/docs/source/_static/sdram_controller.jpg
new file mode 100644
index 0000000..5c0cb82
--- /dev/null
+++ b/docs/source/_static/sdram_controller.jpg
Binary files differ
diff --git a/docs/source/_static/syntacore_blockdiagram.svg b/docs/source/_static/syntacore_blockdiagram.svg
new file mode 100644
index 0000000..ae606a4
--- /dev/null
+++ b/docs/source/_static/syntacore_blockdiagram.svg
@@ -0,0 +1,619 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Создано Microsoft Visio, экспорт SVG scr1_cluster.svg scr1_cluster -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"
+		xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="5.73958in" height="5.11458in"
+		viewBox="0 0 413.25 368.25" xml:space="preserve" color-interpolation-filters="sRGB" class="st12">
+	<v:documentProperties v:langID="2057" v:viewMarkup="false"/>
+
+	<style type="text/css">
+	<![CDATA[
+		.st1 {fill:#dcedfa;stroke:#243740;stroke-linecap:butt;stroke-width:0.75}
+		.st2 {fill:#b1ddf0;stroke:#243740;stroke-linecap:butt;stroke-width:0.75}
+		.st3 {fill:#b0e3e6;stroke:#243740;stroke-linecap:butt;stroke-width:0.75}
+		.st4 {fill:none}
+		.st5 {stroke:#243740;stroke-linecap:butt;stroke-width:1.5}
+		.st6 {fill:#243740;stroke:#243740;stroke-linecap:butt;stroke-width:1.5}
+		.st7 {fill:none;stroke:none;stroke-linecap:butt;stroke-width:0.75}
+		.st8 {fill:#243740;font-family:Calibri;font-size:0.75em;font-weight:bold}
+		.st9 {fill:#243740;font-family:Calibri;font-size:0.833336em;font-weight:bold}
+		.st10 {fill:#0c0c0c;font-family:Calibri;font-size:0.833336em;font-weight:bold}
+		.st11 {font-size:1em}
+		.st12 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}
+	]]>
+	</style>
+
+	<g v:mID="0" v:index="1" v:groupContext="foregroundPage">
+		<title>scr1_cluster</title>
+		<v:pageProperties v:drawingScale="1" v:pageScale="1" v:drawingUnits="19" v:shadowOffsetX="9" v:shadowOffsetY="-9"/>
+		<g id="shape2-1" v:mID="2" v:groupContext="shape" transform="translate(60.375,-30.375)">
+			<title>Лист.2</title>
+			<path d="M0 356.55 A11.7003 11.7003 -180 0 0 11.7 368.25 L280.8 368.25 A11.7003 11.7003 -180 0 0 292.5 356.55 L292.5
+						 42.45 A11.7003 11.7003 -180 0 0 280.8 30.75 L11.7 30.75 A11.7003 11.7003 -180 0 0 0 42.45 L0 356.55 Z"
+					class="st1"/>
+		</g>
+		<g id="shape3-3" v:mID="3" v:groupContext="shape" transform="translate(67.875,-210.375)">
+			<title>Лист.3</title>
+			<path d="M0 362.85 A5.40013 5.40013 -180 0 0 5.4 368.25 L272.1 368.25 A5.40013 5.40013 -180 0 0 277.5 362.85 L277.5 238.65
+						 A5.40013 5.40013 -180 0 0 272.1 233.25 L5.4 233.25 A5.40013 5.40013 -180 0 0 0 238.65 L0 362.85 Z"
+					class="st2"/>
+		</g>
+		<g id="shape4-5" v:mID="4" v:groupContext="shape" transform="translate(75.375,-217.875)">
+			<title>Лист.4</title>
+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001
+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>
+		</g>
+		<g id="shape5-7" v:mID="5" v:groupContext="shape" transform="translate(142.875,-217.875)">
+			<title>Лист.5</title>
+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001
+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>
+		</g>
+		<g id="shape6-9" v:mID="6" v:groupContext="shape" transform="translate(210.375,-217.875)">
+			<title>Лист.6</title>
+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001
+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>
+		</g>
+		<g id="shape7-11" v:mID="7" v:groupContext="shape" transform="translate(277.875,-217.875)">
+			<title>Лист.7</title>
+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001
+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>
+		</g>
+		<g id="shape8-13" v:mID="8" v:groupContext="shape" transform="translate(142.875,-255.375)">
+			<title>Лист.8</title>
+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001
+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>
+		</g>
+		<g id="shape9-15" v:mID="9" v:groupContext="shape" transform="translate(75.375,-255.375)">
+			<title>Лист.9</title>
+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001
+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>
+		</g>
+		<g id="shape10-17" v:mID="10" v:groupContext="shape" transform="translate(210.375,-255.375)">
+			<title>Лист.10</title>
+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001
+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>
+		</g>
+		<g id="shape11-19" v:mID="11" v:groupContext="shape" transform="translate(52.305,-307.635)">
+			<title>Лист.11</title>
+			<path d="M16.14 368.01 L8.07 368.01 L8.07 368.23 L0 368.25 L16.14 368.01 Z" class="st4"/>
+			<path d="M16.14 368.01 L8.07 368.01 L8.07 368.23 L0 368.25" class="st5"/>
+		</g>
+		<g id="shape12-22" v:mID="12" v:groupContext="shape" transform="translate(68.445,-305.25)">
+			<title>Лист.12</title>
+			<path d="M5.25 365.62 L0 368.25 L0 363 L5.25 365.62 Z" class="st6"/>
+		</g>
+		<g id="shape13-24" v:mID="13" v:groupContext="shape" transform="translate(47.055,-305.01)">
+			<title>Лист.13</title>
+			<path d="M0 365.63 L5.24 363 L5.25 368.25 L0 365.63 Z" class="st6"/>
+		</g>
+		<g id="shape14-26" v:mID="14" v:groupContext="shape" transform="translate(75.375,-292.875)">
+			<title>Лист.14</title>
+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001
+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 -0 342.75 L0 363.75 Z" class="st3"/>
+		</g>
+		<g id="shape15-28" v:mID="15" v:groupContext="shape" transform="translate(277.875,-255.375)">
+			<title>Лист.15</title>
+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001
+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>
+		</g>
+		<g id="shape16-30" v:mID="16" v:groupContext="shape" transform="translate(142.875,-292.875)">
+			<title>Лист.16</title>
+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001
+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 -0 342.75 L0 363.75 Z" class="st3"/>
+		</g>
+		<g id="shape17-32" v:mID="17" v:groupContext="shape" transform="translate(344.805,-307.635)">
+			<title>Лист.17</title>
+			<path d="M0 368.01 L8.07 368.01 L8.07 368.23 L16.14 368.25 L0 368.01 Z" class="st4"/>
+			<path d="M0 368.01 L8.07 368.01 L8.07 368.23 L16.14 368.25" class="st5"/>
+		</g>
+		<g id="shape18-35" v:mID="18" v:groupContext="shape" transform="translate(339.555,-305.25)">
+			<title>Лист.18</title>
+			<path d="M0 365.62 L5.25 363 L5.25 368.25 L0 365.62 Z" class="st6"/>
+		</g>
+		<g id="shape19-37" v:mID="19" v:groupContext="shape" transform="translate(360.945,-305.01)">
+			<title>Лист.19</title>
+			<path d="M5.25 365.63 L0 368.25 L0.01 363 L5.25 365.63 Z" class="st6"/>
+		</g>
+		<g id="shape20-39" v:mID="20" v:groupContext="shape" transform="translate(277.875,-292.875)">
+			<title>Лист.20</title>
+			<path d="M-0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001
+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 -0 342.75 L0 363.75 Z" class="st3"/>
+		</g>
+		<g id="shape21-41" v:mID="21" v:groupContext="shape" transform="translate(210.375,-292.875)">
+			<title>Лист.21</title>
+			<path d="M-0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001
+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 -0 342.75 L0 363.75 Z" class="st3"/>
+		</g>
+		<g id="shape22-43" v:mID="22" v:groupContext="shape" transform="translate(150.375,-123.375)">
+			<title>Лист.22</title>
+			<path d="M0 360.37 A7.87518 7.87518 -180 0 0 7.87 368.25 L104.62 368.25 A7.87518 7.87518 -180 0 0 112.5 360.37 L112.5
+						 323.63 A7.87518 7.87518 -180 0 0 104.62 315.75 L7.87 315.75 A7.87518 7.87518 -180 0 0 0 323.63 L0 360.37
+						 Z" class="st2"/>
+		</g>
+		<g id="shape23-45" v:mID="23" v:groupContext="shape" transform="translate(195.375,-85.875)">
+			<title>Лист.23</title>
+			<path d="M-0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L63 368.25 A4.5001 4.5001 -180 0 0 67.5 363.75 L67.5 342.75 A4.5001
+						 4.5001 -180 0 0 63 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 -0 342.75 L0 363.75 Z" class="st2"/>
+		</g>
+		<g id="shape24-47" v:mID="24" v:groupContext="shape" transform="translate(120.375,-149.625)">
+			<title>Лист.24</title>
+			<path d="M0 359.43 L0 368.25 L23.07 368.25 L0 359.43 Z" class="st4"/>
+			<path d="M0 359.43 L0 368.25 L23.07 368.25" class="st5"/>
+		</g>
+		<g id="shape25-50" v:mID="25" v:groupContext="shape" transform="translate(117.75,-158.445)">
+			<title>Лист.25</title>
+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>
+		</g>
+		<g id="shape26-52" v:mID="26" v:groupContext="shape" transform="translate(143.445,-147)">
+			<title>Лист.26</title>
+			<path d="M5.25 365.63 L0 368.25 L0 363 L5.25 365.63 Z" class="st6"/>
+		</g>
+		<g id="shape27-54" v:mID="27" v:groupContext="shape" transform="translate(105.375,-202.305)">
+			<title>Лист.27</title>
+			<path d="M0 368.25 L0 359.61 L0 368.25 Z" class="st4"/>
+			<path d="M0 368.25 L0 359.61" class="st5"/>
+		</g>
+		<g id="shape28-57" v:mID="28" v:groupContext="shape" transform="translate(102.75,-197.055)">
+			<title>Лист.28</title>
+			<path d="M2.63 368.25 L0 363 L5.25 363 L2.63 368.25 Z" class="st6"/>
+		</g>
+		<g id="shape29-59" v:mID="29" v:groupContext="shape" transform="translate(102.75,-210.945)">
+			<title>Лист.29</title>
+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>
+		</g>
+		<g id="shape30-61" v:mID="30" v:groupContext="shape" transform="translate(75.375,-165.375)">
+			<title>Лист.30</title>
+			<path d="M0 368.25 L12 338.25 L48 338.25 L60 368.25 L0 368.25 Z" class="st2"/>
+		</g>
+		<g id="shape31-63" v:mID="31" v:groupContext="shape" transform="translate(269.805,-149.625)">
+			<title>Лист.31</title>
+			<path d="M23.07 359.43 L23.07 368.25 L0 368.25 L23.07 359.43 Z" class="st4"/>
+			<path d="M23.07 359.43 L23.07 368.25 L0 368.25" class="st5"/>
+		</g>
+		<g id="shape32-66" v:mID="32" v:groupContext="shape" transform="translate(290.25,-158.445)">
+			<title>Лист.32</title>
+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>
+		</g>
+		<g id="shape33-68" v:mID="33" v:groupContext="shape" transform="translate(264.555,-147)">
+			<title>Лист.33</title>
+			<path d="M0 365.63 L5.25 363 L5.25 368.25 L0 365.63 Z" class="st6"/>
+		</g>
+		<g id="shape34-70" v:mID="34" v:groupContext="shape" transform="translate(277.875,-165.375)">
+			<title>Лист.34</title>
+			<path d="M0 368.25 L12 338.25 L48 338.25 L60 368.25 L0 368.25 Z" class="st2"/>
+		</g>
+		<g id="shape35-72" v:mID="35" v:groupContext="shape" transform="translate(307.875,-202.305)">
+			<title>Лист.35</title>
+			<path d="M0 359.61 L0 368.25 L0 359.61 Z" class="st4"/>
+			<path d="M0 359.61 L0 368.25" class="st5"/>
+		</g>
+		<g id="shape36-75" v:mID="36" v:groupContext="shape" transform="translate(305.25,-210.945)">
+			<title>Лист.36</title>
+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>
+		</g>
+		<g id="shape37-77" v:mID="37" v:groupContext="shape" transform="translate(305.25,-197.055)">
+			<title>Лист.37</title>
+			<path d="M2.63 368.25 L0 363 L5.25 363 L2.63 368.25 Z" class="st6"/>
+		</g>
+		<g id="shape38-79" v:mID="38" v:groupContext="shape" transform="translate(269.805,-100.875)">
+			<title>Лист.38</title>
+			<path d="M0 368.25 L38.07 368.25 L38.07 310.68 L0 368.25 Z" class="st4"/>
+			<path d="M0 368.25 L38.07 368.25 L38.07 310.68" class="st5"/>
+		</g>
+		<g id="shape39-82" v:mID="39" v:groupContext="shape" transform="translate(264.555,-98.25)">
+			<title>Лист.39</title>
+			<path d="M0 365.62 L5.25 363 L5.25 368.25 L0 365.62 Z" class="st6"/>
+		</g>
+		<g id="shape40-84" v:mID="40" v:groupContext="shape" transform="translate(305.25,-158.445)">
+			<title>Лист.40</title>
+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>
+		</g>
+		<g id="shape41-86" v:mID="41" v:groupContext="shape" transform="translate(90.375,-89.805)">
+			<title>Лист.41</title>
+			<path d="M0 368.25 L0 299.61 L0 368.25 Z" class="st4"/>
+			<path d="M0 368.25 L0 299.61" class="st5"/>
+		</g>
+		<g id="shape42-89" v:mID="42" v:groupContext="shape" transform="translate(87.75,-84.555)">
+			<title>Лист.42</title>
+			<path d="M2.63 368.25 L0 363 L5.25 363 L2.63 368.25 Z" class="st6"/>
+		</g>
+		<g id="shape43-91" v:mID="43" v:groupContext="shape" transform="translate(87.75,-158.445)">
+			<title>Лист.43</title>
+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>
+		</g>
+		<g id="shape44-93" v:mID="44" v:groupContext="shape" transform="translate(75.375,-45.375)">
+			<title>Лист.44</title>
+			<path d="M0 362.62 A5.62513 5.62513 -180 0 0 5.63 368.25 L54.38 368.25 A5.62513 5.62513 -180 0 0 60 362.62 L60 336.38
+						 A5.62513 5.62513 -180 0 0 54.38 330.75 L5.62 330.75 A5.62513 5.62513 -180 0 0 0 336.38 L0 362.62 Z"
+					class="st2"/>
+		</g>
+		<g id="shape45-95" v:mID="45" v:groupContext="shape" transform="translate(277.875,-45.375)">
+			<title>Лист.45</title>
+			<path d="M0 362.62 A5.62513 5.62513 -180 0 0 5.63 368.25 L54.38 368.25 A5.62513 5.62513 -180 0 0 60 362.62 L60 336.38
+						 A5.62513 5.62513 -180 0 0 54.38 330.75 L5.62 330.75 A5.62513 5.62513 -180 0 0 0 336.38 L0 362.62 Z"
+					class="st2"/>
+		</g>
+		<g id="shape46-97" v:mID="46" v:groupContext="shape" transform="translate(322.875,-89.805)">
+			<title>Лист.46</title>
+			<path d="M0 299.61 L0 368.25 L0 299.61 Z" class="st4"/>
+			<path d="M0 299.61 L0 368.25" class="st5"/>
+		</g>
+		<g id="shape47-100" v:mID="47" v:groupContext="shape" transform="translate(320.25,-158.445)">
+			<title>Лист.47</title>
+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>
+		</g>
+		<g id="shape48-102" v:mID="48" v:groupContext="shape" transform="translate(320.25,-84.555)">
+			<title>Лист.48</title>
+			<path d="M2.63 368.25 L0 363 L5.25 363 L2.63 368.25 Z" class="st6"/>
+		</g>
+		<g id="shape49-104" v:mID="49" v:groupContext="shape" transform="translate(367.875,-300.375)">
+			<title>Лист.49</title>
+			<rect x="0" y="353.25" width="45" height="15" class="st7"/>
+		</g>
+		<g id="shape50-106" v:mID="50" v:groupContext="shape" transform="translate(354.35,-302.925)">
+			<title>Лист.50</title>
+			<desc>JTAG I/F</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="36.025" cy="362.85" width="72.06" height="10.8"/>
+			<rect x="0" y="357.45" width="72.05" height="10.8" class="st7"/>
+			<text x="20.5" y="365.55" class="st8" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>JTAG I/F</text>		</g>
+		<g id="shape51-109" v:mID="51" v:groupContext="shape" transform="translate(0.375,-300.375)">
+			<title>Лист.51</title>
+			<rect x="0" y="353.25" width="45" height="15" class="st7"/>
+		</g>
+		<g id="shape52-111" v:mID="52" v:groupContext="shape" transform="translate(-8.65,-302.925)">
+			<title>Лист.52</title>
+			<desc>IRQ I/F</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="31.525" cy="362.85" width="63.05" height="10.8"/>
+			<rect x="0" y="357.45" width="63.05" height="10.8" class="st7"/>
+			<text x="18.49" y="365.55" class="st8" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>IRQ I/F</text>		</g>
+		<g id="shape53-114" v:mID="53" v:groupContext="shape" transform="translate(67.875,-0.375)">
+			<title>Лист.53</title>
+			<rect x="0" y="353.25" width="75" height="15" class="st7"/>
+		</g>
+		<g id="shape54-116" v:mID="54" v:groupContext="shape" transform="translate(55.85,-2.925)">
+			<title>Лист.54</title>
+			<desc>AHB/AXI I/F</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="49.525" cy="362.85" width="99.05" height="10.8"/>
+			<rect x="0" y="357.45" width="99.05" height="10.8" class="st7"/>
+			<text x="24.37" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>AHB/AXI I/F</text>		</g>
+		<g id="shape55-119" v:mID="55" v:groupContext="shape" transform="translate(105.375,-22.305)">
+			<title>Лист.55</title>
+			<path d="M0 352.11 L0 368.25 L0 352.11 Z" class="st4"/>
+			<path d="M0 352.11 L0 368.25" class="st5"/>
+		</g>
+		<g id="shape56-122" v:mID="56" v:groupContext="shape" transform="translate(102.75,-38.445)">
+			<title>Лист.56</title>
+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>
+		</g>
+		<g id="shape57-124" v:mID="57" v:groupContext="shape" transform="translate(102.75,-17.055)">
+			<title>Лист.57</title>
+			<path d="M2.63 368.25 L0 363 L5.25 363 L2.63 368.25 Z" class="st6"/>
+		</g>
+		<g id="shape58-126" v:mID="58" v:groupContext="shape" transform="translate(270.375,-0.375)">
+			<title>Лист.58</title>
+			<rect x="0" y="353.25" width="75" height="15" class="st7"/>
+		</g>
+		<g id="shape59-128" v:mID="59" v:groupContext="shape" transform="translate(258.35,-2.925)">
+			<title>Лист.59</title>
+			<desc>AHB/AXI I/F</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="49.525" cy="362.85" width="99.06" height="10.8"/>
+			<rect x="0" y="357.45" width="99.05" height="10.8" class="st7"/>
+			<text x="24.37" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>AHB/AXI I/F</text>		</g>
+		<g id="shape60-131" v:mID="60" v:groupContext="shape" transform="translate(307.875,-22.305)">
+			<title>Лист.60</title>
+			<path d="M0 352.11 L0 368.25 L0 352.11 Z" class="st4"/>
+			<path d="M0 352.11 L0 368.25" class="st5"/>
+		</g>
+		<g id="shape61-134" v:mID="61" v:groupContext="shape" transform="translate(305.25,-38.445)">
+			<title>Лист.61</title>
+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>
+		</g>
+		<g id="shape62-136" v:mID="62" v:groupContext="shape" transform="translate(305.25,-17.055)">
+			<title>Лист.62</title>
+			<path d="M2.63 368.25 L0 363 L5.25 363 L2.63 368.25 Z" class="st6"/>
+		</g>
+		<g id="shape63-138" v:mID="63" v:groupContext="shape" transform="translate(67.875,-349.125)">
+			<title>Лист.63</title>
+			<rect x="0" y="353.25" width="82.5" height="15" class="st7"/>
+		</g>
+		<g id="shape64-140" v:mID="64" v:groupContext="shape" transform="translate(82.675,-351.45)">
+			<title>Лист.64</title>
+			<desc>SCR1 cluster</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="43.325" cy="362.85" width="86.65" height="10.8"/>
+			<rect x="0" y="357.45" width="86.65" height="10.8" class="st7"/>
+			<text x="0" y="365.85" class="st10" v:langID="2057"><v:paragraph/><v:tabList/>SCR1 cluster</text>		</g>
+		<g id="shape65-143" v:mID="65" v:groupContext="shape" transform="translate(75.375,-326.625)">
+			<title>Лист.65</title>
+			<rect x="0" y="353.25" width="75" height="15" class="st7"/>
+		</g>
+		<g id="shape66-145" v:mID="66" v:groupContext="shape" transform="translate(76.85,-329.175)">
+			<title>Лист.66</title>
+			<desc>SCR1 core</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>
+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>
+			<text x="0" y="365.85" class="st10" v:langID="2057"><v:paragraph/><v:tabList/>SCR1 core</text>		</g>
+		<g id="shape67-148" v:mID="67" v:groupContext="shape" transform="translate(90.375,-300.375)">
+			<title>Лист.67</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape68-150" v:mID="68" v:groupContext="shape" transform="translate(64.125,-301.95)">
+			<title>Лист.68</title>
+			<desc>Interrupt Controller</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="40.525" cy="362.85" width="81.05" height="10.8"/>
+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>
+			<text x="23.5" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Interrupt <v:lf/><tspan
+						x="21.65" dy="1.2em" class="st11">Controller</tspan></text>		</g>
+		<g id="shape69-154" v:mID="69" v:groupContext="shape" transform="translate(157.875,-300.375)">
+			<title>Лист.69</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape70-156" v:mID="70" v:groupContext="shape" transform="translate(132.35,-302.925)">
+			<title>Лист.70</title>
+			<desc>System Control Unit</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>
+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>
+			<text x="26.99" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>System <v:lf/><tspan
+						x="17.59" dy="1.2em" class="st11">Control Unit</tspan></text>		</g>
+		<g id="shape71-160" v:mID="71" v:groupContext="shape" transform="translate(225.375,-300.375)">
+			<title>Лист.71</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape72-162" v:mID="72" v:groupContext="shape" transform="translate(204.35,-302.925)">
+			<title>Лист.72</title>
+			<desc>Debug Module</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="36.025" cy="362.85" width="72.06" height="10.8"/>
+			<rect x="0" y="357.45" width="72.05" height="10.8" class="st7"/>
+			<text x="23.96" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Debug <v:lf/><tspan
+						x="21.47" dy="1.2em" class="st11">Module</tspan></text>		</g>
+		<g id="shape73-166" v:mID="73" v:groupContext="shape" transform="translate(292.875,-300.375)">
+			<title>Лист.73</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape74-168" v:mID="74" v:groupContext="shape" transform="translate(267.35,-302.925)">
+			<title>Лист.74</title>
+			<desc>TAP Controller</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>
+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>
+			<text x="33.18" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>TAP<v:lf/><tspan
+						x="21.65" dy="1.2em" class="st11">Controller</tspan></text>		</g>
+		<g id="shape75-172" v:mID="75" v:groupContext="shape" transform="translate(90.375,-262.875)">
+			<title>Лист.75</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape76-174" v:mID="76" v:groupContext="shape" transform="translate(64.85,-265.425)">
+			<title>Лист.76</title>
+			<desc>Control-Status Register File</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="40.525" cy="362.85" width="81.05" height="10.8"/>
+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>
+			<text x="13.57" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Control-Status <v:lf/><tspan
+						x="17.71" dy="1.2em" class="st11">Register File</tspan></text>		</g>
+		<g id="shape77-178" v:mID="77" v:groupContext="shape" transform="translate(191.625,-142.125)">
+			<title>Лист.77</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape78-180" v:mID="78" v:groupContext="shape" transform="translate(162,-144)">
+			<title>Лист.78</title>
+			<desc>Tightly-Coupled Memory</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="45" cy="362.85" width="90" height="10.8"/>
+			<rect x="0" y="357.45" width="90" height="10.8" class="st7"/>
+			<text x="12.25" y="359.85" class="st9" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Tightly-Coupled <tspan
+						x="27.21" dy="1.2em" class="st11">Memory</tspan></text>		</g>
+		<g id="shape79-184" v:mID="79" v:groupContext="shape" transform="translate(214.125,-93.375)">
+			<title>Лист.79</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape80-186" v:mID="80" v:groupContext="shape" transform="translate(206.6,-95.925)">
+			<title>Лист.80</title>
+			<desc>Timer</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="22.525" cy="362.85" width="45.05" height="10.8"/>
+			<rect x="0" y="357.45" width="45.05" height="10.8" class="st7"/>
+			<text x="10.46" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>Timer</text>		</g>
+		<g id="shape81-189" v:mID="81" v:groupContext="shape" transform="translate(157.875,-225.375)">
+			<title>Лист.81</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape82-191" v:mID="82" v:groupContext="shape" transform="translate(132.35,-227.925)">
+			<title>Лист.82</title>
+			<desc>Instruction Decode Unit</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>
+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>
+			<text x="20.16" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Instruction <v:lf/><tspan
+						x="17.41" dy="1.2em" class="st11">Decode Unit</tspan></text>		</g>
+		<g id="shape83-195" v:mID="83" v:groupContext="shape" transform="translate(225.375,-225.375)">
+			<title>Лист.83</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape84-197" v:mID="84" v:groupContext="shape" transform="translate(199.85,-227.925)">
+			<title>Лист.84</title>
+			<desc>Execution Unit</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>
+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>
+			<text x="22.2" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Execution <v:lf/><tspan
+						x="32.51" dy="1.2em" class="st11">Unit</tspan></text>		</g>
+		<g id="shape85-201" v:mID="85" v:groupContext="shape" transform="translate(292.875,-225.375)">
+			<title>Лист.85</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape86-203" v:mID="86" v:groupContext="shape" transform="translate(267.35,-227.925)">
+			<title>Лист.86</title>
+			<desc>Load-Store Unit</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>
+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>
+			<text x="20.22" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Load-Store <v:lf/><tspan
+						x="32.51" dy="1.2em" class="st11">Unit</tspan></text>		</g>
+		<g id="shape87-207" v:mID="87" v:groupContext="shape" transform="translate(225.375,-262.875)">
+			<title>Лист.87</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape88-209" v:mID="88" v:groupContext="shape" transform="translate(199.85,-265.425)">
+			<title>Лист.88</title>
+			<desc>Trigger Debug Unit</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>
+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>
+			<text x="27.46" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Trigger <v:lf/><tspan
+						x="19.42" dy="1.2em" class="st11">Debug Unit</tspan></text>		</g>
+		<g id="shape89-213" v:mID="89" v:groupContext="shape" transform="translate(90.375,-67.875)">
+			<title>Лист.89</title>
+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>
+		</g>
+		<g id="shape90-215" v:mID="90" v:groupContext="shape" transform="translate(87.35,-66.675)">
+			<title>Лист.90</title>
+			<desc>IMEM</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="18.025" cy="362.85" width="36.05" height="10.8"/>
+			<rect x="0" y="357.45" width="36.05" height="10.8" class="st7"/>
+			<text x="5.51" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>IMEM</text>		</g>
+		<g id="shape91-218" v:mID="91" v:groupContext="shape" transform="translate(90.375,-58.875)">
+			<title>Лист.91</title>
+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>
+		</g>
+		<g id="shape92-220" v:mID="92" v:groupContext="shape" transform="translate(73.85,-57.675)">
+			<title>Лист.92</title>
+			<desc>AHB/AXI</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="31.525" cy="362.85" width="63.05" height="10.8"/>
+			<rect x="0" y="357.45" width="63.05" height="10.8" class="st7"/>
+			<text x="13.27" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>AHB/AXI</text>		</g>
+		<g id="shape93-223" v:mID="93" v:groupContext="shape" transform="translate(90.375,-49.875)">
+			<title>Лист.93</title>
+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>
+		</g>
+		<g id="shape94-225" v:mID="94" v:groupContext="shape" transform="translate(78.35,-48.675)">
+			<title>Лист.94</title>
+			<desc>bridge</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="27.025" cy="362.85" width="54.05" height="10.8"/>
+			<rect x="0" y="357.45" width="54.05" height="10.8" class="st7"/>
+			<text x="13.77" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>bridge</text>		</g>
+		<g id="shape95-228" v:mID="95" v:groupContext="shape" transform="translate(292.875,-67.875)">
+			<title>Лист.95</title>
+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>
+		</g>
+		<g id="shape96-230" v:mID="96" v:groupContext="shape" transform="translate(289.85,-66.675)">
+			<title>Лист.96</title>
+			<desc>DMEM</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="18.025" cy="362.85" width="36.05" height="10.8"/>
+			<rect x="0" y="357.45" width="36.05" height="10.8" class="st7"/>
+			<text x="3.69" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>DMEM</text>		</g>
+		<g id="shape97-233" v:mID="97" v:groupContext="shape" transform="translate(292.875,-58.875)">
+			<title>Лист.97</title>
+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>
+		</g>
+		<g id="shape98-235" v:mID="98" v:groupContext="shape" transform="translate(276.35,-57.675)">
+			<title>Лист.98</title>
+			<desc>AHB/AXI</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="31.525" cy="362.85" width="63.05" height="10.8"/>
+			<rect x="0" y="357.45" width="63.05" height="10.8" class="st7"/>
+			<text x="13.27" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>AHB/AXI</text>		</g>
+		<g id="shape99-238" v:mID="99" v:groupContext="shape" transform="translate(292.875,-49.875)">
+			<title>Лист.99</title>
+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>
+		</g>
+		<g id="shape100-240" v:mID="100" v:groupContext="shape" transform="translate(280.85,-48.675)">
+			<title>Лист.100</title>
+			<desc>bridge</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="27.025" cy="362.85" width="54.05" height="10.8"/>
+			<rect x="0" y="357.45" width="54.05" height="10.8" class="st7"/>
+			<text x="13.77" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>bridge</text>		</g>
+		<g id="shape101-243" v:mID="101" v:groupContext="shape" transform="translate(90.375,-180.375)">
+			<title>Лист.101</title>
+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>
+		</g>
+		<g id="shape102-245" v:mID="102" v:groupContext="shape" transform="translate(87.35,-179.175)">
+			<title>Лист.102</title>
+			<desc>IMEM</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="18.025" cy="362.85" width="36.05" height="10.8"/>
+			<rect x="0" y="357.45" width="36.05" height="10.8" class="st7"/>
+			<text x="5.51" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>IMEM</text>		</g>
+		<g id="shape103-248" v:mID="103" v:groupContext="shape" transform="translate(90.375,-171.375)">
+			<title>Лист.103</title>
+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>
+		</g>
+		<g id="shape104-250" v:mID="104" v:groupContext="shape" transform="translate(78.35,-170.175)">
+			<title>Лист.104</title>
+			<desc>router</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="27.025" cy="362.85" width="54.05" height="10.8"/>
+			<rect x="0" y="357.45" width="54.05" height="10.8" class="st7"/>
+			<text x="13.85" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>router</text>		</g>
+		<g id="shape105-253" v:mID="105" v:groupContext="shape" transform="translate(292.875,-180.375)">
+			<title>Лист.105</title>
+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>
+		</g>
+		<g id="shape106-255" v:mID="106" v:groupContext="shape" transform="translate(289.85,-179.175)">
+			<title>Лист.106</title>
+			<desc>DMEM</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="18.025" cy="362.85" width="36.05" height="10.8"/>
+			<rect x="0" y="357.45" width="36.05" height="10.8" class="st7"/>
+			<text x="3.69" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>DMEM</text>		</g>
+		<g id="shape107-258" v:mID="107" v:groupContext="shape" transform="translate(292.875,-171.375)">
+			<title>Лист.107</title>
+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>
+		</g>
+		<g id="shape108-260" v:mID="108" v:groupContext="shape" transform="translate(280.85,-170.175)">
+			<title>Лист.108</title>
+			<desc>router</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="27.025" cy="362.85" width="54.05" height="10.8"/>
+			<rect x="0" y="357.45" width="54.05" height="10.8" class="st7"/>
+			<text x="13.85" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>router</text>		</g>
+		<g id="shape109-263" v:mID="109" v:groupContext="shape" transform="translate(157.875,-262.875)">
+			<title>Лист.109</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape110-265" v:mID="110" v:groupContext="shape" transform="translate(132.35,-265.425)">
+			<title>Лист.110</title>
+			<desc>Multi-Port Register File</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>
+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>
+			<text x="21.06" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Multi-Port <v:lf/><tspan
+						x="17.71" dy="1.2em" class="st11">Register File</tspan></text>		</g>
+		<g id="shape111-269" v:mID="111" v:groupContext="shape" transform="translate(292.875,-262.875)">
+			<title>Лист.111</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape112-271" v:mID="112" v:groupContext="shape" transform="translate(267.35,-265.425)">
+			<title>Лист.112</title>
+			<desc>Hart Debug Unit</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>
+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>
+			<text x="32.31" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Hart <v:lf/><tspan
+						x="19.42" dy="1.2em" class="st11">Debug Unit</tspan></text>		</g>
+		<g id="shape113-275" v:mID="113" v:groupContext="shape" transform="translate(90.375,-225.375)">
+			<title>Лист.113</title>
+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>
+		</g>
+		<g id="shape114-277" v:mID="114" v:groupContext="shape" transform="translate(64.85,-227.925)">
+			<title>Лист.114</title>
+			<desc>Instruction Fetch Unit</desc>
+			<v:textBlock v:margins="rect(0,0,0,0)"/>
+			<v:textRect cx="40.525" cy="362.85" width="81.05" height="10.8"/>
+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>
+			<text x="20.16" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Instruction<v:newlineChar/><tspan
+						x="21.3" dy="1.2em" class="st11">Fetch Unit</tspan></text>		</g>
+	</g>
+</svg>
diff --git a/docs/source/_static/user_project_wrapper.gds.png b/docs/source/_static/user_project_wrapper.gds.png
new file mode 100644
index 0000000..0f3df5d
--- /dev/null
+++ b/docs/source/_static/user_project_wrapper.gds.png
Binary files differ
diff --git a/hacks/patch/pdngen.patch b/hacks/patch/pdngen.patch
new file mode 100644
index 0000000..8d44ec8
--- /dev/null
+++ b/hacks/patch/pdngen.patch
@@ -0,0 +1,27 @@
+diff --git a/src/pdn/src/PdnGen.tcl b/src/pdn/src/PdnGen.tcl
+index 7322d54ad..7f178167f 100644
+--- a/src/pdn/src/PdnGen.tcl
++++ b/src/pdn/src/PdnGen.tcl
+@@ -966,8 +966,9 @@ proc add_pdn_ring {args} {
+ 
+   if {[dict exists $args -grid]} {
+     set current_grid [check_grid [get_grid [dict get $args -grid]]]
++    #Dinesh-A: Core Ring without Strap
++    set grid $current_grid
+   }
+-  set grid $current_grid
+   set layers [check_layer_names [dict get $args -layers]]
+ 
+   set process_args $args
+@@ -6686,7 +6687,10 @@ proc plan_grid {} {
+   }
+ 
+   add_grid
+-  process_channels
++  #Dinesh-A: Core Ring without Strap
++  if {[info exists $grid_data]} {
++  	process_channels
++  }
+ 
+   foreach pwr_net [dict get $design_data power_nets] {
+     generate_grid_vias "POWER" $pwr_net
diff --git a/hacks/patch/resizer.patch b/hacks/patch/resizer.patch
new file mode 100644
index 0000000..bf587c7
--- /dev/null
+++ b/hacks/patch/resizer.patch
@@ -0,0 +1,17 @@
+diff --git a/src/rsz/src/Resizer.cc b/src/rsz/src/Resizer.cc
+index 3cbe306e3..300c6c476 100644
+--- a/src/rsz/src/Resizer.cc
++++ b/src/rsz/src/Resizer.cc
+@@ -1691,9 +1691,11 @@ Resizer::resizeToTargetSlew(const Pin *drvr_pin,
+     ensureWireParasitic(drvr_pin);
+     // Includes net parasitic capacitance.
+     float load_cap = graph_delay_calc_->loadCap(drvr_pin, tgt_slew_dcalc_ap_);
+-    if (load_cap > 0.0) {
++    // DINESH-A: delay cells resize disabled
++    if (load_cap > 0.00 && (strncmp(cell->name(),"sky130_fd_sc_hd__clkdlybuf4s15_2",26) != 0)) {
+       LibertyCell *target_cell = findTargetCell(cell, load_cap, revisiting_inst);
+       if (target_cell != cell) {
++        //printf("Dinesh-A: Resizing : %s => %s %s Load_cap: %f \n",sdc_network_->pathName(drvr_pin),cell->name(),target_cell->name(),load_cap);
+         debugPrint(logger_, RSZ, "resize", 2, "{} {} -> {}",
+                    sdc_network_->pathName(drvr_pin),
+                    cell->name(),
diff --git a/hacks/patch/scan_swap.patch b/hacks/patch/scan_swap.patch
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/hacks/patch/scan_swap.patch
diff --git a/hacks/src/OpenROAD/PdnGen.tcl b/hacks/src/OpenROAD/PdnGen.tcl
new file mode 100644
index 0000000..7f17816
--- /dev/null
+++ b/hacks/src/OpenROAD/PdnGen.tcl
@@ -0,0 +1,6751 @@
+#BSD 3-Clause License
+#
+#Copyright (c) 2019, The Regents of the University of California
+#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 copyright holder nor the names of its
+#   contributors may be used to endorse or promote products derived from
+#   this software without specific prior written permission.
+#
+#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+#AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+#IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+
+sta::define_cmd_args "pdngen" {[-verbose] [config_file]}
+
+proc pdngen { args } {
+  sta::parse_key_args "pdngen" args \
+    keys {} flags {-verbose}
+
+  if {[info exists flags(-verbose)]} {
+    pdngen::set_verbose
+  }
+
+  if {[llength $args] > 0} {
+    set config_file [file nativename [lindex $args 0]]
+    pdngen::apply $config_file
+  } else {
+    pdngen::apply
+  }
+}
+
+sta::define_cmd_args "add_global_connection" {-net <net_name> \
+                                              -inst_pattern <inst_name_pattern> \ 
+                                              -pin_pattern <pin_name_pattern> \
+                                              [(-power|-ground)]}
+
+proc add_global_connection {args} {
+  if {[ord::get_db_block] == "NULL"} {
+    utl::error PDN 91 "Design must be loaded before calling the add_global_connection command."
+  }
+
+  sta::parse_key_args "add_global_connection" args \
+    keys {-net -inst_pattern -pin_pattern} \
+    flags {-power -ground}
+
+  if {[llength $args] > 0} {
+    utl::error PDN 131 "Unexpected argument [lindex $args 0] for add_global_connection command."
+  }
+
+  if {[info exists flags(-power)] && [info exists flags(-ground)]} {
+    utl::error PDN 92 "The flags -power and -ground of the add_global_connection command are mutually exclusive."
+  }
+
+  if {![info exists keys(-net)]} {
+    utl::error PDN 93 "The -net option of the add_global_connection command is required."
+  }
+
+  if {![info exists keys(-inst_pattern)]} {
+    set keys(-inst_pattern) {.*}
+  } else {
+    if {[catch {regexp $keys(-inst_pattern) ""}]} {
+      utl::error PDN 142 "The -inst_pattern argument ($keys(-inst_pattern)) is not a valid regular expression."
+    }
+  }
+
+  if {![info exists keys(-pin_pattern)]} { 
+    utl::error PDN 94 "The -pin_pattern option of the add_global_connection command is required."
+  } else {
+    if {[catch {regexp $keys(-pin_pattern) ""}]} {
+      utl::error PDN 157 "The -pin_pattern argument ($keys(-pin_pattern)) is not a valid regular expression."
+    }
+  }
+
+  if {[info exists flags(-power)]} {
+    if {[set net [[ord::get_db_block] findNet $keys(-net)]] == "NULL"} {
+      set net [odb::dbNet_create [ord::get_db_block] $keys(-net)]
+    }
+    $net setSpecial
+    $net setSigType POWER
+    pdngen::check_power $keys(-net)
+    pdngen::add_power_net $keys(-net)
+  }
+
+  if {[info exists flags(-ground)]} {
+    if {[set net [[ord::get_db_block] findNet $keys(-net)]] == "NULL"} {
+      set net [odb::dbNet_create [ord::get_db_block] $keys(-net)]
+    }
+    $net setSpecial
+    $net setSigType GROUND
+    pdngen::check_ground $keys(-net)
+    pdngen::add_ground_net $keys(-net)
+  }
+
+  dict lappend pdngen::global_connections $keys(-net) [list inst_name $keys(-inst_pattern) pin_name $keys(-pin_pattern)]
+
+  if {[set net [[ord::get_db_block] findNet $keys(-net)]] == "NULL"} {
+    utl::warn PDN 167 "Net created for $keys(-net), if intended as power or ground net add the -power/-ground switch as appropriate."
+    set net [odb::dbNet_create [ord::get_db_block] $keys(-net)]
+  }
+  pdn::add_global_connect $keys(-inst_pattern) $keys(-pin_pattern) $net
+  pdn::global_connect [ord::get_db_block]
+}
+
+# define_pdn_grid -name main_grid -pins {metal7} -voltage_domains {CORE VIN}
+# define_pdn_grid -macro -name ram -orient {R0 R180 MX MY} -starts_with POWER -pin_direction vertical -block metal6
+
+sta::define_cmd_args "define_pdn_grid" {[-name <name>] \
+                                        [-macro] \
+                                        [-grid_over_pg_pins|-grid_over_boundary] \
+                                        [-voltage_domains <list_of_voltage_domains>] \
+                                        [-orient <list_of_valid_orientations>] \
+                                        [-instances <list_of_instances>] \
+                                        [-cells <list_of_cell_names> ] \
+                                        [-halo <list_of_halo_values>] \
+                                        [-pin_direction (horizontal|vertical)] \
+                                        [-pins <list_of_pin_layers>] \
+                                        [-starts_with (POWER|GROUND)]}
+
+proc define_pdn_grid {args} {
+  pdngen::check_design_state
+
+  sta::parse_key_args "define_pdn_grid" args \
+    keys {-name -voltage_domains -orient -instances -cells -halo -pin_direction -pins -starts_with} \
+    flags {-macro -grid_over_pg_pins -grid_over_boundary}
+
+  if {[llength $args] > 0} {
+    utl::error PDN 132 "Unexpected argument [lindex $args 0] for define_pdn_grid command."
+  }
+
+  if {[info exists flags(-macro)]} {
+    set keys(-macro) 1
+
+    if {[info exists flags(-grid_over_pg_pins)] && [info exists flags(-grid_over_bounary)]} {
+      utl::error PDN 175 "Options -grid_over_pg_pins and -grid_over_boundary are mutually exclusive."
+    }
+
+    set keys(-grid_over_pg_pins) 1
+    if {[info exists flags(-grid_over_boundary)]} {
+      set keys(-grid_over_pg_pins) 0
+    }
+  }
+
+  if {[llength $args] > 0} {
+    utl::error PDN 73 "Unrecognized argument [lindex $args 0] for define_pdn_grid."
+  }
+
+  if {[info exists keys(-halo)]} {
+    if {[llength $keys(-halo)] == 1} {
+      set keys(-halo) [list $keys(-halo) $keys(-halo) $keys(-halo) $keys(-halo)]
+    } elseif {[llength $keys(-halo)] == 2} {
+      set keys(-halo) [list {*}$keys(-halo) {*}$keys(-halo)]
+    } elseif {[llength $keys(-halo)] != 4} {
+      utl::error PDN 163 "Argument -halo of define_pdn_grid must consist of 1, 2 or 4 entries."
+    }
+  }
+  pdngen::define_pdn_grid {*}[array get keys]
+}
+
+# set_voltage_domain -name CORE -power_net VDD  -ground_net VSS
+# set_voltage_domain -name VIN  -region_name TEMP_ANALOG -power_net VPWR -ground_net VSS
+
+sta::define_cmd_args "set_voltage_domain" {-name domain_name \
+                                           [-region region_name] \
+                                           -power power_net_name \
+                                           [-secondary_power secondary_power_net_name] \
+                                           -ground ground_net_name}
+
+proc set_voltage_domain {args} {
+  pdngen::check_design_state
+
+  sta::parse_key_args "set_voltage_domain" args \
+    keys {-name -region -power -secondary_power -ground}
+
+  if {[llength $args] > 0} {
+    utl::error PDN 133 "Unexpected argument [lindex $args 0] for set_voltage_domain command."
+  }
+
+  if {![info exists keys(-name)]} {
+    utl::error PDN 97 "The -name argument is required."
+  }
+
+  if {![info exists keys(-power)]} {
+    utl::error PDN 98 "The -power argument is required."
+  }
+
+  if {![info exists keys(-ground)]} {
+    utl::error PDN 99 "The -ground argument is required."
+  }
+
+  if {[llength $args] > 0} {
+    utl::error PDN 120 "Unrecognized argument [lindex $args 0] for set_voltage_domain."
+  }
+
+  pdngen::set_voltage_domain {*}[array get keys]
+}
+
+# add_pdn_stripe -grid main_grid -layer metal1 -width 0.17 -followpins
+# add_pdn_stripe -grid main_grid -layer metal2 -width 0.17 -followpins
+# add_pdn_stripe -grid main_grid -layer metal4 -width 0.48 -pitch 56.0 -offset 2 -starts_with POWER
+# add_pdn_stripe -grid main_grid -layer metal7 -width 1.40 -pitch 40.0 -offset 2 -starts_with POWER
+sta::define_cmd_args "add_pdn_stripe" {[-grid grid_name] \
+                                       -layer layer_name \
+                                       -width width_value \
+                                       [-followpins] \
+                                       [-extend_to_core_ring] \
+                                       [-pitch pitch_value] \
+                                       [-spacing spacing_value] \
+                                       [-offset offset_value] \
+                                       [-starts_width (POWER|GROUND)]}
+
+proc add_pdn_stripe {args} {
+  pdngen::check_design_state
+
+  sta::parse_key_args "add_pdn_stripe" args \
+    keys {-grid -layer -width -pitch -spacing -offset -starts_with} \
+    flags {-followpins -extend_to_core_ring}
+
+  if {[llength $args] > 0} {
+    utl::error PDN 134 "Unexpected argument [lindex $args 0] for add_pdn_stripe command."
+  }
+
+  if {![info exists keys(-layer)]} {
+    utl::error PDN 100 "The -layer argument is required."
+  }
+
+  if {![info exists keys(-width)]} {
+    utl::error PDN 101 "The -width argument is required."
+  }
+
+  if {![info exists flags(-followpins)] && ![info exists keys(-pitch)]} {
+    utl::error PDN 102 "The -pitch argument is required for non-followpins stripes."
+  }
+
+  if {[info exists flags(-followpins)]} {
+    set keys(stripe) rails
+  } else {
+    set keys(stripe) straps
+  }
+
+  if {[info exists flags(-extend_to_core_ring)]} {
+    set keys(-extend_to_core_ring) 1
+  }
+
+  pdngen::add_pdn_stripe {*}[array get keys]
+}
+
+# add_pdn_ring   -grid main_grid -layer metal6 -width 5.0 -spacing  3.0 -core_offset 5
+# add_pdn_ring   -grid main_grid -layer metal7 -width 5.0 -spacing  3.0 -core_offset 5
+
+sta::define_cmd_args "add_pdn_ring" {[-grid grid_name] \
+                                     -layers list_of_2_layer_names \
+                                     -widths (width_value|list_of_width_values) \
+                                     -spacings (spacing_value|list_of_spacing_values) \
+                                     [-core_offsets (offset_value|list_of_offset_values)] \
+                                     [-pad_offsets (offset_value|list_of_offset_values)] \
+                                     [-power_pads list_of_core_power_padcells] \
+                                     [-ground_pads list_of_core_ground_padcells]}
+
+proc add_pdn_ring {args} {
+  pdngen::check_design_state
+
+  sta::parse_key_args "add_pdn_ring" args \
+    keys {-grid -layers -widths -spacings -core_offsets -pad_offsets -power_pads -ground_pads} 
+
+  if {[llength $args] > 0} {
+    utl::error PDN 135 "Unexpected argument [lindex $args 0] for add_pdn_ring command."
+  }
+
+  if {![info exists keys(-layers)]} {
+    utl::error PDN 103 "The -layers argument is required."
+  }
+
+  if {[llength $keys(-layers)] != 2} {
+    utl::error PDN 137 "Expecting a list of 2 elements for -layers option of add_pdn_ring command, found [llength $keys(-layers)]."
+  }
+
+  if {![info exists keys(-widths)]} {
+    utl::error PDN 104 "The -widths argument is required."
+  }
+
+  if {![info exists keys(-spacings)]} {
+    utl::error PDN 105 "The -spacings argument is required."
+  }
+
+  if {[info exists keys(-core_offsets)] && [info exists keys(-pad_offsets)]} {
+    utl::error PDN 106 "Only one of -pad_offsets or -core_offsets can be specified."
+  }
+
+  if {![info exists keys(-core_offsets)] && ![info exists keys(-pad_offsets)]} {
+    utl::error PDN 107 "One of -pad_offsets or -core_offsets must be specified."
+  }
+
+  if {[info exists keys(-pad_offsets)]} {
+    if {![info exists keys(-power_pads)]} {
+      utl::error PDN 143 "The -power_pads option is required when the -pad_offsets option is used."
+    }
+
+    if {![info exists keys(-ground_pads)]} {
+      utl::error PDN 144 "The -ground_pads option is required when the -pad_offsets option is used."
+    }
+  } else {
+    if {[info exists keys(-power_pads)] || [info exists keys(-ground_pads)]} {
+      utl::warn PDN 145 "Options -power_pads and -ground_pads are only used when the -pad_offsets option is specified."
+    }
+  }
+
+  pdngen::add_pdn_ring {*}[array get keys]
+}
+
+sta::define_cmd_args "add_pdn_connect" {[-grid grid_name] \
+                                        -layers list_of_2_layers \
+                                        [-cut_pitch pitch_value] \
+                                        [-fixed_vias list_of_vias]}
+
+# add_pdn_connect -grid main_grid -layers {metal1 metal2} -cut_pitch 0.16
+# add_pdn_connect -grid main_grid -layers {metal2 metal4}
+# add_pdn_connect -grid main_grid -layers {metal4 metal7}
+
+proc add_pdn_connect {args} {
+  pdngen::check_design_state
+
+  sta::parse_key_args "add_pdn_connect" args \
+    keys {-grid -layers -cut_pitch -fixed_vias} \
+
+  if {[llength $args] > 0} {
+    utl::error PDN 136 "Unexpected argument [lindex $args 0] for add_pdn_connect command."
+  }
+
+  if {![info exists keys(-layers)]} {
+    utl::error PDN 108 "The -layers argument is required."
+  }
+
+  pdngen::add_pdn_connect {*}[array get keys]
+}
+
+namespace eval pdngen {
+variable block_masters {}
+variable logical_viarules {}
+variable physical_viarules {}
+variable vias {}
+variable stripe_locs
+variable layers {}
+variable block
+variable tech
+variable libs
+variable design_data {}
+variable default_grid_data {}
+variable def_output
+variable widths
+variable pitches
+variable loffset
+variable boffset
+variable site
+variable row_height
+variable metal_layers {}
+variable blockages {}
+variable padcell_blockages {}
+variable instances {}
+variable default_template_name {}
+variable template {}
+variable default_cutclass {}
+variable twowidths_table {}
+variable twowidths_table_wrongdirection {}
+variable stdcell_area ""
+variable power_nets {}
+variable ground_nets {}
+variable macros {}
+variable verbose 0
+variable global_connections {}
+variable default_global_connections {
+  VDD {
+    {inst_name .* pin_name ^VDD$}
+    {inst_name .* pin_name ^VDDPE$}
+    {inst_name .* pin_name ^VDDCE$}
+  }
+  VSS {
+    {inst_name .* pin_name ^VSS$}
+    {inst_name .* pin_name ^VSSE$}
+  }
+}
+variable voltage_domains {
+  CORE {
+    primary_power VDD primary_ground VSS
+  }
+}
+
+proc check_design_state {} {
+  if {[ord::get_db_block] == "NULL"} {
+    utl::error PDN 72 "Design must be loaded before calling pdngen commands."
+  }
+}
+
+proc check_orientations {orientations} {
+  set valid_orientations {R0 R90 R180 R270 MX MY MXR90 MYR90}
+  set lef_orientations {N R0 FN MY S R180 FS MX E R270 FE MYR90 W R90 FW MXR90}
+
+  set checked_orientations {}
+  foreach orient $orientations {
+    if {[lsearch -exact $valid_orientations $orient] > -1} {
+      lappend checked_orientations $orient
+    } elseif {[dict exists $lef_orientations $orient]} {
+      lappend checked_orientations [dict get $lef_orientations $orient]
+    } else {
+      utl::error PDN 74 "Invalid orientation $orient specified, must be one of [join $valid_orientations {, }]."
+    }
+  }
+  return $checked_orientations
+}
+
+proc check_layer_names {layer_names} {
+  set tech [ord::get_db_tech]
+
+  foreach layer_name $layer_names {
+    if {[$tech findLayer $layer_name] == "NULL"} {
+      if {[regexp {(.*)_PIN_(hor|ver)$} $layer_name - actual_layer_name]} {
+        if {[$tech findLayer $actual_layer_name] == "NULL"} {
+          utl::error "PDN" 75 "Layer $actual_layer_name not found in loaded technology data."
+        }
+      } else {
+        utl::error "PDN" 76 "Layer $layer_name not found in loaded technology data."
+      }
+    }  
+  }
+  return $layer_names
+}
+
+proc check_layer_width {layer_name width} {
+  set tech [ord::get_db_tech]
+
+  set layer [$tech findLayer $layer_name]
+  set minWidth [$layer getMinWidth]
+  set maxWidth [$layer getMaxWidth]
+
+  if {[ord::microns_to_dbu $width] < $minWidth} {
+    utl::error "PDN" 77 "Width ($width) specified for layer $layer_name is less than minimum width ([ord::dbu_to_microns $minWidth])."
+  }
+  if {[ord::microns_to_dbu $width] > $maxWidth} {
+    utl::error "PDN" 78 "Width ($width) specified for layer $layer_name is greater than maximum width ([ord::dbu_to_microns $maxWidth])."
+  }
+  return $width
+}
+
+proc check_layer_spacing {layer_name spacing} {
+  set tech [ord::get_db_tech]
+
+  set layer [$tech findLayer $layer_name]
+  set minSpacing [$layer getSpacing]
+
+  if {[ord::microns_to_dbu $spacing] < $minSpacing} {
+    utl::error "PDN" 79 "Spacing ($spacing) specified for layer $layer_name is less than minimum spacing ([ord::dbu_to_microns $minSpacing)]."
+  }
+  return $spacing
+}
+
+proc check_rails {rails_spec} {
+  if {[llength $rails_spec] % 2 == 1} {
+    utl::error "PDN" 81 "Expected an even number of elements in the list for -rails option, got [llength $rails_spec]."
+  }
+  check_layer_names [dict keys $rails_spec]
+  foreach layer_name [dict keys $rails_spec] {
+    if {[dict exists $rails_spec $layer_name width]} {
+      check_layer_width $layer_name [dict get $rails_spec $layer_name width]
+    }
+    if {[dict exists $rails_spec $layer_name spacing]} {
+      check_layer_spacing $layer_name [dict get $rails_spec $layer_name spacing]
+    }
+    if {![dict exists $rails_spec $layer_name pitch]} {
+      dict set rails_spec $layer_name pitch [ord::dbu_to_microns [expr [get_row_height] * 2]]
+    }
+  }
+  return $rails_spec
+}
+
+proc check_straps {straps_spec} {
+  if {[llength $straps_spec] % 2 == 1} {
+    utl::error "PDN" 83 "Expected an even number of elements in the list for straps specification, got [llength $straps_spec]."
+  }
+  check_layer_names [dict keys $straps_spec]
+  foreach layer_name [dict keys $straps_spec] {
+    if {[dict exists $straps_spec $layer_name width]} {
+      check_layer_width $layer_name [dict get $straps_spec $layer_name width]
+    } else {
+      utl::error PDN 84 "Missing width specification for strap on layer $layer_name."
+    }
+    set width [ord::microns_to_dbu [dict get $straps_spec $layer_name width]]
+
+    if {![dict exists $straps_spec $layer_name spacing]} {
+      dict set straps_spec $layer_name spacing [expr [dict get $straps_spec $layer_name pitch] / 2.0]
+    }
+    check_layer_spacing $layer_name [dict get $straps_spec $layer_name spacing]
+    set spacing [ord::microns_to_dbu [dict get $straps_spec $layer_name spacing]]
+
+    if {[dict exists $straps_spec $layer_name pitch]} {
+      set layer [[ord::get_db_tech] findLayer $layer_name]
+      set minPitch [expr 2 * ([$layer getSpacing] + $width)]
+      if {[ord::microns_to_dbu [dict get $straps_spec $layer_name pitch]] < $minPitch} {
+        utl::error "PDN" 85 "Pitch [dict get $straps_spec $layer_name pitch] specified for layer $layer_name is less than 2 x (width + spacing) (width=[ord::dbu_to_microns $width], spacing=[ord::dbu_to_microns $spacing])."
+      }
+    } else {
+      utl::error PDN 86 "No pitch specified for strap on layer $layer_name."
+    }
+  }
+  return $straps_spec
+}
+
+proc check_connect {grid connect_spec} {
+  foreach connect_statement $connect_spec {
+    if {[llength $connect_statement] < 2} {
+      utl::error PDN 87 "Connect statement must consist of at least 2 entries."
+    }
+    check_layer_names [lrange $connect_statement 0 1]
+    dict set layers [lindex $connect_statement 0] 1
+    dict set layers [lindex $connect_statement 1] 1
+  }
+
+  if {[dict get $grid type] == "macro"} {
+    set pin_layer_defined 0
+    set actual_layers {}
+    foreach layer_name [dict keys $layers] {
+      if {[regexp {(.*)_PIN_(hor|ver)$} $layer_name - layer]} {
+        lappend actual_layers $layer
+      } else {
+        lappend actual_layers $layer_name
+      }
+    }
+  }
+  return $connect_spec
+}
+
+proc check_core_ring {core_ring_spec} {
+  if {[llength $core_ring_spec] % 2 == 1} {
+    utl::error "PDN" 109 "Expected an even number of elements in the list for core_ring specification, got [llength $core_ring_spec]."
+  }
+  set layer_directions {}
+  check_layer_names [dict keys $core_ring_spec]
+  foreach layer_name [dict keys $core_ring_spec] {
+    if {[dict exists $core_ring_spec $layer_name width]} {
+      check_layer_width $layer_name [dict get $core_ring_spec $layer_name width]
+    } else {
+      utl::error PDN 121 "Missing width specification for strap on layer $layer_name."
+    }
+    set width [ord::microns_to_dbu [dict get $core_ring_spec $layer_name width]]
+
+    if {![dict exists $core_ring_spec $layer_name spacing]} {
+      dict set core_ring_spec $layer_name spacing [expr [dict get $core_ring_spec $layer_name pitch] / 2.0]
+    }
+    check_layer_spacing $layer_name [dict get $core_ring_spec $layer_name spacing]
+    set spacing [ord::microns_to_dbu [dict get $core_ring_spec $layer_name spacing]]
+    dict set layer_directions [get_dir $layer_name] $layer_name
+
+    if {[dict exists $core_ring_spec $layer_name core_offset]} {
+      check_layer_spacing $layer_name [dict get $core_ring_spec $layer_name core_offset]
+    } elseif {[dict exists $core_ring_spec $layer_name pad_offset]} {
+      check_layer_spacing $layer_name [dict get $core_ring_spec $layer_name pad_offset]
+    } else {
+      utl::error PDN 146 "Must specifu a pad_offset or core_offset for rings."
+    }
+  }
+  if {[llength [dict keys $layer_directions]] == 0} {
+    utl::error PDN 139 "No direction defiend for layers [dict keys $core_ring_spec]." 
+  } elseif {[llength [dict keys $layer_directions]] == 1} {
+    set dir [dict keys $layer_directions]
+    set direction [expr $dir == "ver" ? "vertical" : "horizontal"]
+    set missing_direction [expr $dir == "ver" ? "horizontal" : "vertical"]
+    
+    utl::error PDN 140 "Layers [dict keys $core_ring_spec] are both $direction, missing layer in direction $other_direction." 
+  } elseif {[llength [dict keys $layer_directions]] > 2} {
+    utl::error PDN 141 "Unexpected number of directions found for layers [dict keys $core_ring_spec], ([dict keys $layer_directions])." 
+  }
+
+  return $core_ring_spec
+}
+
+proc check_starts_with {value} {
+  if {$value != "POWER" && $value != "GROUND"} {
+    utl::error PDN 95 "Value specified for -starts_with option ($value), must be POWER or GROUND."
+  }
+
+  return $value
+}
+
+proc check_voltage_domains {domains} {
+  variable voltage_domains
+
+  foreach domain $domains {
+    if {[lsearch [dict keys $voltage_domains] $domain] == -1} {
+      utl::error PDN 110 "Voltage domain $domain has not been specified, use set_voltage_domain to create this voltage domain."
+    }
+  }
+
+  return $domains
+}
+
+proc check_instances {instances} {
+  variable $block
+
+  foreach instance $instances {
+    if {[$block findInst $instance] == "NULL"} {
+      utl::error PDN 111 "Instance $instance does not exist in the design."
+    }
+  }
+
+  return $instances
+}
+
+proc check_cells {cells} {
+  foreach cell $cells {
+    if {[[ord::get_db] findMaster $cell] == "NULL"} {
+      utl::warn PDN 112 "Cell $cell not loaded into the database."
+    }
+  }
+
+  return $cells
+}
+
+proc check_region {region_name} {
+  set block [ord::get_db_block]
+
+  if {[$block findRegion $region_name] == "NULL"} {
+    utl::error PDN 127 "No region $region_name found in the design for voltage_domain."
+  }
+
+  return $region_name
+}
+
+proc check_power {power_net_name} {
+  set block [ord::get_db_block]
+
+  if {[set net [$block findNet $power_net_name]] == "NULL"} {
+    set net [odb::dbNet_create $block $power_net_name]
+    $net setSpecial
+    $net setSigType "POWER"
+  } else {
+    if {[$net getSigType] != "POWER"} {
+      utl::error PDN 128 "Net $power_net_name already exists in the design, but is of signal type [$net getSigType]."
+    }
+  }
+  return $power_net_name
+}
+
+proc check_secondary_power {secondary_power_net_name} {
+  set block [ord::get_db_block]
+
+  foreach secondary_power $secondary_power_net_name {
+    if {[set net [$block findNet $secondary_power]] == "NULL"} {
+      set net [odb::dbNet_create $block $secondary_power]
+      $net setSpecial
+      $net setSigType "POWER"
+    } else {
+      if {[$net getSigType] != "POWER"} {
+        utl::error PDN 176 "Net $secondary_power already exists in the design, but is of signal type [$net getSigType]."
+      }
+    }
+  }
+  return $secondary_power_net_name
+}
+
+proc check_ground {ground_net_name} {
+  set block [ord::get_db_block]
+
+  if {[set net [$block findNet $ground_net_name]] == "NULL"} {
+    set net [odb::dbNet_create $block $ground_net_name]
+    $net setSpecial
+    $net setSigType "GROUND"
+  } else {
+    if {[$net getSigType] != "GROUND"} {
+      utl::error PDN 129 "Net $ground_net_name already exists in the design, but is of signal type [$net getSigType]."
+    }
+  }
+  return $ground_net_name
+}
+
+proc set_voltage_domain {args} {
+  variable voltage_domains
+
+  set voltage_domain {}
+  set process_args $args
+  while {[llength $process_args] > 0} {
+    set arg [lindex $process_args 0]
+    set value [lindex $process_args 1]
+
+    switch $arg {
+      -name            {dict set voltage_domain name $value}
+      -power           {dict set voltage_domain primary_power [check_power $value]}
+      -secondary_power {dict set voltage_domain secondary_power [check_secondary_power $value]}
+      -ground          {dict set voltage_domain primary_ground [check_ground $value]}
+      -region          {dict set voltage_domain region [check_region $value]}
+      default          {utl::error PDN 130 "Unrecognized argument $arg, should be one of -name, -power, -ground -region."}
+    }
+
+    set process_args [lrange $process_args 2 end]
+  }
+  dict set voltage_domains [dict get $voltage_domain name] $voltage_domain
+}
+
+proc check_direction {direction} {
+  if {$direction != "horizontal" && $direction != "vertical"} {
+    utl::error PDN 138 "Unexpected value for direction ($direction), should be horizontal or vertical."
+  }
+  return $direction
+}
+
+proc check_number {value} {
+  if {![string is double $value]} {
+    error "value ($value) not recognized as a number."
+  }
+
+  return $value
+}
+
+proc check_halo {value} {
+  foreach item $value {
+    if {[catch {check_number $item} msg]} {
+      utl::error PDN 164 "Problem with halo specification, $msg."
+    }
+  }
+
+  return $value
+}
+
+proc define_pdn_grid {args} {
+  variable current_grid
+
+  set grid {}
+
+  set process_args $args
+  while {[llength $process_args] > 0} {
+    set arg [lindex $process_args 0]
+    set value [lindex $process_args 1]
+
+    switch $arg {
+      -name              {dict set grid name $value}
+      -voltage_domains   {dict set grid voltage_domains [check_voltage_domains $value]}
+      -macro             {dict set grid type macro}
+      -grid_over_pg_pins {dict set grid grid_over_pg_pins $value}
+      -orient            {dict set grid orient [check_orientations $value]}
+      -instances         {dict set grid instances [check_instances $value]}
+      -cells             {dict set grid macro [check_cells $value]}
+      -halo              {dict set grid halo [check_halo [lmap x $value {ord::microns_to_dbu [check_number $x]}]]}
+      -pins              {dict set grid pins [check_layer_names $value]}
+      -starts_with       {dict set grid starts_with [check_starts_with $value]}
+      -pin_direction     {dict set grid pin_direction [check_direction $value]}
+      default            {utl::error PDN 88 "Unrecognized argument $arg, should be one of -name, -orient, -instances -cells -pins -starts_with."}
+    }
+
+    set process_args [lrange $process_args 2 end]
+  }
+
+  set current_grid [verify_grid $grid]
+}
+
+proc get_grid {grid_name} {
+  variable design_data
+
+  if {[dict exists $design_data grid]} {
+    dict for {type grids} [dict get $design_data grid] {
+      dict for {name grid} $grids {
+        if {$name == $grid_name} {
+          return $grid
+        }
+      }
+    }
+  }
+
+  return {}
+}
+
+proc check_grid {grid} {
+  if {$grid == {}} {
+    utl::error PDN  113 "The grid $grid_name has not been defined."
+  }
+  return $grid
+}
+
+proc check_power_ground {value} {
+  if {$value == "POWER" || $value == "GROUND"} {
+    return $value
+  }
+  utl::error PDN 114 "Unexpected value ($value), must be either POWER or GROUND."
+}
+
+proc add_pdn_stripe {args} {
+  variable current_grid
+
+  if {[dict exists $args -grid]} {
+    set current_grid [check_grid [get_grid [dict get $args -grid]]]
+  }
+  set grid $current_grid
+
+  set stripe [dict get $args stripe]
+  set layer [check_layer_names [dict get $args -layer]]
+
+  set process_args $args
+  while {[llength $process_args] > 0} {
+    set arg [lindex $process_args 0]
+    set value [lindex $process_args 1]
+
+    switch $arg {
+      -grid            {;}
+      -layer           {;}
+      -width           {dict set grid $stripe $layer width $value}
+      -spacing         {dict set grid $stripe $layer spacing $value}
+      -offset          {dict set grid $stripe $layer offset $value}
+      -pitch           {dict set grid $stripe $layer pitch $value}
+      -starts_with     {dict set grid $stripe $layer starts_with [check_power_ground $value]}
+      -extend_to_core_ring {dict set grid $stripe $layer extend_to_core_ring 1}
+      stripe           {;}
+      default          {utl::error PDN 124 "Unrecognized argument $arg, should be one of -grid, -type, -orient, -power_pins, -ground_pins, -blockages, -rails, -straps, -connect."}
+    }
+
+    set process_args [lrange $process_args 2 end]
+  }
+
+  set current_grid [verify_grid $grid]
+}
+
+proc check_max_length {values max_length} {
+  if {[llength $values] > $max_length} {
+    error "[llength $values] provided, maximum of $max_length values allowed."
+  }
+}
+
+proc check_grid_voltage_domains {grid} {
+  if {![dict exists $grid voltage_domains]} {
+    utl::error PDN 158 "No voltage domains defined for grid."
+  }
+}
+
+proc get_voltage_domain_by_name {domain_name} {
+  variable voltage_domains
+
+  if {[dict exists $voltage_domains $domain_name]} {
+    return [dict get $voltage_domains $domain_name]
+  }
+
+  utl::error PDN 159 "Voltage domains $domain_name has not been defined."
+}
+
+proc match_inst_connection {inst net_name} {
+  variable global_connections
+
+  foreach pattern [dict get $global_connections $net_name] {
+    if {[regexp [dict get $pattern inst_name] [$inst getName]]} {
+      foreach pin [[$inst getMaster] getMTerms] {
+        if {[regexp [dict get $pattern pin_name] [$pin getName]]} {
+          return 1
+        }
+      }
+    }
+  }
+  return 0
+}
+
+proc is_inst_in_voltage_domain {inst domain_name} {
+  set voltage_domain [get_voltage_domain_by_name $domain_name]
+
+  # The instance is in the voltage domain if it connected to both related power and ground nets
+  set power_net [dict get $voltage_domain primary_power]
+  set ground_net [dict get $voltage_domain primary_ground]
+
+  return [match_inst_connection $inst $power_net] && [match_inst_connection $inst $ground_net]
+}
+
+proc get_block_inst_masters {} {
+  variable block_masters
+
+  if {[llength $block_masters] == 0} {
+    foreach inst [[ord::get_db_block] getInsts] {
+      if {[lsearch $block_masters [[$inst getMaster] getName]] == -1} {
+        lappend block_masters [[$inst getMaster] getName]
+      }
+    }
+  }
+  return $block_masters
+}
+
+proc is_cell_present {cell_name} {
+  return [lsearch [get_block_inst_masters] $cell_name] > -1
+}
+
+proc check_pwr_pads {grid cells} {
+  check_grid_voltage_domains $grid
+  set voltage_domains [dict get $grid voltage_domains]
+  set pwr_pads {}
+  set inst_example {}
+  foreach voltage_domain $voltage_domains {
+
+    set net_name [get_voltage_domain_power $voltage_domain]
+    if {[set net [[ord::get_db_block] findNet $net_name]] == "NULL"} {
+      utl::error PDN 149 "Power net $net_name not found."
+    }
+    set find_cells $cells
+    foreach inst [[ord::get_db_block] getInsts] {
+      if {[set idx [lsearch $find_cells [[$inst getMaster] getName]]] > -1} {
+        if {![is_inst_in_voltage_domain $inst $voltage_domain]} {continue}
+        # Only need one example of each cell
+        set cell_name [lindex $find_cells $idx]
+        set find_cells [lreplace $find_cells $idx $idx]
+        dict set inst_example $cell_name $inst
+      }
+      if {[llength $find_cells] == 0} {break}
+    }
+    if {[llength $find_cells] > 0} {
+      utl::warn PDN 150 "Cannot find cells ([join $find_cells {, }]) in voltage domain $voltage_domain."
+    }
+    dict for {cell inst} $inst_example {
+      set pin_name [get_inst_pin_connected_to_net $inst $net]
+      dict lappend pwr_pads $pin_name $cell
+    }
+  }
+
+  return $pwr_pads
+}
+
+proc check_gnd_pads {grid cells} {
+  check_grid_voltage_domains $grid
+  set voltage_domains [dict get $grid voltage_domains]
+  set gnd_pads {}
+  set inst_example {}
+  foreach voltage_domain $voltage_domains {
+    set net_name [get_voltage_domain_ground $voltage_domain]
+    if {[set net [[ord::get_db_block] findNet $net_name]] == "NULL"} {
+      utl::error PDN 151 "Ground net $net_name not found."
+    }
+    set find_cells $cells
+    foreach inst [[ord::get_db_block] getInsts] {
+      if {[set idx [lsearch $find_cells [[$inst getMaster] getName]]] > -1} {
+        if {![is_inst_in_voltage_domain $inst $voltage_domain]} {continue}
+        # Only need one example of each cell
+        set cell_name [lindex $find_cells $idx]
+        set find_cells [lreplace $find_cells $idx $idx]
+        dict set inst_example $cell_name $inst
+      }
+      if {[llength $find_cells] == 0} {break}
+    }
+    if {[llength $find_cells] > 0} {
+      utl::warn PDN 152 "Cannot find cells ([join $find_cells {, }]) in voltage domain $voltage_domain."
+    }
+    dict for {cell inst} $inst_example {
+      set pin_name [get_inst_pin_connected_to_net $inst $net]
+      dict lappend gnd_pads $pin_name $cell
+    }
+  }
+  return $gnd_pads
+}
+
+proc add_pdn_ring {args} {
+  variable current_grid
+
+  if {[dict exists $args -grid]} {
+    set current_grid [check_grid [get_grid [dict get $args -grid]]]
+    #Dinesh-A: Core Ring without Strap
+    set grid $current_grid
+  }
+  set layers [check_layer_names [dict get $args -layers]]
+
+  set process_args $args
+  while {[llength $process_args] > 0} {
+    set arg [lindex $process_args 0]
+    set value [lindex $process_args 1]
+
+    switch $arg {
+      -grid            {;}
+      -layers          {;}
+      -widths {
+        if {[catch {check_max_length $value 2} msg]} {
+          utl::error PDN 115 "Unexpected number of values for -widths, $msg."
+        }
+        if {[llength $value] == 1} {
+          set values [list $value $value]
+        } else {
+          set values $value
+        }
+        foreach layer $layers width $values {
+          dict set grid core_ring $layer width $width
+        }
+      }
+      -spacings {
+        if {[catch {check_max_length $value 2} msg]} {
+          utl::error PDN 116 "Unexpected number of values for -spacings, $msg."
+        }
+        if {[llength $value] == 1} {
+          set values [list $value $value]
+        } else {
+          set values $value
+        }
+        foreach layer $layers spacing $values {
+          dict set grid core_ring $layer spacing $spacing
+        }
+      }
+      -core_offsets {
+        if {[catch {check_max_length $value 2} msg]} {
+          utl::error PDN 117 "Unexpected number of values for -core_offsets, $msg."
+        }
+        if {[llength $value] == 1} {
+          set values [list $value $value]
+        } else {
+          set values $value
+        }
+        foreach layer $layers offset $values {
+          dict set grid core_ring $layer core_offset $offset
+        }
+      }
+      -pad_offsets {
+        if {[catch {check_max_length $value 2} msg]} {
+          utl::error PDN 118 "Unexpected number of values for -pad_offsets, $msg."
+        }
+        if {[llength $value] == 1} {
+          set values [list $value $value]
+        } else {
+          set values $value
+        }
+        foreach layer $layers offset $values {
+          dict set grid core_ring $layer pad_offset $offset
+        }
+      }
+      -power_pads      {dict set grid pwr_pads [check_pwr_pads $grid $value]}
+      -ground_pads     {dict set grid gnd_pads [check_gnd_pads $grid $value]}
+      default          {utl::error PDN 125 "Unrecognized argument $arg, should be one of -grid, -type, -orient, -power_pins, -ground_pins, -blockages, -rails, -straps, -connect."}
+    }
+
+    set process_args [lrange $process_args 2 end]
+  }
+
+  set current_grid [verify_grid $grid]
+}
+
+proc check_fixed_vias {via_names} {
+  set tech [ord::get_db_tech]
+
+  foreach via_name $via_names {
+    if {[set via [$tech findVia $via_name]] == "NULL"} {
+      utl::error "PDN" 119 "Via $via_name specified in the grid specification does not exist in this technology."
+    }
+  }
+
+  return $via_names
+}
+
+proc add_pdn_connect {args} {
+  variable current_grid
+
+  if {[dict exists $args -grid]} {
+    set current_grid [check_grid [get_grid [dict get $args -grid]]]
+  }
+  set grid $current_grid
+
+  set layers [check_layer_names [dict get $args -layers]]
+
+  set process_args $args
+  while {[llength $process_args] > 0} {
+    set arg [lindex $process_args 0]
+    set value [lindex $process_args 1]
+
+    switch $arg {
+      -grid            {;}
+      -layers          {;}
+      -cut_pitch       {dict set layers constraints cut_pitch $value}
+      -fixed_vias      {dict set layers fixed_vias [check_fixed_vias $value]}
+      default          {utl::error PDN 126 "Unrecognized argument $arg, should be one of -grid, -type, -orient, -power_pins, -ground_pins, -blockages, -rails, -straps, -connect."}
+    }
+
+    set process_args [lrange $process_args 2 end]
+  }
+
+  dict lappend grid connect $layers
+  set current_grid [verify_grid $grid]
+}
+
+proc convert_grid_to_def_units {grid} {
+  if {![dict exists $grid units]} {
+    if {[dict exists $grid core_ring]} {
+      dict for {layer data} [dict get $grid core_ring] {
+        dict set grid core_ring $layer [convert_layer_spec_to_def_units $data]
+      }
+    }
+  
+    if {[dict exists $grid rails]} {
+      dict for {layer data} [dict get $grid rails] {
+        dict set grid rails $layer [convert_layer_spec_to_def_units $data]
+        if {[dict exists $grid template]} {
+          foreach template [dict get $grid template names] {
+            if {[dict exists $grid layers $layer $template]} {
+              dict set grid rails $layer $template [convert_layer_spec_to_def_units [dict get $grid rails $layer $template]]
+            }
+          }
+        }
+      }
+    }
+    if {[dict exists $grid straps]} {
+      dict for {layer data} [dict get $grid straps] {
+        dict set grid straps $layer [convert_layer_spec_to_def_units $data]
+        if {[dict exists $grid template]} {
+          foreach template [dict get $grid template names] {
+            if {[dict exists $grid straps $layer $template]} {
+              dict set grid straps $layer $template [convert_layer_spec_to_def_units [dict get $grid straps $layer $template]]
+            }
+          }
+        }
+      }
+    }
+    dict set grid units "db"
+  }
+
+  return $grid
+}
+
+proc get_inst_pin_connected_to_net {inst net} {
+  foreach iterm [$inst getITerms] {
+    # debug "[$inst getName] [$iterm getNet] == $net"
+    if {[$iterm getNet] == $net} {
+      return [[$iterm getMTerm] getName]
+    }
+  }
+}
+
+proc filter_out_selected_by {instances selection} {
+  dict for {inst_name instance} $instances {
+    if {[dict exists $instance selected_by]} {
+      if {[dict get $instance selected_by] == $selection} {
+        set instances [dict remove $instances $inst_name]
+      }
+    }
+  }
+
+  return $instances
+}
+
+proc get_priority_value {priority} {
+  if {$priority == "inst_name"} {return 4}
+  if {$priority == "cell_name"} {return 3}
+  if {$priority == "orient"} {return 2}
+  if {$priority == "none"} {return 1}
+}
+
+proc set_instance_grid {inst_name grid priority} {
+  variable instances
+
+  # debug "start- inst_name $inst_name, grid: [dict get $grid name], priority: $priority"
+  set grid_name [dict get $grid name]
+  set priority_value [get_priority_value $priority]
+  set instance [dict get $instances $inst_name]
+  if {[dict exists $instance grid]} {
+    if {[dict get $instance grid] != $grid_name} {
+      set current_priority_value [get_priority_value [dict get $instance selected_by]]
+      if {$priority_value < $current_priority_value} {
+        return
+      } elseif {$priority_value == $current_priority_value} {
+        utl::error PDN 165 "Conflict found, instance $inst_name is part of two grid definitions ($grid_name, [dict get $instances $inst_name grid])."
+      }
+    }
+  } else {
+    dict set instances $inst_name grid $grid_name
+  }
+
+  if {[dict exists $grid halo]} {
+    set_instance_halo $inst_name [dict get $grid halo]
+  }
+  dict set instances $inst_name selected_by $priority
+  dict set instances $inst_name grid $grid_name
+  dict set insts $inst_name selected_by $priority
+  dict set insts $inst_name grid $grid_name
+}
+
+proc verify_grid {grid} {
+  variable design_data
+  variable default_grid_data
+
+  if {![dict exists $grid type]} {
+    dict set grid type stdcell
+  }
+  set type [dict get $grid type]
+
+  if {![dict exists $grid voltage_domains]} {
+    dict set grid voltage_domains "CORE"
+  }
+  set voltage_domains [dict get $grid voltage_domains]
+
+  if {![dict exists $grid name]} {
+    set idx 1
+    set name "[join [dict get $grid voltage_domains] {_}]_${type}_grid_$idx"
+    while {[get_grid $name] != {}} {
+      incr idx
+      set name "[join [dict get $grid voltage_domains] {_}]_${type}_grid_$idx"
+    }
+    dict set grid name $name
+  }
+  set grid_name [dict get $grid name]
+
+  if {[dict exists $grid core_ring]} {
+    check_core_ring [dict get $grid core_ring]
+    set layer [lindex [dict keys [dict get $grid core_ring]]]
+    if {[dict exist $grid core_ring $layer pad_offset]} {
+      if {![dict exists $grid pwr_pads]} {
+        utl::error PDN 147 "No definition of power padcells provided, required when using pad_offset."
+      }
+      if {![dict exists $grid gnd_pads]} {
+        utl::error PDN 148 "No definition of ground padcells provided, required when using pad_offset."
+      }
+    }
+  }
+
+  if {[dict exists $grid pwr_pads]} {
+    dict for {pin_name cells} [dict get $grid pwr_pads] {
+      foreach cell $cells {
+        if {[set master [[ord::get_db] findMaster $cell]] == "NULL"} {
+          utl::error PDN 153  "Core power padcell ($cell) not found in the database."
+        } 
+        if {[$master findMTerm $pin_name] == "NULL"} {
+          utl::error PDN 154 "Cannot find pin ($pin_name) on core power padcell ($cell)."
+        }
+      } 
+    }
+  }
+
+  if {[dict exists $grid gnd_pads]} {
+    dict for {pin_name cells} [dict get $grid gnd_pads] {
+      foreach cell $cells {
+        if {[set master [[ord::get_db] findMaster $cell]] == "NULL"} {
+          utl::error PDN 155  "Core ground padcell ($cell) not found in the database."
+        } 
+        if {[$master findMTerm $pin_name] == "NULL"} {
+          utl::error PDN 156 "Cannot find pin ($pin_name) on core ground padcell ($cell)."
+        }
+      } 
+    }
+  }
+
+  if {[dict exists $grid macro]} {
+    check_cells [dict get $grid macro]
+  }
+ 
+  if {[dict exists $grid rails]} {
+    dict set grid rails [check_rails [dict get $grid rails]]
+  }
+
+  if {[dict exists $grid straps]} {
+    check_straps [dict get $grid straps]
+  }
+
+  if {[dict exists $grid template]} {
+    set_template_size {*}[dict get $grid template size]
+  }
+  
+  if {[dict exists $grid orient]} {
+    if {$type == "stdcell"} {
+      utl::error PDN 90 "The orient attribute cannot be used with stdcell grids."
+    }
+    dict set grid orient [check_orientations [dict get $grid orient]]
+  }
+
+  if {[dict exists $grid connect]} {
+    dict set grid connect [check_connect $grid [dict get $grid connect]]
+  }
+
+  if {$type == "macro"} {
+    if {![dict exists $grid halo]} {
+      dict set grid halo [get_default_halo]
+    }
+    check_halo [dict get $grid halo]
+  } else {
+    set default_grid_data $grid
+  }
+
+  # debug $grid
+
+  dict set design_data grid $type $grid_name $grid
+  return $grid
+}
+
+proc complete_macro_grid_specifications {} {
+  variable design_data
+  variable instances
+  variable macros
+
+  set macros [get_macro_blocks]
+
+  dict for {type grid_types} [dict get $design_data grid] {
+    dict for {name grid} $grid_types {
+      dict set design_data grid $type $name [convert_grid_to_def_units $grid]
+    }
+  }
+  if {![dict exists $design_data grid macro]} {
+    return
+  }
+
+  ########################################
+  # Creating blockages based on macro locations
+  #######################################
+  # debug "import_macro_boundaries"
+  import_macro_boundaries
+
+  # Associate each block instance with a grid specification
+  set macro_names [dict keys $macros]
+  dict for {grid_name grid} [dict get $design_data grid macro] {
+    set insts [find_instances_of $macro_names]
+    set boundary [odb::newSetFromRect {*}[get_core_area]]
+    set insts [filtered_insts_within $insts $boundary]
+    if {[dict exists $grid instances]} {
+      # debug "Check macro name for [dict get $grid name]"
+      dict for {inst_name instance} $insts {
+        if {[lsearch [dict get $grid instances] $inst_name] > -1} {
+          set_instance_grid $inst_name $grid inst_name
+	}
+      }
+      set insts [set_instance_grid $selected_insts $grid inst_name]
+    } elseif {[dict exists $grid macro]} {
+      # set insts [filter_out_selected_by $insts inst_name]
+      # debug "Check instance name for [dict get $grid name]"
+      dict for {inst_name instance} $insts {
+        set cell_name [dict get $instance macro]
+        if {[lsearch [dict get $grid macro] $cell_name] > -1} {
+          set_instance_grid $inst_name $grid cell_name
+        }
+      }
+    } elseif {[dict exists $grid orient]} {
+      # set insts [filter_out_selected_by $insts inst_name]
+      # set insts [filter_out_selected_by $insts cell_name]
+      # debug "Check orientation for [dict get $grid name]"
+      dict for {inst_name instance} $insts {
+        set orient [dict get $instance orient]
+	# debug "Inst: $inst_name, orient: $orient, compare to: [dict get $grid orient]"
+        if {[lsearch [dict get $grid orient] $orient] > -1} {
+          set_instance_grid $inst_name $grid orient
+        }
+      }
+    }
+  }
+  dict for {grid_name grid} [dict get $design_data grid macro] {
+    set related_instances {}
+    dict for {inst instance} $instances {
+      if {![dict exists $instance grid]} {
+        # utl::error PDN 166 "Instance $inst of cell [dict get $instance macro] is not associated with any grid."
+        dict set instance grid "__none__"
+      }
+      if {[dict get $instance grid] == $grid_name} {
+        dict set related_instances $inst $instance 
+      }
+    }
+    dict set design_data grid macro $grid_name _related_instances $related_instances
+  }
+
+  dict for {grid_name grid} [dict get $design_data grid macro] {
+    # Set the pin layer on the connect statement to the pin layer of the def to be _PIN_<dir>
+    set blockages {}
+    set pin_layers {}
+    set power_pins {}
+    set ground_pins {}
+    dict for {instance_name instance} [dict get $grid _related_instances] {
+      lappend blockages {*}[dict get $macros [dict get $instance macro] blockage_layers]
+      lappend pin_layers {*}[dict get $macros [dict get $instance macro] pin_layers]
+      lappend power_pins {*}[dict get $macros [dict get $instance macro] power_pins]
+      lappend ground_pins {*}[dict get $macros [dict get $instance macro] ground_pins]
+    }
+    dict set design_data grid macro $grid_name power_pins [lsort -unique $power_pins]
+    dict set design_data grid macro $grid_name ground_pins [lsort -unique $ground_pins]
+
+    if {[dict exists $grid pin_direction]} {
+      if {[dict get $grid pin_direction] == "vertical"} {
+        set direction ver
+      } else {
+        set direction hor
+      }
+      set pin_layers [lsort -unique $pin_layers]
+
+      foreach pin_layer $pin_layers {
+        set new_connections {}
+        foreach connect [dict get $grid connect] {
+          if {[lindex $connect 0] == $pin_layer} {
+            set connect [lreplace $connect 0 0 ${pin_layer}_PIN_$direction]
+          }
+          if {[lindex $connect 1] == $pin_layer} {
+            set connect [lreplace $connect 1 1 ${pin_layer}_PIN_$direction]
+          }
+          lappend new_connections $connect
+        }
+        dict set design_data grid macro $grid_name connect $new_connections
+      }
+    }
+    
+    if {[dict exists $grid straps]} {
+      foreach strap_layer [dict keys [dict get $grid straps]] {
+        lappend blockages $strap_layer
+      }
+    }
+    # debug "Grid: $grid_name"
+    # debug "  instances: [dict keys [dict get $grid _related_instances]]"
+    # debug "  blockages: [lsort -unique $blockages]"
+    # debug "  connect: [dict get $design_data grid macro $grid_name connect]"
+
+    dict set design_data grid macro $grid_name blockages [lsort -unique $blockages]
+  }
+
+ # debug "get_memory_instance_pg_pins"
+  get_memory_instance_pg_pins
+}
+
+#This file contains procedures that are used for PDN generation
+proc debug {message} {
+  set state [info frame -1]
+  set str ""
+  if {[dict exists $state file]} {
+    set str "$str[dict get $state file]:"
+  }
+  if {[dict exists $state proc]} {
+    set str "$str[dict get $state proc]:"
+  }
+  if {[dict exists $state line]} {
+    set str "$str[dict get $state line]"
+  }
+  puts "\[DEBUG\] $str: $message"
+}
+
+proc lmap {args} {
+  set result {}
+  set var [lindex $args 0]
+  foreach item [lindex $args 1] {
+    uplevel 1 "set $var $item"
+    lappend result [uplevel 1 [lindex $args end]]
+  }
+  return $result
+}
+
+proc get_routing_direction {layer_name} {
+  variable layers
+
+  if {$layers == ""} {
+    init_metal_layers
+  }
+
+  if {![dict exists $layers $layer_name direction]} {
+    utl::error "PDN" 33 "Unknown direction for layer $layer_name."
+  }
+  return [dict get $layers $layer_name direction]
+}
+
+proc get_dir {layer_name} {
+  if {[regexp {.*_PIN_(hor|ver)} $layer_name - dir]} {
+    return $dir
+  }
+
+  if {[is_rails_layer $layer_name]} {
+    return "hor"
+  }
+
+  return [get_routing_direction $layer_name]
+}
+
+proc get_rails_layers {} {
+  variable design_data
+
+  if {[dict exists $design_data grid]} {
+    foreach type [dict keys [dict get $design_data grid]] {
+      dict for {name specification} [dict get $design_data grid $type] {
+        if {[dict exists $specification rails]} {
+          return [dict keys [dict get $specification rails]]
+        }
+      }
+    }
+  }
+  return {}
+}
+
+proc is_rails_layer {layer} {
+  return [expr {[lsearch -exact [get_rails_layers] $layer] > -1}]
+}
+
+proc via_number {layer_rule1 layer_rule2} {
+  return [expr [[$layer_rule1 getLayer] getNumber] - [[$layer_rule2 getLayer] getNumber]]
+}
+
+proc init_via_tech {} {
+  variable tech
+  variable def_via_tech
+
+  set def_via_tech {}
+  foreach via_rule [$tech getViaGenerateRules] {
+    set levels [list [$via_rule getViaLayerRule 0] [$via_rule getViaLayerRule 1] [$via_rule getViaLayerRule 2]]
+    set levels [lsort -command via_number $levels]
+    lassign $levels lower cut upper
+
+    dict set def_via_tech [$via_rule getName] [list \
+      lower [list layer [[$lower getLayer] getName] enclosure [$lower getEnclosure]] \
+      upper [list layer [[$upper getLayer] getName] enclosure [$upper getEnclosure]] \
+      cut   [list layer [[$cut getLayer] getName] spacing [$cut getSpacing] size [list [[$cut getRect] dx] [[$cut getRect] dy]]] \
+    ]
+  }
+  # debug "def_via_tech: $def_via_tech"
+}
+
+proc set_prop_lines {obj prop_name} {
+  variable prop_line
+  if {[set prop [::odb::dbStringProperty_find $obj $prop_name]] != "NULL"} {
+    set prop_line [$prop getValue]
+  } else {
+    set prop_line {}
+  }
+}
+
+proc read_propline {} {
+  variable prop_line
+
+  set word [lindex $prop_line 0]
+  set prop_line [lrange $prop_line 1 end]
+
+  set line {}
+  while {[llength $prop_line] > 0 && $word != ";"} {
+    lappend line $word
+    set word [lindex $prop_line 0]
+    set prop_line [lrange $prop_line 1 end]
+  }
+  return $line
+}
+
+proc empty_propline {} {
+  variable prop_line
+  return [expr ![llength $prop_line]]
+}
+
+proc find_layer {layer_name} {
+  variable tech
+
+  if {[set layer [$tech findLayer $layer_name]] == "NULL"} {
+    utl::error "PDN" 19 "Cannot find layer $layer_name in loaded technology."
+  }
+  return $layer
+}
+
+proc read_spacing {layer_name} {
+  variable layers
+  variable def_units
+
+  set layer [find_layer $layer_name]
+
+  set_prop_lines $layer LEF58_SPACING
+  set spacing {}
+
+  while {![empty_propline]} {
+    set line [read_propline]
+    if {[set idx [lsearch -exact $line CUTCLASS]] > -1} {
+      set cutclass [lindex $line [expr $idx + 1]]
+      set line [lreplace $line $idx [expr $idx + 1]]
+
+      if {[set idx [lsearch -exact $line LAYER]] > -1} {
+        set other_layer [lindex $line [expr $idx + 1]]
+        set line [lreplace $line $idx [expr $idx + 1]]
+
+        if {[set idx [lsearch -exact $line CONCAVECORNER]] > -1} {
+          set line [lreplace $line $idx $idx]
+
+          if {[set idx [lsearch -exact $line SPACING]] > -1} {
+            dict set spacing $cutclass $other_layer concave [expr round([lindex $line [expr $idx + 1]] * $def_units)]
+            # set line [lreplace $line $idx [expr $idx + 1]]
+          }
+        }
+      }
+    }
+  }
+  # debug "$layer_name $spacing"
+  dict set layers $layer_name spacing $spacing
+  # debug "$layer_name [dict get $layers $layer_name]"
+}
+
+proc read_spacingtables {layer_name} {
+  variable layers
+  variable def_units
+
+  set layer [find_layer $layer_name]
+  set prls {}
+
+  if {[$layer hasTwoWidthsSpacingRules]} {
+    set type "TWOWIDTHS"
+    set subtype "NONE"
+
+    set table_size [$layer getTwoWidthsSpacingTableNumWidths]
+    for {set i 0} {$i < $table_size} {incr i} {
+      set width [$layer getTwoWidthsSpacingTableWidth $i]
+
+      if {[$layer getTwoWidthsSpacingTableHasPRL $i]} {
+        set prl [$layer getTwoWidthsSpacingTablePRL $i]
+      } else {
+        set prl 0
+      }
+      set spacings {}
+      for {set j 0} {$j < $table_size} {incr j} {
+        lappend spacings [$layer getTwoWidthsSpacingTableEntry $i $j]
+      }
+
+      dict set layers $layer_name spacingtable $type $subtype $width [list prl $prl spacings $spacings]
+    }
+  }
+
+  set_prop_lines $layer LEF58_SPACINGTABLE
+  set spacing {}
+
+  while {![empty_propline]} {
+    set line [read_propline]
+    # debug "$line"
+    set type [lindex $line 1]
+    set subtype [lindex $line 2]
+
+    set table_entry_indexes [lsearch -exact -all $line "WIDTH"]
+    set num_entries [llength $table_entry_indexes]
+
+    foreach start_index $table_entry_indexes {
+      set pos $start_index
+      incr pos
+      set width [expr round([lindex $line $pos] * $def_units)]
+      incr pos
+      if {[lindex $line $pos] == "PRL"} {
+        incr pos
+        set prl [expr round([lindex $line $pos] * $def_units)]
+        incr pos
+      } else {
+        set prl 0
+      }
+      set spacings {}
+      for {set i 0} {$i < $num_entries} {incr i} {
+        # debug "[expr $i + $pos] [lindex $line [expr $i + $pos]]"
+        lappend spacings [expr round([lindex $line [expr $i + $pos]] * $def_units)]
+      }
+      dict set layers $layer_name spacingtable $type $subtype $width [list prl $prl spacings $spacings]
+    }
+  }
+
+  if {![dict exists $layers $layer_name spacingtable]} {
+    dict set layers $layer_name spacingtable {}
+  }
+  # debug "$layer_name [dict get $layers $layer_name]"
+}
+
+proc get_spacingtables {layer_name} {
+  variable layers
+
+  if {![dict exists $layers $layer_name spacingtable]} {
+    read_spacingtables $layer_name
+  }
+
+  return [dict get $layers $layer_name spacingtable]
+}
+
+proc get_concave_spacing_value {layer_name other_layer_name} {
+  variable layers
+  variable default_cutclass
+
+  if {![dict exists $layers $layer_name spacing]} {
+    read_spacing $layer_name
+  }
+  # debug "$layer_name [dict get $layers $layer_name]"
+  if {[dict exists $layers $layer_name spacing [dict get $default_cutclass $layer_name] $other_layer_name concave]} {
+    return [dict get $layers $layer_name spacing [dict get $default_cutclass $layer_name] $other_layer_name concave]
+  }
+  return 0
+}
+
+proc read_arrayspacing {layer_name} {
+  variable layers
+  variable def_units
+
+  set layer [find_layer $layer_name]
+
+  set_prop_lines $layer LEF58_ARRAYSPACING
+  set arrayspacing {}
+
+  while {![empty_propline]} {
+    set line [read_propline]
+    if {[set idx [lsearch -exact $line PARALLELOVERLAP]] > -1} {
+      dict set arrayspacing paralleloverlap 1
+      set line [lreplace $line $idx $idx]
+    }
+    if {[set idx [lsearch -exact $line LONGARRAY]] > -1} {
+      dict set arrayspacing longarray 1
+      set line [lreplace $line $idx $idx]
+    }
+    if {[set idx [lsearch -exact $line CUTSPACING]] > -1} {
+      dict set arrayspacing cutspacing [expr round([lindex $line [expr $idx + 1]] * $def_units)]
+      set line [lreplace $line $idx [expr $idx + 1]]
+    }
+    while {[set idx [lsearch -exact $line ARRAYCUTS]] > -1} {
+      dict set arrayspacing arraycuts [lindex $line [expr $idx + 1]] spacing [expr round([lindex $line [expr $idx + 3]] * $def_units)]
+      set line [lreplace $line $idx [expr $idx + 3]]
+    }
+  }
+  dict set layers $layer_name arrayspacing $arrayspacing
+}
+
+proc read_cutclass {layer_name} {
+  variable layers
+  variable def_units
+  variable default_cutclass
+
+  set layer [find_layer $layer_name]
+  set_prop_lines $layer LEF58_CUTCLASS
+  dict set layers $layer_name cutclass {}
+  set min_area -1
+
+  while {![empty_propline]} {
+    set line [read_propline]
+    if {![regexp {CUTCLASS\s+([^\s]+)\s+WIDTH\s+([^\s]+)} $line - cut_class width]} {
+      utl::error "PDN" 20 "Failed to read CUTCLASS property '$line'."
+    }
+    if {[regexp {LENGTH\s+([^\s]+)} $line - length]} {
+      set area [expr $width * $length]
+    } else {
+      set area [expr $width * $width]
+    }
+    if {$min_area == -1 || $area < $min_area} {
+      dict set default_cutclass $layer_name $cut_class
+      set min_area $area
+    }
+    dict set layers $layer_name cutclass $cut_class [list width [expr round($width * $def_units)] length [expr round($length * $def_units)]]
+  }
+}
+
+proc read_enclosures {layer_name} {
+  variable layers
+  variable def_units
+
+  set layer [find_layer $layer_name]
+  set_prop_lines $layer LEF58_ENCLOSURE
+  set prev_cutclass ""
+
+  while {![empty_propline]} {
+    set line [read_propline]
+    # debug "$line"
+    set enclosure {}
+    if {[set idx [lsearch -exact $line EOL]] > -1} {
+      continue
+      dict set enclosure eol [expr round([lindex $line [expr $idx + 1]] * $def_units)]
+      set line [lreplace $line $idx [expr $idx + 1]]
+    }
+    if {[set idx [lsearch -exact $line EOLONLY]] > -1} {
+      dict set enclosure eolonly 1
+      set line [lreplace $line $idx $idx]
+    }
+    if {[set idx [lsearch -exact $line SHORTEDGEONEOL]] > -1} {
+      dict set enclosure shortedgeoneol 1
+      set line [lreplace $line $idx $idx]
+    }
+    if {[set idx [lsearch -exact $line MINLENGTH]] > -1} {
+      dict set enclosure minlength [expr round([lindex $line [expr $idx + 1]] * $def_units)]
+      set line [lreplace $line $idx [expr $idx + 1]]
+    }
+    if {[set idx [lsearch -exact $line ABOVE]] > -1} {
+      dict set enclosure above 1
+      set line [lreplace $line $idx $idx]
+    }
+    if {[set idx [lsearch -exact $line BELOW]] > -1} {
+      dict set enclosure below 1
+      set line [lreplace $line $idx $idx]
+    }
+    if {[set idx [lsearch -exact $line END]] > -1} {
+      dict set enclosure end 1
+      set line [lreplace $line $idx $idx]
+    }
+    if {[set idx [lsearch -exact $line SIDE]] > -1} {
+      dict set enclosure side 1
+      set line [lreplace $line $idx $idx]
+    }
+
+    set width 0
+    regexp {WIDTH\s+([^\s]+)} $line - width
+    set width [expr round($width * $def_units)]
+
+    if {![regexp {ENCLOSURE CUTCLASS\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)} $line - cut_class overlap1 overlap2]} {
+      utl::error "PDN" 21 "Failed to read ENCLOSURE property '$line'."
+    }
+    dict set enclosure overlap1 [expr round($overlap1 * $def_units)]
+    dict set enclosure overlap2 [expr round($overlap2 * $def_units)]
+    # debug "class - $cut_class enclosure - $enclosure"
+    if {$prev_cutclass != $cut_class} {
+      set enclosures {}
+      set prev_cutclass $cut_class
+    }
+    dict lappend enclosures $width $enclosure
+    dict set layers $layer_name cutclass $cut_class enclosures $enclosures
+  }
+  # debug "end"
+}
+
+proc read_minimumcuts {layer_name} {
+  variable layers
+  variable def_units
+  variable default_cutclass
+
+  set layer [find_layer $layer_name]
+  set_prop_lines $layer LEF58_MINIMUMCUT
+
+  while {![empty_propline]} {
+    set line [read_propline]
+    set classes {}
+    set constraints {}
+    set fromabove 0
+    set frombelow 0
+
+    if {[set idx [lsearch -exact $line FROMABOVE]] > -1} {
+      set fromabove 1
+      set line [lreplace $line $idx $idx]
+    } elseif {[set idx [lsearch -exact $line FROMBELOW]] > -1} {
+      set frombelow 1
+      set line [lreplace $line $idx $idx]
+    } else {
+      set fromabove 1
+      set frombelow 1
+    }
+
+    if {[set idx [lsearch -exact $line WIDTH]] > -1} {
+      set width [expr round([lindex $line [expr $idx + 1]] * $def_units)]
+    }
+
+    if {[regexp {LENGTH ([0-9\.]*) WITHIN ([0-9\.]*)} $line - length within]} {
+      # Not expecting to deal with this king of structure, so can ignore
+      set line [regsub {LENGTH ([0-9\.]*) WITHIN ([0-9\.]*)} $line {}]
+    }
+
+    if {[regexp {AREA ([0-9\.]*) WITHIN ([0-9\.]*)} $line - area within]} {
+      # Not expecting to deal with this king of structure, so can ignore
+      set line [regsub {AREA ([0-9\.]*) WITHIN ([0-9\.]*)} $line {}]
+    }
+
+    while {[set idx [lsearch -exact $line CUTCLASS]] > -1} {
+      set cutclass [lindex $line [expr $idx + 1]]
+      set num_cuts [lindex $line [expr $idx + 2]]
+
+      if {$fromabove == 1} {
+        dict set layers $layer_name minimumcut width $width fromabove $cutclass $num_cuts
+      }
+      if {$frombelow == 1} {
+        dict set layers $layer_name minimumcut width $width frombelow $cutclass $num_cuts
+      }
+
+      set line [lreplace $line $idx [expr $idx + 2]]
+    }
+  }
+}
+
+proc get_minimumcuts {layer_name width from cutclass} {
+  variable layers
+  # debug "$layer_name, $width, $from, $cutclass"
+  if {![dict exists $layers $layer_name minimumcut]} {
+    read_minimumcuts $layer_name
+    # debug "[dict get $layers $layer_name minimumcut]"
+  }
+
+  set min_cuts 1
+
+  if {![dict exists $layers $layer_name minimumcut]} {
+    # debug "No mincut rule for layer $layer_name"
+    return $min_cuts
+  }
+
+  set idx 0
+  set widths [lsort -integer -decreasing [dict keys [dict get $layers $layer_name minimumcut width]]]
+  if {$width <= [lindex $widths end]} {
+    # debug "width $width less than smallest width boundary [lindex $widths end]"
+    return $min_cuts
+  }
+  foreach width_boundary [lreverse $widths] {
+    if {$width > $width_boundary && [dict exists $layers $layer_name minimumcut width $width_boundary $from]} {
+      # debug "[dict get $layers $layer_name minimumcut width $width_boundary]"
+      if {[dict exists $layers $layer_name minimumcut width $width_boundary $from $cutclass]} {
+        set min_cuts [dict get $layers $layer_name minimumcut width $width_boundary $from $cutclass]
+      }
+      # debug "Selected width boundary $width_boundary for $layer_name, $width $from, $cutclass [dict get $layers $layer_name minimumcut width $width_boundary $from $cutclass]"
+      break
+    }
+  }
+
+  return $min_cuts
+}
+
+proc get_via_enclosure {via_info lower_width upper_width} {
+  variable layers
+  variable default_cutclass
+  variable min_lower_enclosure
+  variable max_lower_enclosure
+  variable min_upper_enclosure
+  variable max_upper_enclosure
+
+  # debug "via_info $via_info width $lower_width,$upper_width"
+  set layer_name [dict get $via_info cut layer]
+
+  if {![dict exists $layers $layer_name cutclass]} {
+    read_cutclass $layer_name
+    read_enclosures $layer_name
+  }
+
+  if {!([dict exists $default_cutclass $layer_name] && [dict exists $layers $layer_name cutclass [dict get $default_cutclass $layer_name] enclosures])} {
+    set lower_enclosure [dict get $via_info lower enclosure]
+    set upper_enclosure [dict get $via_info upper enclosure]
+
+    set min_lower_enclosure [lindex $lower_enclosure 0]
+    set max_lower_enclosure [lindex $lower_enclosure 1]
+
+    if {$max_lower_enclosure < $min_lower_enclosure} {
+      set swap $min_lower_enclosure
+      set min_lower_enclosure $max_lower_enclosure
+      set max_lower_enclosure $swap
+    }
+
+    set min_upper_enclosure [lindex $upper_enclosure 0]
+    set max_upper_enclosure [lindex $upper_enclosure 1]
+
+    if {$max_upper_enclosure < $min_upper_enclosure} {
+      set swap $min_upper_enclosure
+      set min_upper_enclosure $max_upper_enclosure
+      set max_upper_enclosure $swap
+    }
+
+    set selected_enclosure [list $min_lower_enclosure $max_lower_enclosure $min_upper_enclosure $max_upper_enclosure]
+  } else {
+    set enclosures [dict get $layers $layer_name cutclass [dict get $default_cutclass $layer_name] enclosures]
+    # debug "Enclosure set $enclosures"
+    set upper_enclosures {}
+    set lower_enclosures {}
+
+    set width $lower_width
+
+    foreach size [lreverse [dict keys $enclosures]] {
+      if {$width >= $size} {
+          break
+      }
+    }
+
+    set enclosure_list [dict get $enclosures $size]
+    # debug "Initial enclosure_list (size = $size)- $enclosure_list"
+    if {$size > 0} {
+      foreach enclosure $enclosure_list {
+        if {![dict exists $enclosure above]} {
+          lappend lower_enclosures $enclosure
+        }
+      }
+    }
+
+    set width $upper_width
+
+    foreach size [lreverse [dict keys $enclosures]] {
+      if {$width >= $size} {
+          break
+      }
+    }
+
+    set enclosure_list [dict get $enclosures $size]
+    # debug "Initial enclosure_list (size = $size)- $enclosure_list"
+    if {$size > 0} {
+      foreach enclosure $enclosure_list {
+        if {![dict exists $enclosure below]} {
+          lappend upper_enclosures $enclosure
+        }
+      }
+    }
+
+    if {[llength $upper_enclosures] == 0} {
+      set zero_enclosures_list [dict get $enclosures 0]
+      foreach enclosure $zero_enclosures_list {
+        if {![dict exists $enclosure below]} {
+          lappend upper_enclosures $enclosure
+        }
+      }
+    }
+    if {[llength $lower_enclosures] == 0} {
+      set zero_enclosures_list [dict get $enclosures 0]
+      foreach enclosure $zero_enclosures_list {
+        if {![dict exists $enclosure above]} {
+          lappend lower_enclosures $enclosure
+        }
+      }
+    }
+    set upper_min -1
+    set lower_min -1
+    if {[llength $upper_enclosures] > 1} {
+      foreach enclosure $upper_enclosures {
+        # debug "upper enclosure - $enclosure"
+        set this_min [expr min([dict get $enclosure overlap1], [dict get $enclosure overlap2])]
+        if {$upper_min < 0 || $this_min < $upper_min} {
+          set upper_min $this_min
+          set upper_enc [list [dict get $enclosure overlap1] [dict get $enclosure overlap2]]
+          # debug "upper_enc: $upper_enc"
+        }
+      }
+    } else {
+      set enclosure [lindex $upper_enclosures 0]
+      set upper_enc [list [dict get $enclosure overlap1] [dict get $enclosure overlap2]]
+    }
+    if {[llength $lower_enclosures] > 1} {
+      foreach enclosure $lower_enclosures {
+        # debug "lower enclosure - $enclosure"
+        set this_min [expr min([dict get $enclosure overlap1], [dict get $enclosure overlap2])]
+        if {$lower_min < 0 || $this_min < $lower_min} {
+          set lower_min $this_min
+          set lower_enc [list [dict get $enclosure overlap1] [dict get $enclosure overlap2]]
+        }
+      }
+      # debug "[llength $lower_enclosures] lower_enc: $lower_enc"
+    } else {
+      set enclosure [lindex $lower_enclosures 0]
+      set lower_enc [list [dict get $enclosure overlap1] [dict get $enclosure overlap2]]
+      # debug "1 lower_enc: lower_enc: $lower_enc"
+    }
+    set selected_enclosure [list {*}$lower_enc {*}$upper_enc]
+  }
+  # debug "selected $selected_enclosure"
+  set min_lower_enclosure [expr min([lindex $selected_enclosure 0], [lindex $selected_enclosure 1])]
+  set max_lower_enclosure [expr max([lindex $selected_enclosure 0], [lindex $selected_enclosure 1])]
+  set min_upper_enclosure [expr min([lindex $selected_enclosure 2], [lindex $selected_enclosure 3])]
+  set max_upper_enclosure [expr max([lindex $selected_enclosure 2], [lindex $selected_enclosure 3])]
+  # debug "enclosures - min_lower $min_lower_enclosure max_lower $max_lower_enclosure min_upper $min_upper_enclosure max_upper $max_upper_enclosure"
+}
+
+proc select_via_info {lower} {
+  variable def_via_tech
+
+  set layer_name $lower
+  regexp {(.*)_PIN} $lower - layer_name
+
+  return [dict filter $def_via_tech script {rule_name rule} {expr {[dict get $rule lower layer] == $layer_name}}]
+}
+
+proc set_layer_info {layer_info} {
+  variable layers
+
+  set layers $layer_info
+}
+
+proc read_widthtable {layer_name} {
+  variable tech
+  variable def_units
+
+  set table {}
+  set layer [find_layer $layer_name]
+  set_prop_lines $layer LEF58_WIDTHTABLE
+
+  while {![empty_propline]} {
+    set line [read_propline]
+    set flags {}
+    if {[set idx [lsearch -exact $line ORTHOGONAL]] > -1} {
+      dict set flags orthogonal 1
+      set line [lreplace $line $idx $idx]
+    }
+    if {[set idx [lsearch -exact $line WRONGDIRECTION]] > -1} {
+      dict set flags wrongdirection 1
+      set line [lreplace $line $idx $idx]
+    }
+
+    regexp {WIDTHTABLE\s+(.*)} $line - widthtable
+    set widthtable [lmap x $widthtable {ord::microns_to_dbu $x}]
+
+    if {[dict exists $flags wrongdirection]} {
+      dict set table wrongdirection $widthtable
+    } else {
+      dict set table rightdirection $widthtable
+    }
+  }
+  return $table
+}
+
+proc get_widthtable {layer_name direction} {
+  variable layers
+
+  if {![dict exists $layers $layer_name widthtable]} {
+      dict set layers $layer_name widthtable [read_widthtable $layer_name]
+  }
+
+  if {![dict exists $layers $layer_name widthtable $direction]} {
+    if {$direction == "wrongdirection" && [dict exists $layers $layer_name widthtable rightdirection]} {
+      dict set layers $layer_name widthtable $direction [dict get $layers $layer_name widthtable rightdirection]
+    } else {
+      dict set layers $layer_name widthtable $direction {}
+    }
+  }
+
+  return [dict get $layers $layer_name widthtable $direction]
+}
+
+# Layers that have a widthtable will only support some width values, the widthtable defines the
+# set of widths that are allowed, or any width greater than or equal to the last value in the
+# table
+#
+
+proc adjust_width {widthtable width} {
+  if {[llength $widthtable] == 0} {return $width}
+  if {[lsearch -exact $widthtable $width] > -1} {return $width}
+  if {$width > [lindex $widthtable end]} {return $width}
+
+  foreach value $widthtable {
+    if {$value > $width} {
+      # debug "Adjust width from $width to $value"
+      return $value
+    }
+  }
+
+  return $width
+}
+
+proc get_adjusted_dX {layer width} {
+  if {[get_routing_direction $layer] == "ver"} {
+    # debug "Using rightdirection adjustment for layer $layer (dX)"
+    return [adjust_width [get_widthtable $layer rightdirection] $width]
+  } else {
+    # debug "Using wrongdirection adjustment for layer $layer (dX)"
+    return [adjust_width [get_widthtable $layer wrongdirection] $width]
+  }
+}
+
+proc get_adjusted_dY {layer height} {
+  if {[get_routing_direction $layer] == "hor"} {
+    # debug "Using rightdirection adjustment for layer $layer (dY)"
+    return [adjust_width [get_widthtable $layer rightdirection] $height]
+  } else {
+    # debug "Using wrongdirection adjustment for layer $layer (dY)"
+    return [adjust_width [get_widthtable $layer wrongdirection] $height]
+  }
+}
+
+proc get_arrayspacing_rule {layer_name} {
+  variable layers
+
+  if {![dict exists $layers $layer_name arrayspacing]} {
+    read_arrayspacing $layer_name
+  }
+
+  return [dict get $layers $layer_name arrayspacing]
+}
+
+proc use_arrayspacing {layer_name rows columns} {
+  set arrayspacing [get_arrayspacing_rule $layer_name]
+  # debug "$arrayspacing"
+  # debug "$rows $columns"
+  if {[llength $arrayspacing] == 0} {
+    # debug "No array spacing rule defined"
+    return 0
+  }
+  # debug "[dict keys [dict get $arrayspacing arraycuts]]"
+  if {[dict exists $arrayspacing arraycuts [expr min($rows,$columns)]]} {
+    # debug "Matching entry in arrayspacing"
+    return 1
+  }
+  if {min($rows,$columns) < [lindex [dict keys [dict get $arrayspacing arraycuts]] 0]} {
+    # debug "row/columns less than min array spacing"
+    return 0
+  }
+  if {min($rows,$columns) > [lindex [dict keys [dict get $arrayspacing arraycuts]] end]} {
+    # debug "row/columns greater than min array spacing"
+    return 1
+  }
+  # debug "default 1"
+  return 1
+}
+
+proc determine_num_via_columns {via_info constraints} {
+  variable upper_width
+  variable lower_width
+  variable upper_height
+  variable lower_height
+  variable lower_dir
+  variable upper_dir
+  variable min_lower_enclosure
+  variable max_lower_enclosure
+  variable min_upper_enclosure
+  variable max_upper_enclosure
+  variable cut_width
+  variable xcut_pitch
+  variable xcut_spacing
+  variable def_units
+
+  # What are the maximum number of columns that we can fit in this space?
+  set i 1
+  if {$lower_dir == "hor"} {
+    set via_width_lower [expr $cut_width + $xcut_pitch * ($i - 1) + 2 * $min_lower_enclosure]
+    set via_width_upper [expr $cut_width + $xcut_pitch * ($i - 1) + 2 * $max_upper_enclosure]
+  } else {
+    set via_width_lower [expr $cut_width + $xcut_pitch * ($i - 1) + 2 * $max_lower_enclosure]
+    set via_width_upper [expr $cut_width + $xcut_pitch * ($i - 1) + 2 * $min_upper_enclosure]
+  }
+  if {[dict exists $constraints cut_pitch]} {set xcut_pitch [expr round([dict get $constraints cut_pitch] * $def_units)]}
+
+  while {$via_width_lower <= $lower_width && $via_width_upper <= $upper_width} {
+    incr i
+    if {$lower_dir == "hor"} {
+      set via_width_lower [expr $cut_width + $xcut_pitch * ($i - 1) + 2 * $max_lower_enclosure]
+      set via_width_upper [expr $cut_width + $xcut_pitch * ($i - 1) + 2 * $min_upper_enclosure]
+    } else {
+      set via_width_lower [expr $cut_width + $xcut_pitch * ($i - 1) + 2 * $min_lower_enclosure]
+      set via_width_upper [expr $cut_width + $xcut_pitch * ($i - 1) + 2 * $max_upper_enclosure]
+    }
+  }
+  set xcut_spacing [expr $xcut_pitch - $cut_width]
+  set columns [expr max(1, $i - 1)]
+  # debug "cols $columns W: via_width_lower $via_width_lower >= lower_width $lower_width || via_width_upper $via_width_upper >= upper_width $upper_width"
+  if {[dict exists $constraints max_columns]} {
+    if {$columns > [dict get $constraints max_columns]} {
+      set columns [dict get $constraints max_columns]
+
+      set lower_concave_enclosure [get_concave_spacing_value [dict get $via_info cut layer] [dict get $via_info lower layer]]
+      # debug "$lower_concave_enclosure $max_lower_enclosure"
+      if {$lower_concave_enclosure > $max_lower_enclosure} {
+        set max_lower_enclosure $lower_concave_enclosure
+      }
+      set upper_concave_enclosure [get_concave_spacing_value [dict get $via_info cut layer] [dict get $via_info upper layer]]
+      # debug "$upper_concave_enclosure $max_upper_enclosure"
+      if {$upper_concave_enclosure > $max_upper_enclosure} {
+        set max_upper_enclosure $upper_concave_enclosure
+      }
+    }
+
+  }
+  # debug "Lower: [dict get $via_info lower layer] $lower_dir"
+  # debug "Upper: [dict get $via_info upper layer] $upper_dir"
+  if {[get_routing_direction [dict get $via_info upper layer]] == "ver"} {
+    if {[dict get $constraints stack_top] != [dict get $via_info upper layer]} {
+      # debug "Adjust width of [dict get $via_info upper layer]"
+      get_via_enclosure $via_info [expr min($lower_width,$lower_height)] [expr min([expr $cut_width + $xcut_pitch * ($columns - 1)],$upper_height)]
+      set upper_width [expr $cut_width + $xcut_pitch * ($columns - 1) + 2 * $min_upper_enclosure]
+    }
+  } 
+  if {[get_routing_direction [dict get $via_info lower layer]] == "ver"} {
+    if {[dict get $constraints stack_bottom] != [dict get $via_info lower layer]} {
+      # debug "Adjust width of [dict get $via_info lower layer]"
+      get_via_enclosure $via_info [expr min([expr $cut_width + $xcut_pitch * ($columns - 1)],$lower_height)] [expr min($upper_width,$upper_height)]
+      set lower_width [expr $cut_width + $xcut_pitch * ($columns - 1) + 2 * $min_lower_enclosure]
+    }
+  }
+  # debug "cols $columns W: lower $lower_width upper $upper_width"
+  set lower_width [get_adjusted_dX [dict get $via_info lower layer] $lower_width]
+  set upper_width [get_adjusted_dX [dict get $via_info upper layer] $upper_width]
+  # debug "cols $columns W: lower $lower_width upper $upper_width"
+
+  return $columns
+}
+
+proc determine_num_via_rows {via_info constraints} {
+  variable cut_height
+  variable ycut_pitch
+  variable ycut_spacing
+  variable upper_height
+  variable lower_height
+  variable lower_width
+  variable upper_width
+  variable lower_dir
+  variable upper_dir
+  variable min_lower_enclosure
+  variable max_lower_enclosure
+  variable min_upper_enclosure
+  variable max_upper_enclosure
+  variable def_units
+
+  # What are the maximum number of rows that we can fit in this space?
+  set i 1
+  if {$lower_dir == "hor"} {
+    set via_height_lower [expr $cut_height + $ycut_pitch * ($i - 1) + 2 * $min_lower_enclosure]
+    set via_height_upper [expr $cut_height + $ycut_pitch * ($i - 1) + 2 * $max_upper_enclosure]
+  } else {
+    set via_height_lower [expr $cut_height + $ycut_pitch * ($i - 1) + 2 * $max_lower_enclosure]
+    set via_height_upper [expr $cut_height + $ycut_pitch * ($i - 1) + 2 * $min_upper_enclosure]
+  }
+  if {[dict exists $constraints cut_pitch]} {set ycut_pitch [expr round([dict get $constraints cut_pitch] * $def_units)]}
+  while {$via_height_lower < $lower_height && $via_height_upper < $upper_height} {
+    incr i
+    if {$lower_dir == "hor"} {
+      set via_height_lower [expr $cut_height + $ycut_pitch * ($i - 1) + 2 * $min_lower_enclosure]
+      set via_height_upper [expr $cut_height + $ycut_pitch * ($i - 1) + 2 * $max_upper_enclosure]
+    } else {
+      set via_height_lower [expr $cut_height + $ycut_pitch * ($i - 1) + 2 * $max_lower_enclosure]
+      set via_height_upper [expr $cut_height + $ycut_pitch * ($i - 1) + 2 * $min_upper_enclosure]
+    }
+  }
+  set ycut_spacing [expr $ycut_pitch - $cut_height]
+  set rows [expr max(1,$i - 1)]
+  # debug "$rows H: $via_height_lower >= $lower_height && $via_height_upper >= $upper_height"
+  if {[dict exists $constraints max_rows]} {
+    if {$rows > [dict get $constraints max_rows]} {
+      set rows [dict get $constraints max_rows]
+
+      set lower_concave_enclosure [get_concave_spacing_value [dict get $via_info cut layer] [dict get $via_info lower layer]]
+      # debug "$lower_concave_enclosure $max_lower_enclosure"
+      if {$lower_concave_enclosure > $max_lower_enclosure} {
+        set max_lower_enclosure $lower_concave_enclosure
+      }
+      set upper_concave_enclosure [get_concave_spacing_value [dict get $via_info cut layer] [dict get $via_info upper layer]]
+      # debug "$upper_concave_enclosure $max_upper_enclosure"
+      if {$upper_concave_enclosure > $max_upper_enclosure} {
+        set max_upper_enclosure $upper_concave_enclosure
+      }
+
+    }
+  }
+  if {[get_routing_direction [dict get $via_info lower layer]] == "hor"} {
+    # debug "[dict get $constraints stack_bottom] != [dict get $via_info lower layer]"
+    if {[dict get $constraints stack_bottom] != [dict get $via_info lower layer]} {
+      # debug "Adjust height of [dict get $via_info lower layer]"
+      get_via_enclosure $via_info [expr min($lower_width,[expr $cut_height + $ycut_pitch * ($rows - 1)])] [expr min($upper_width,$upper_height)]
+      set lower_height [expr $cut_height + $ycut_pitch * ($rows - 1) + 2 * $min_lower_enclosure]
+      # debug "modify lower_height to $lower_height ($cut_height + $ycut_pitch * ($rows - 1) + 2 * $min_lower_enclosure"
+    }
+  } 
+  if {[get_routing_direction [dict get $via_info upper layer]] == "hor"} {
+    # debug "[dict get $constraints stack_top] != [dict get $via_info upper layer]"
+    if {[dict get $constraints stack_top] != [dict get $via_info upper layer]} {
+      # debug "Adjust height of [dict get $via_info upper layer]"
+      get_via_enclosure $via_info [expr min($lower_width,$lower_height)] [expr min($upper_width,[expr $cut_height + $ycut_pitch * ($rows - 1)])]
+      set upper_height [expr $cut_height + $ycut_pitch * ($rows - 1) + 2 * $min_upper_enclosure]
+      # debug "modify upper_height to $upper_height ($cut_height + $ycut_pitch * ($rows - 1) + 2 * $min_upper_enclosure"
+    }
+  }
+  # debug "$rows H: lower $lower_height upper $upper_height"
+  set lower_height [get_adjusted_dY [dict get $via_info lower layer] $lower_height]
+  set upper_height [get_adjusted_dY [dict get $via_info upper layer] $upper_height]
+  # debug "$rows H: lower $lower_height upper $upper_height"
+
+  return $rows
+}
+
+proc init_via_width_height {via_info lower_layer width height constraints} {
+  variable def_units
+  variable upper_width
+  variable lower_width
+  variable upper_height
+  variable lower_height
+  variable lower_dir
+  variable upper_dir
+  variable min_lower_enclosure
+  variable max_lower_enclosure
+  variable min_upper_enclosure
+  variable max_upper_enclosure
+  variable cut_width
+  variable cut_height
+  variable xcut_pitch
+  variable ycut_pitch
+  variable xcut_spacing
+  variable ycut_spacing
+
+  set upper_layer [dict get $via_info upper layer]
+
+  set xcut_pitch [lindex [dict get $via_info cut spacing] 0]
+  set ycut_pitch [lindex [dict get $via_info cut spacing] 0]
+
+  set cut_width   [lindex [dict get $via_info cut size] 0]
+  set cut_height  [lindex [dict get $via_info cut size] 1]
+
+  if {[dict exists $constraints split_cuts $lower_layer]} {
+    if {[get_dir $lower_layer] == "hor"} {
+      set ycut_pitch [expr round([dict get $constraints split_cuts $lower_layer] * $def_units)]
+    } else {
+      set xcut_pitch [expr round([dict get $constraints split_cuts $lower_layer] * $def_units)]
+    }
+  }
+
+  if {[dict exists $constraints split_cuts $upper_layer]} {
+    if {[get_dir $upper_layer] == "hor"} {
+      set ycut_pitch [expr round([dict get $constraints split_cuts $upper_layer] * $def_units)]
+    } else {
+      set xcut_pitch [expr round([dict get $constraints split_cuts $upper_layer] * $def_units)]
+    }
+  }
+
+  if {[dict exists $constraints width $lower_layer]} {
+    if {[get_dir $lower_layer] == "hor"} {
+      set lower_height [expr round([dict get $constraints width $lower_layer] * $def_units)]
+      set lower_width  [get_adjusted_dX $lower_layer $width]
+    } else {
+      set lower_width [expr round([dict get $constraints width $lower_layer] * $def_units)]
+      set lower_height [get_adjusted_dY $lower_layer $height]
+    }
+  } else {
+    # Adjust the width and height values to the next largest allowed value if necessary
+    set lower_width  [get_adjusted_dX $lower_layer $width]
+    set lower_height [get_adjusted_dY $lower_layer $height]
+  }
+  if {[dict exists $constraints width $upper_layer]} {
+    if {[get_dir $upper_layer] == "hor"} {
+      set upper_height [expr round([dict get $constraints width $upper_layer] * $def_units)]
+      set upper_width  [get_adjusted_dX $upper_layer $width]
+    } else {
+      set upper_width [expr round([dict get $constraints width $upper_layer] * $def_units)]
+      set upper_height [get_adjusted_dY $upper_layer $height]
+    }
+  } else {
+    set upper_width  [get_adjusted_dX $upper_layer $width]
+    set upper_height [get_adjusted_dY $upper_layer $height]
+  }
+  # debug "lower (width $lower_width height $lower_height) upper (width $upper_width height $upper_height)"
+  # debug "min - \[expr min($lower_width,$lower_height,$upper_width,$upper_height)\]"
+}
+
+proc get_enclosure_by_direction {layer xenc yenc max_enclosure min_enclosure} {
+  set info {}
+  if {$xenc > $max_enclosure && $yenc > $min_enclosure || $xenc > $min_enclosure && $yenc > $max_enclosure} {
+    # If the current enclosure values meet the min/max enclosure requirements either way round, then keep
+    # the current enclsoure settings
+    dict set info xEnclosure $xenc
+    dict set info yEnclosure $yenc
+  } else {
+    # Enforce min/max enclosure rule, with max_enclosure along the preferred direction of the layer.
+    if {[get_dir $layer] == "hor"} {
+      dict set info xEnclosure [expr max($xenc,$max_enclosure)]
+      dict set info yEnclosure [expr max($yenc,$min_enclosure)]
+    } else {
+      dict set info xEnclosure [expr max($xenc,$min_enclosure)]
+      dict set info yEnclosure [expr max($yenc,$max_enclosure)]
+    }
+  }
+
+  return $info
+}
+
+proc via_generate_rule {viarule_name via_info rule_name rows columns constraints} {
+  variable xcut_pitch
+  variable ycut_pitch
+  variable xcut_spacing
+  variable ycut_spacing
+  variable cut_height
+  variable cut_width
+  variable upper_width
+  variable lower_width
+  variable upper_height
+  variable lower_height
+  variable lower_dir
+  variable min_lower_enclosure
+  variable max_lower_enclosure
+  variable min_upper_enclosure
+  variable max_upper_enclosure
+
+  set lower_enc_width  [expr round(($lower_width  - ($cut_width   + $xcut_pitch * ($columns - 1))) / 2)]
+  set lower_enc_height [expr round(($lower_height - ($cut_height  + $ycut_pitch * ($rows    - 1))) / 2)]
+  set upper_enc_width  [expr round(($upper_width  - ($cut_width   + $xcut_pitch * ($columns - 1))) / 2)]
+  set upper_enc_height [expr round(($upper_height - ($cut_height  + $ycut_pitch * ($rows    - 1))) / 2)]
+
+  set lower [get_enclosure_by_direction [dict get $via_info lower layer] $lower_enc_width $lower_enc_height $max_lower_enclosure $min_lower_enclosure]
+  set upper [get_enclosure_by_direction [dict get $via_info upper layer] $upper_enc_width $upper_enc_height $max_upper_enclosure $min_upper_enclosure]
+  # debug "rule $rule_name"
+  # debug "lower: width $lower_width height $lower_height"
+  # debug "lower: enc_width $lower_enc_width enc_height $lower_enc_height enclosure_rule $max_lower_enclosure $min_lower_enclosure"
+  # debug "lower: enclosure [dict get $lower xEnclosure] [dict get $lower yEnclosure]"
+  # debug "upper: enc_width $upper_enc_width enc_height $upper_enc_height enclosure_rule $max_upper_enclosure $min_upper_enclosure"
+  # debug "upper: enclosure [dict get $upper xEnclosure] [dict get $upper yEnclosure]"
+
+  return [list [list \
+    name $rule_name \
+    rule $viarule_name \
+    cutsize [dict get $via_info cut size] \
+    layers [list [dict get $via_info lower layer] [dict get $via_info cut layer] [dict get $via_info upper layer]] \
+    cutspacing [list $xcut_spacing $ycut_spacing] \
+    rowcol [list $rows $columns] \
+    lower_rect [list [expr -1 * $lower_width / 2] [expr -1 * $lower_height / 2] [expr $lower_width / 2] [expr $lower_height / 2]] \
+    upper_rect [list [expr -1 * $upper_width / 2] [expr -1 * $upper_height / 2] [expr $upper_width / 2] [expr $upper_height / 2]] \
+    enclosure [list \
+      [dict get $lower xEnclosure] \
+      [dict get $lower yEnclosure] \
+      [dict get $upper xEnclosure] \
+      [dict get $upper yEnclosure] \
+    ] \
+    origin_x 0 origin_y 0
+  ]]
+}
+
+proc via_generate_array_rule {viarule_name via_info rule_name rows columns} {
+  variable xcut_pitch
+  variable ycut_pitch
+  variable xcut_spacing
+  variable ycut_spacing
+  variable cut_height
+  variable cut_width
+  variable upper_width
+  variable lower_width
+  variable upper_height
+  variable lower_height
+  variable min_lower_enclosure
+  variable max_lower_enclosure
+  variable min_upper_enclosure
+  variable max_upper_enclosure
+
+  # We need array vias -
+  # if the min(rows,columns) > ARRAYCUTS
+  #   determine which direction gives best number of CUTs wide using min(ARRAYCUTS)
+  #   After adding ARRAYs, is there space for more vias
+  #   Add vias to the rule with appropriate origin setting
+  # else
+  #   add a single via with min(rows,columns) cuts - hor/ver as required
+
+
+  set spacing_rule [get_arrayspacing_rule [dict get $via_info cut layer]]
+  set array_size [expr min($rows, $columns)]
+
+  set lower_enc_width  [expr round(($lower_width  - ($cut_width   + $xcut_pitch * ($columns - 1))) / 2)]
+  set lower_enc_height [expr round(($lower_height - ($cut_height  + $ycut_pitch * ($rows    - 1))) / 2)]
+  set upper_enc_width  [expr round(($upper_width  - ($cut_width   + $xcut_pitch * ($columns - 1))) / 2)]
+  set upper_enc_height [expr round(($upper_height - ($cut_height  + $ycut_pitch * ($rows    - 1))) / 2)]
+
+  if {$array_size > [lindex [dict keys [dict get $spacing_rule arraycuts]] end]} {
+    # debug "Multi-viaArrayspacing rule"
+    set use_array_size [lindex [dict keys [dict get $spacing_rule arraycuts]] 0]
+    foreach other_array_size [lrange [dict keys [dict get $spacing_rule arraycuts]] 1 end] {
+      if {$array_size % $use_array_size > $array_size % $other_array_size} {
+        set use_array_size $other_array_size
+      }
+    }
+    set num_arrays [expr $array_size / $use_array_size]
+    set array_spacing [expr max($xcut_spacing,$ycut_spacing,[dict get $spacing_rule arraycuts $use_array_size spacing])]
+
+    set rule [list \
+      rule $viarule_name \
+      cutsize [dict get $via_info cut size] \
+      layers [list [dict get $via_info lower layer] [dict get $via_info cut layer] [dict get $via_info upper layer]] \
+      cutspacing [list $xcut_spacing $ycut_spacing] \
+      lower_rect [list [expr -1 * $lower_width / 2] [expr -1 * $lower_height / 2] [expr $lower_width / 2] [expr $lower_height / 2]] \
+      upper_rect [list [expr -1 * $upper_width / 2] [expr -1 * $upper_height / 2] [expr $upper_width / 2] [expr $upper_height / 2]] \
+      origin_x 0 \
+      origin_y 0 \
+    ]
+    # debug "$rule"
+    set rule_list {}
+    if {$array_size == $rows} {
+      # Split into num_arrays rows of arrays
+      set array_min_size [expr [lindex [dict get $via_info cut size] 0] * $use_array_size + [dict get $spacing_rule cutspacing] * ($use_array_size - 1)]
+      set total_array_size [expr $array_min_size * $num_arrays + $array_spacing * ($num_arrays - 1)]
+      # debug "Split into $num_arrays rows of arrays"
+
+      set lower_enc_height [expr round(($lower_height - ($cut_height  + $ycut_pitch * ($use_array_size - 1))) / 2)]
+      set upper_enc_height [expr round(($upper_height - ($cut_height  + $ycut_pitch * ($use_array_size - 1))) / 2)]
+
+      set lower_enc [get_enclosure_by_direction [dict get $via_info lower layer] $lower_enc_width $lower_enc_height $max_lower_enclosure $min_lower_enclosure]
+      set upper_enc [get_enclosure_by_direction [dict get $via_info upper layer] $upper_enc_width $upper_enc_height $max_upper_enclosure $min_upper_enclosure]
+
+      dict set rule rowcol [list $use_array_size $columns]
+      dict set rule name "[dict get $via_info cut layer]_ARRAY_${use_array_size}X${columns}"
+      dict set rule enclosure [list \
+        [dict get $lower_enc xEnclosure] \
+        [dict get $lower_enc yEnclosure] \
+        [dict get $upper_enc xEnclosure] \
+        [dict get $upper_enc yEnclosure] \
+      ]
+
+      set y [expr $array_min_size / 2 - $total_array_size / 2]
+      for {set i 0} {$i < $num_arrays} {incr i} {
+        dict set rule origin_y $y
+        lappend rule_list $rule
+        set y [expr $y + $array_spacing + $array_min_size]
+      }
+    } else {
+      # Split into num_arrays columns of arrays
+      set array_min_size [expr [lindex [dict get $via_info cut size] 1] * $use_array_size + [dict get $spacing_rule cutspacing] * ($use_array_size - 1)]
+      set total_array_size [expr $array_min_size * $num_arrays + $array_spacing * ($num_arrays - 1)]
+      # debug "Split into $num_arrays columns of arrays"
+
+      set lower_enc_width  [expr round(($lower_width  - ($cut_width   + $xcut_pitch * ($use_array_size - 1))) / 2)]
+      set upper_enc_width  [expr round(($upper_width  - ($cut_width   + $xcut_pitch * ($use_array_size - 1))) / 2)]
+
+      set lower_enc [get_enclosure_by_direction [dict get $via_info lower layer] $lower_enc_width $lower_enc_height $max_lower_enclosure $min_lower_enclosure]
+      set upper_enc [get_enclosure_by_direction [dict get $via_info upper layer] $upper_enc_width $upper_enc_height $max_upper_enclosure $min_upper_enclosure]
+
+      dict set rule rowcol [list $rows $use_array_size]
+      dict set rule name "[dict get $via_info cut layer]_ARRAY_${rows}X${use_array_size}"
+      dict set rule enclosure [list \
+        [dict get $lower_enc xEnclosure] \
+        [dict get $lower_enc yEnclosure] \
+        [dict get $upper_enc xEnclosure] \
+        [dict get $upper_enc yEnclosure] \
+      ]
+
+      set x [expr $array_min_size / 2 - $total_array_size / 2]
+      for {set i 0} {$i < $num_arrays} {incr i} {
+        dict set rule origin_x $x
+        lappend rule_list $rule
+        set x [expr $x + $array_spacing + $array_min_size]
+      }
+    }
+  } else {
+    # debug "Arrayspacing rule"
+    set lower_enc [get_enclosure_by_direction [dict get $via_info lower layer] $lower_enc_width $lower_enc_height $max_lower_enclosure $min_lower_enclosure]
+    set upper_enc [get_enclosure_by_direction [dict get $via_info upper layer] $upper_enc_width $upper_enc_height $max_upper_enclosure $min_upper_enclosure]
+
+    set rule [list \
+      name $rule_name \
+      rule $viarule_name \
+      cutsize [dict get $via_info cut size] \
+      layers [list [dict get $via_info lower layer] [dict get $via_info cut layer] [dict get $via_info upper layer]] \
+      cutspacing [list $xcut_spacing $ycut_spacing] \
+      rowcol [list $rows $columns] \
+      enclosure [list \
+        [dict get $lower_enc xEnclosure] \
+        [dict get $lower_enc yEnclosure] \
+        [dict get $upper_enc xEnclosure] \
+        [dict get $upper_enc yEnclosure] \
+      ] \
+      origin_x 0 \
+      origin_y 0 \
+    ]
+    set rule_list [list $rule]
+  }
+
+  return $rule_list
+}
+
+proc via_split_cuts_rule {rule_name via_info rows columns constraints} {
+  variable tech
+  variable def_units
+  variable min_lower_enclosure
+  variable max_lower_enclosure
+  variable min_upper_enclosure
+  variable max_upper_enclosure
+  variable cut_width
+  variable cut_height
+  variable xcut_pitch
+  variable ycut_pitch
+  variable xcut_spacing
+  variable ycut_spacing
+
+  set lower_rects {}
+  set cut_rects   {}
+  set upper_rects {}
+
+  set lower [dict get $via_info lower layer]
+  set upper [dict get $via_info upper layer]
+  # debug $via_info
+  # debug "lower $lower upper $upper"
+
+  set rule {}
+  set rule [list \
+    rule $rule_name \
+    cutsize [dict get $via_info cut size] \
+    layers [list $lower [dict get $via_info cut layer] $upper] \
+    cutspacing [list $xcut_spacing $ycut_spacing] \
+    rowcol [list 1 1] \
+  ]
+
+  # Enclosure was calculated from full width of intersection - need to recalculate for min cut size.
+  get_via_enclosure $via_info 0 0
+
+  # Area is stored in real units, adjust to def_units
+  set lower_area [expr round([[find_layer $lower] getArea] * $def_units * $def_units)]
+  set upper_area [expr round([[find_layer $upper] getArea] * $def_units * $def_units)]
+
+  if {[get_dir $lower] == "hor"} {
+    set lower_height [expr $cut_height + $min_lower_enclosure]
+    set lower_width  [expr $cut_width  + $max_lower_enclosure]
+    set upper_height [expr $cut_height + $max_upper_enclosure]
+    set upper_width  [expr $cut_width  + $min_upper_enclosure]
+
+    if {[dict exists $constraints split_cuts $lower]} {
+      set lower_width  [expr $lower_area / $lower_height]
+      if {$lower_width % 2 == 1} {incr lower_width}
+      set max_lower_enclosure [expr max(($lower_width - $cut_width) / 2, $max_lower_enclosure)]
+    }
+
+    if {[dict exists $constraints split_cuts $upper]} {
+      set upper_height [expr $upper_area / $upper_width]
+      if {$upper_height % 2 == 1} {incr upper_height}
+      set max_upper_enclosure [expr max(($upper_height - $cut_height) / 2, $max_upper_enclosure)]
+    }
+
+    set width [expr $max_lower_enclosure * 2 + $cut_width]
+    set height [expr $max_upper_enclosure * 2 + $cut_width]
+
+    dict set rule name [get_viarule_name $lower $width $height]
+    dict set rule enclosure [list $max_lower_enclosure $min_lower_enclosure $min_upper_enclosure $max_upper_enclosure]
+  } else {
+    set lower_height [expr $cut_height + $max_lower_enclosure]
+    set lower_width  [expr $cut_width  + $min_lower_enclosure]
+    set upper_height [expr $cut_height + $min_upper_enclosure]
+    set upper_width  [expr $cut_width  + $max_upper_enclosure]
+
+    if {[dict exists $constraints split_cuts $lower]} {
+      set lower_width  [expr $cut_width + $min_lower_enclosure]
+      set lower_height [expr $cut_width + $max_lower_enclosure]
+      set min_lower_length [expr $lower_area / $lower_width]
+      if {$min_lower_length % 2 == 1} {incr min_lower_length}
+      set max_lower_enclosure [expr max(($min_lower_length - $cut_width) / 2, $max_lower_enclosure)]
+    }
+
+    if {[dict exists $constraints split_cuts $upper]} {
+      set upper_width  [expr $cut_height + $max_upper_enclosure]
+      set upper_height [expr $cut_height + $min_upper_enclosure]
+      set min_upper_length [expr $upper_area / $upper_height]
+      if {$min_upper_length % 2 == 1} {incr min_upper_length}
+      set max_upper_enclosure [expr max(($min_upper_length - $cut_height) / 2, $max_upper_enclosure)]
+    }
+
+    set width [expr $max_upper_enclosure * 2 + $cut_width]
+    set height [expr $max_lower_enclosure * 2 + $cut_width]
+
+    dict set rule name [get_viarule_name $lower $width $height]
+    dict set rule enclosure [list $min_lower_enclosure $max_lower_enclosure $max_upper_enclosure $min_upper_enclosure]
+  }
+  dict set rule lower_rect [list [expr -1 * $lower_width / 2] [expr -1 * $lower_height / 2] [expr $lower_width / 2] [expr $lower_height / 2]]
+  dict set rule upper_rect [list [expr -1 * $upper_width / 2] [expr -1 * $upper_height / 2] [expr $upper_width / 2] [expr $upper_height / 2]]
+  # debug "min_lower_enclosure $min_lower_enclosure"
+  # debug "lower $lower upper $upper enclosure [dict get $rule enclosure]"
+
+  for {set i 0} {$i < $rows} {incr i} {
+    for {set j 0} {$j < $columns} {incr j} {
+      set centre_x [expr round(($j - (($columns - 1) / 2.0)) * $xcut_pitch)]
+      set centre_y [expr round(($i - (($rows - 1)    / 2.0)) * $ycut_pitch)]
+
+      dict set rule origin_x $centre_x
+      dict set rule origin_y $centre_y
+      lappend rule_list $rule
+    }
+  }
+  # debug "split into [llength $rule_list] vias"
+  return $rule_list
+}
+
+# viarule structure:
+# {
+#    name <via_name>
+#    rule <via_rule_name>
+#    cutsize {<cut_size>}
+#    layers {<lower> <cut> <upper>}
+#    cutspacing {<x_spacing> <y_spacing>}
+#    rowcol {<rows> <columns>}
+#    origin_x <x_location>
+#    origin_y <y_location>
+#    enclosure {<x_lower_enclosure> <y_lower_enclosure> <x_upper_enclosure> <y_upper_enclosure>}
+#    lower_rect {<llx> <lly> <urx> <ury>}
+#  }
+
+# Given the via rule expressed in via_info, what is the via with the largest cut area that we can make
+# Try using a via generate rule
+proc get_via_option {viarule_name via_info lower width height constraints} {
+  variable upper_width
+  variable lower_width
+  variable upper_height
+  variable lower_height
+  variable lower_dir
+  variable upper_dir
+  variable min_lower_enclosure
+  variable max_lower_enclosure
+  variable min_upper_enclosure
+  variable max_upper_enclosure
+  variable default_cutclass
+  variable grid_data
+  variable via_location
+  variable def_units
+
+  set upper [dict get $via_info upper layer]
+
+  # debug "{$lower $width $height}"
+
+  set lower_dir [get_dir $lower]
+  set upper_dir [get_dir $upper]
+
+  init_via_width_height $via_info $lower $width $height $constraints
+  # debug "lower: $lower, width: $width, height: $height, lower_width: $lower_width, lower_height: $lower_height"
+  get_via_enclosure $via_info [expr min($lower_width,$lower_height)] [expr min($upper_width,$upper_height)]
+
+  # debug "split cuts? [dict exists $constraints split_cuts]"
+  # debug "lower $lower upper $upper"
+  # debug [dict get $via_info cut layer]
+
+  # Determines the maximum number of rows and columns that can fit into this width/height
+  set columns [determine_num_via_columns $via_info $constraints]
+  set rows    [determine_num_via_rows    $via_info $constraints]
+
+  # debug "columns: $columns, rows: $rows"	  
+  # debug "lower_width $lower_width lower_height: $lower_height, min_lower_enclosure $min_lower_enclosure"
+  # debug "upper_width $upper_width upper_height: $upper_height, min_upper_enclosure $min_upper_enclosure"
+
+  if {[dict exists $constraints split_cuts] && ([lsearch -exact [dict get $constraints split_cuts] $lower] > -1 || [lsearch -exact [dict get $constraints split_cuts] $upper] > -1)} {
+    # debug "via_split_cuts_rule"
+    set rules [via_split_cuts_rule $viarule_name $via_info $rows $columns $constraints]
+  } elseif {[use_arrayspacing [dict get $via_info cut layer] $rows $columns]} {
+    # debug "via_generate_array_rule"
+    set rules [via_generate_array_rule $viarule_name $via_info [get_viarule_name $lower $width $height] $rows $columns]
+  } else {
+    # debug "via_generate_rule"
+    set rules [via_generate_rule $viarule_name $via_info [get_viarule_name $lower $width $height] $rows $columns $constraints]
+  }
+
+  # Check minimum_cuts
+  set checked_rules {}
+  foreach via_rule $rules {
+    # debug "$via_rule"
+    set num_cuts [expr [lindex [dict get $via_rule rowcol] 0] * [lindex [dict get $via_rule rowcol] 1]]
+    if {[dict exists $default_cutclass [lindex [dict get $via_rule layers] 1]]} {
+      set cut_class [dict get $default_cutclass [lindex [dict get $via_rule layers] 1]]
+    } else {
+      set cut_class "NONE"
+    }
+    set lower_layer [lindex [dict get $via_rule layers] 0]
+    if {[dict exists $constraints stack_bottom]} {
+      if {[dict exists $grid_data straps $lower_layer] || [dict exists $grid_data rails $lower_layer]} {
+        set lower_width [get_grid_wire_width $lower_layer]
+      } else {
+        set lower_rect [dict get $via_rule lower_rect]
+        set lower_width [expr min(([lindex $lower_rect 2] - [lindex $lower_rect 0]), ([lindex $lower_rect 3] - [lindex $lower_rect 1]))]
+      }
+    } else {
+      set lower_rect [dict get $via_rule lower_rect]
+      set lower_width [expr min(([lindex $lower_rect 2] - [lindex $lower_rect 0]), ([lindex $lower_rect 3] - [lindex $lower_rect 1]))]
+    }
+    set min_cut_rule [get_minimumcuts $lower_layer $lower_width fromabove $cut_class]
+    if {$num_cuts < $min_cut_rule} {
+      utl::warn "PDN" 38 "Illegal via: number of cuts ($num_cuts), does not meet minimum cut rule ($min_cut_rule) for $lower_layer to $cut_class with width [expr 1.0 * $lower_width / $def_units]."
+      dict set via_rule illegal 1
+    } else {
+      # debug "Legal number of cuts ($num_cuts) meets minimum cut rule ($min_cut_rule) for $lower_layer, $lower_width, $cut_class"
+    }
+
+    set upper_layer [lindex [dict get $via_rule layers] 2]
+    if {[dict exists $constraints stack_top]} {
+      if {[dict exists $grid_data straps $upper_layer width] || [dict exists $grid_data rails $upper_layer width]} {
+        set upper_width [get_grid_wire_width $upper_layer]
+      } else {
+        set upper_rect [dict get $via_rule upper_rect]
+        set upper_width [expr min(([lindex $upper_rect 2] - [lindex $upper_rect 0]), ([lindex $upper_rect 3] - [lindex $upper_rect 1]))]
+      }
+    } else {
+      set upper_rect [dict get $via_rule upper_rect]
+      set upper_width [expr min(([lindex $upper_rect 2] - [lindex $upper_rect 0]), ([lindex $upper_rect 3] - [lindex $upper_rect 1]))]
+    }
+    set min_cut_rule [get_minimumcuts $upper_layer $upper_width frombelow $cut_class]
+
+    if {$num_cuts < $min_cut_rule} {
+      utl::warn "PDN" 39 "Illegal via: number of cuts ($num_cuts), does not meet minimum cut rule ($min_cut_rule) for $upper_layer to $cut_class with width [expr 1.0 * $upper_width / $def_units]."
+      dict set via_rule illegal 1
+    } else {
+      # debug "Legal number of cuts ($num_cuts) meets minimum cut rule ($min_cut_rule) for $upper_layer, $upper_width $cut_class"
+    }
+    if {[dict exists $via_rule illegal]} {
+      utl::warn "PDN" 36 "Attempt to add illegal via at : ([expr 1.0 * [lindex $via_location 0] / $def_units] [expr 1.0 * [lindex $via_location 1] / $def_units]), via will not be added."
+    }
+    lappend checked_rules $via_rule
+  }
+
+  return $checked_rules
+}
+
+proc get_viarule_name {lower width height} {
+  set rules [select_via_info $lower]
+  if {[llength $rules] > 0} {
+    set first_key [lindex [dict keys $rules] 0]
+    #if {![dict exists $rules $first_key cut layer]} {
+    #  debug "$lower $width $height"
+    #  debug "$rules"
+    #  debug "$first_key"
+    #}
+    set cut_layer [dict get $rules $first_key cut layer]
+  } else {
+    set cut_layer $lower
+  }
+
+  return ${cut_layer}_${width}x${height}
+}
+
+proc get_cut_area {rule} {
+  set area 0
+  foreach via $rule {
+    set area [expr [lindex [dict get $via rowcol] 0] * [lindex [dict get $via rowcol] 0] * [lindex [dict get $via cutsize] 0] * [lindex [dict get $via cutsize] 1]]
+  }
+  return $area
+}
+
+proc select_rule {rule1 rule2} {
+  if {[get_cut_area $rule2] > [get_cut_area $rule1]} {
+    return $rule2
+  }
+  return $rule1
+}
+
+proc connection_specifies_fixed_via {constraints lower} {
+  if {[dict exists $constraints use_fixed_via]} {
+    return [dict exists $constraints use_fixed_via $lower]
+  }
+  return 0
+}
+
+proc get_via {lower width height constraints} {
+  # First cur will assume that all crossing points (x y) are on grid for both lower and upper layers
+  # TODO: Refine the algorithm to cope with offgrid intersection points
+  variable physical_viarules
+
+  set rule_name [get_viarule_name $lower $width $height]
+
+  if {![dict exists $physical_viarules $rule_name]} {
+    set selected_rule {}
+    # debug "$constraints"
+    if {[connection_specifies_fixed_via $constraints $lower]} {
+      # debug "Using fixed_via for $rule_name"
+      set via_name [dict get $constraints use_fixed_via $lower]
+      dict set physical_viarules $rule_name [list [list name $via_name fixed $via_name origin_x 0 origin_y 0 layers [list $lower "cut" "upper"]]]
+    } else {
+      dict for {name rule} [select_via_info $lower] {
+        set result [get_via_option $name $rule $lower $width $height $constraints]
+        if {$selected_rule == {}} {
+          set selected_rule $result
+        } else {
+          # Choose the best between selected rule and current result, the winner becomes the new selected rule
+          set selected_rule [select_rule $selected_rule $result]
+        }
+      }
+      dict set physical_viarules $rule_name $selected_rule
+      # debug "Via [dict size $physical_viarules]: $rule_name"
+    }
+  }
+
+  return $rule_name
+}
+
+proc instantiate_via {physical_via_name x y constraints} {
+  variable physical_viarules
+  variable block
+  variable layers
+
+  set via_insts {}
+
+  foreach via [dict get $physical_viarules $physical_via_name] {
+    # debug "via x $x y $y $via"
+
+    # Dont instantiate illegal vias
+    if {[dict exists $via illegal]} {continue}
+
+    set x_location [expr $x + [dict get $via origin_x]]
+    set y_location [expr $y + [dict get $via origin_y]]
+
+    set lower_layer_name [lindex [dict get $via layers] 0]
+    set upper_layer_name [lindex [dict get $via layers] 2]
+
+    if {[dict exists $constraints ongrid]} {
+      if {[lsearch -exact [dict get $constraints ongrid] $lower_layer_name] > -1} {
+        if {[get_dir $lower_layer_name] == "hor"} {
+          set y_pitch [dict get $layers $lower_layer_name pitch]
+          set y_offset [dict get $layers $lower_layer_name offsetY]
+
+          set y_location [expr ($y - $y_offset + $y_pitch / 2) / $y_pitch * $y_pitch + $y_offset + [dict get $via origin_y]]
+        } else {
+          set x_pitch [dict get $layers $lower_layer_name pitch]
+          set x_offset [dict get $layers $lower_layer_name offsetX]
+
+          set x_location [expr ($x - $x_offset + $x_pitch / 2) / $x_pitch * $x_pitch + $x_offset + [dict get $via origin_x]]
+        }
+      }
+      if {[lsearch -exact [dict get $constraints ongrid] $upper_layer_name] > -1} {
+        if {[get_dir $lower_layer_name] == "hor"} {
+          set x_pitch [dict get $layers $upper_layer_name pitch]
+          set x_offset [dict get $layers $upper_layer_name offsetX]
+
+          set x_location [expr ($x - $x_offset + $x_pitch / 2) / $x_pitch * $x_pitch + $x_offset + [dict get $via origin_x]]
+        } else {
+          set y_pitch [dict get $layers $upper_layer_name pitch]
+          set y_offset [dict get $layers $upper_layer_name offsetY]
+
+          set y_location [expr ($y - $y_offset + $y_pitch / 2) / $y_pitch * $y_pitch + $y_offset + [dict get $via origin_y]]
+        }
+      }
+    }
+    # debug "x: $x -> $x_location"
+    # debug "y: $y -> $y_location"
+
+    dict set via x $x_location
+    dict set via y $y_location
+
+    lappend via_insts $via
+  }
+  return $via_insts
+}
+
+proc generate_vias {layer1 layer2 intersections connection} {
+  variable logical_viarules
+  variable metal_layers
+  variable via_location
+  variable tech
+
+  set constraints {}
+  if {[dict exists $connection constraints]} {
+    set constraints [dict get $connection constraints]
+  }
+  if {[dict exists $connection fixed_vias]} {
+    foreach via_name [dict get $connection fixed_vias] {
+      if {[set via [$tech findVia $via_name]] != "NULL"} {
+        set lower_layer_name [[$via getBottomLayer] getName]
+        dict set constraints use_fixed_via $lower_layer_name $via_name
+      } else {
+        utl::warn "PDN" 63 "Via $via_name specified in the grid specification does not exist in this technology."
+      }
+    }
+  }
+
+  # debug "    Constraints: $constraints"
+  set vias {}
+  set layer1_name $layer1
+  set layer2_name $layer2
+  regexp {(.*)_PIN_(hor|ver)} $layer1 - layer1_name layer1_direction
+
+  set i1 [lsearch -exact $metal_layers $layer1_name]
+  set i2 [lsearch -exact $metal_layers $layer2_name]
+  if {$i1 == -1} {utl::error "PDN" 22 "Cannot find lower metal layer $layer1."}
+  if {$i2 == -1} {utl::error "PDN" 23 "Cannot find upper metal layer $layer2."}
+
+  # For each layer between l1 and l2, add vias at the intersection
+  # debug "  # Intersections [llength $intersections]"
+  set count 0
+  foreach intersection $intersections {
+    if {![dict exists $logical_viarules [dict get $intersection rule]]} {
+      utl::error "PDN" 24 "Missing logical viarule [dict get $intersection rule].\nAvailable logical viarules [dict keys $logical_viarules]."
+    }
+    set logical_rule [dict get $logical_viarules [dict get $intersection rule]]
+
+    set x [dict get $intersection x]
+    set y [dict get $intersection y]
+    set width  [dict get $logical_rule width]
+    set height  [dict get $logical_rule height]
+    set via_location [list $x $y]
+
+    set connection_layers [lrange $metal_layers $i1 [expr $i2 - 1]]
+    # debug "  # Connection layers: [llength $connection_layers]"
+    # debug "  Connection layers: $connection_layers"
+    dict set constraints stack_top $layer2_name
+    dict set constraints stack_bottom $layer1_name
+    foreach lay $connection_layers {
+      set via_name [get_via $lay $width $height $constraints]
+      foreach via [instantiate_via $via_name $x $y $constraints] {
+        lappend vias $via
+      }
+    }
+
+    incr count
+    #if {$count % 1000 == 0} {
+    #  debug "  # $count / [llength $intersections]"
+    #}
+  }
+
+  return $vias
+}
+
+proc get_layers_from_to {from to} {
+  variable metal_layers
+
+  set layers {}
+  for {set i [lsearch -exact $metal_layers $from]} {$i <= [lsearch -exact $metal_layers $to]} {incr i} {
+    lappend layers [lindex $metal_layers $i]
+  }
+  return $layers
+}
+
+proc get_grid_channel_layers {} {
+  variable grid_data
+
+  set channel_layers {}
+  if {[dict exists $grid_data rails]} {
+    lappend channel_layers [lindex [dict keys [dict get $grid_data rails]] end]
+  }
+  foreach layer_name [dict keys [dict get $grid_data straps]] {
+    lappend channel_layers $layer_name
+  }
+
+  return $channel_layers
+}
+
+proc get_grid_channel_spacing {layer_name parallel_length} {
+  variable grid_data
+  variable def_units
+
+  if {[dict exists $grid_data straps $layer_name channel_spacing]} {
+    return [expr round([dict get $grid_data straps $layer_name channel_spacing] * $def_units)]
+  } elseif {[dict exists $grid_data straps $layer_name] && [dict exists $grid_data template names]} {
+    set template_name [lindex [dict get $grid_data template names] 0]
+    if {[dict exists $grid_data straps $layer_name $template_name channel_spacing]} {
+      return [expr round([dict get $grid_data straps $layer_name $template_name channel_spacing]]
+    }
+  } else {
+    set layer [[ord::get_db_tech] findLayer $layer_name]
+    if {$layer == "NULL"}  {
+      utl::error PDN 168 "Layer $layer_name does not exist"
+    }
+    set layer_width [get_grid_wire_width $layer_name]
+    if {[$layer hasTwoWidthsSpacingRules]} {
+      set num_widths [$layer getTwoWidthsSpacingTableNumWidths]
+      set current_width 0
+      set prl_rule -1
+      for {set rule 0} {$rule < $num_widths} {incr rule} {
+        set width [$layer getTwoWidthsSpacingTableWidth $rule]
+        if {$width == $current_width && $prl_rule != -1} {
+          continue
+        } else {
+          set current_width $width
+          if {[$layer getTwoWidthsSpacingTableHasPRL $rule] == 0} {
+            set non_prl_rule $rule
+            set prl_rule -1
+          } else {
+            if {$parallel_length > [$layer getTwoWidthsSpacingTablePRL $rule]} {
+              set prl_rule $rule
+            }
+          }
+        }
+        if {$layer_width < [$layer getTwoWidthsSpacingTableWidth $rule]} {
+          if {$prl_rule == 0} {
+            set use_rule $non_prl_rule
+          } else {
+            set use_rule $prl_rule
+          }
+          break
+        }
+      }
+
+      set spacing [$layer getTwoWidthsSpacingTableEntry $use_rule $use_rule]
+      # debug "Two widths spacing: layer: $layer_name, rule: $use_rule, spacing: $spacing"
+    } elseif {[$layer hasV55SpacingRules]} {
+      set layer_width [get_grid_wire_width $layer_name]
+      set spacing [$layer findV55Spacing $layer_width $parallel_length]
+    } else {
+      set spacing [$layer getSpacing]
+    }
+    # Can't store value, since it depends on channel height
+    return $spacing
+  }
+
+  utl::error "PDN" 52 "Unable to get channel_spacing setting for layer $layer_name."
+}
+
+proc get_grid_wire_width {layer_name} {
+  variable grid_data
+  variable default_grid_data
+  variable design_data
+
+  if {[info exists grid_data]} {
+    if {[dict exists $grid_data rails $layer_name width]} {
+      set width [dict get $grid_data rails $layer_name width]
+      return $width
+    } elseif {[dict exists $grid_data straps $layer_name width]} {
+      set width [dict get $grid_data straps $layer_name width]
+      return $width
+    } elseif {[dict exists $grid_data straps $layer_name] && [dict exists $grid_data template names]} {
+      set template_name [lindex [dict get $grid_data template names] 0]
+      set width [dict get $grid_data straps $layer_name $template_name width]
+      return $width
+    } elseif {[dict exists $grid_data core_ring $layer_name width]} {
+      set width [dict get $grid_data core_ring $layer_name width]
+      return $width
+    }
+  }
+
+  if {[info exists default_grid_data]} {
+    if {[dict exists $default_grid_data rails $layer_name width]} {
+      set width [dict get $default_grid_data rails $layer_name width]
+      return $width
+    } elseif {[dict exists $default_grid_data straps $layer_name width]} {
+      set width [dict get $default_grid_data straps $layer_name width]
+      return $width
+    } elseif {[dict exists $default_grid_data straps $layer_name] && [dict exists $default_grid_data template names]} {
+      set template_name [lindex [dict get $default_grid_data template names] 0]
+      set width [dict get $default_grid_data straps $layer_name $template_name width]
+      return $width
+    }
+  }
+  utl::error "PDN" 44 "No width information found for $layer_name."
+}
+
+proc get_grid_wire_pitch {layer_name} {
+  variable grid_data
+  variable default_grid_data
+  variable design_data
+
+  if {[dict exists $grid_data rails $layer_name pitch]} {
+    set pitch [dict get $grid_data rails $layer_name pitch]
+  } elseif {[dict exists $grid_data straps $layer_name pitch]} {
+    set pitch [dict get $grid_data straps $layer_name pitch]
+  } elseif {[dict exists $grid_data straps $layer_name] && [dict exists $grid_data template names]} {
+    set template_name [lindex [dict get $grid_data template names] 0]
+    set pitch [dict get $grid_data straps $layer_name $template_name pitch]
+  } elseif {[dict exists $default_grid_data straps $layer_name pitch]} {
+    set pitch [dict get $default_grid_data straps $layer_name pitch]
+  } elseif {[dict exists $default_grid_data straps $layer_name] && [dict exists $default_grid_data template names]} {
+    set template_name [lindex [dict get $default_grid_data template names] 0]
+    set pitch [dict get $default_grid_data straps $layer_name $template_name pitch]
+  } else {
+    utl::error "PDN" 45 "No pitch information found for $layer_name."
+  }
+
+  return $pitch
+}
+
+## Proc to generate via locations, both for a normal via and stacked via
+proc generate_via_stacks {l1 l2 tag connection} {
+  variable logical_viarules
+  variable stripe_locs
+  variable def_units
+  variable grid_data
+
+  set area [dict get $grid_data area]
+  # debug "From $l1 to $l2"
+
+  if {[dict exists $grid_data core_ring_area combined]} {
+    set grid_area [dict get $grid_data core_ring_area combined]
+    set factor [expr max([lindex $area 2] - [lindex $area 0], [lindex $area 3] - [lindex $area 1]) * 2]
+    set grid_area [odb::shrinkSet [odb::bloatSet $grid_area $factor] $factor]
+    # debug "Old area ($area)"
+    set bbox [lindex [odb::getRectangles $grid_area] 0]
+    set area [list {*}[$bbox ll] {*}[$bbox ur]]
+    # debug "Recalculated area to be ($area)"
+  }
+
+  #this variable contains locations of intersecting points of two orthogonal metal layers, between which via needs to be inserted
+  #for every intersection. Here l1 and l2 are layer names, and i1 and i2 and their indices, tag represents domain (power or ground)
+  set intersections ""
+  #check if layer pair is orthogonal, case 1
+  set layer1 $l1
+  regexp {(.*)_PIN_(hor|ver)} $l1 - layer1 direction
+
+  set layer2 $l2
+
+  set ignore_count 0
+  if {[array names stripe_locs "$l1,$tag"] == ""} {
+    utl::warn "PDN" 2 "No shapes on layer $l1 for $tag."
+    return {}
+  }
+  if {[array names stripe_locs "$l2,$tag"] == ""} {
+    utl::warn "PDN" 3 "No shapes on layer $l2 for $tag."
+    return {}
+  }
+  set intersection [odb::andSet [odb::andSet $stripe_locs($l1,$tag) $stripe_locs($l2,$tag)] [odb::newSetFromRect {*}$area]]
+
+  # debug "Detected [llength [::odb::getPolygons $intersection]] intersections of $l1 and $l2"
+
+  foreach shape [::odb::getPolygons $intersection] {
+    set points [::odb::getPoints $shape]
+    if {[llength $points] != 4} {
+        variable def_units
+        utl::warn "PDN" 4 "Unexpected number of points in connection shape ($l1,$l2 $tag [llength $points])."
+        set str "    "
+        foreach point $points {set str "$str ([expr 1.0 * [$point getX] / $def_units ] [expr 1.0 * [$point getY] / $def_units]) "}
+        utl::warn "PDN" 5 $str
+        continue
+    }
+    set xMin [expr min([[lindex $points 0] getX], [[lindex $points 1] getX], [[lindex $points 2] getX], [[lindex $points 3] getX])]
+    set xMax [expr max([[lindex $points 0] getX], [[lindex $points 1] getX], [[lindex $points 2] getX], [[lindex $points 3] getX])]
+    set yMin [expr min([[lindex $points 0] getY], [[lindex $points 1] getY], [[lindex $points 2] getY], [[lindex $points 3] getY])]
+    set yMax [expr max([[lindex $points 0] getY], [[lindex $points 1] getY], [[lindex $points 2] getY], [[lindex $points 3] getY])]
+
+    set width [expr $xMax - $xMin]
+    set height [expr $yMax - $yMin]
+
+    # Ensure that the intersections are not partial
+    if {![regexp {(.*)_PIN_(hor|ver)} $l1]} {
+      if {[get_dir $layer1] == "hor"} {
+        if {$height < [get_grid_wire_width $layer1]} {
+          # If the intersection doesnt cover the whole width of the bottom level wire, then ignore
+          utl::warn "PDN" 40 "No via added at ([expr 1.0 * $xMin / $def_units] [expr 1.0 * $yMin / $def_units] [expr 1.0 * $xMax / $def_units] [expr 1.0 * $yMax / $def_units]) because the full height of $layer1 ([expr 1.0 * [get_grid_wire_width $layer1] / $def_units]) is not covered by the overlap."
+          continue
+        }
+      } else {
+        if {$width < [get_grid_wire_width $layer1]} {
+          # If the intersection doesnt cover the whole width of the bottom level wire, then ignore
+          utl::warn "PDN" 41 "No via added at ([expr 1.0 * $xMin / $def_units] [expr 1.0 * $yMin / $def_units] [expr 1.0 * $xMax / $def_units] [expr 1.0 * $yMax / $def_units]) because the full width of $layer1 ([expr 1.0 * [get_grid_wire_width $layer1] / $def_units]) is not covered by the overlap."
+          continue
+        }
+      }
+    }
+    if {[get_dir $layer2] == "hor"} {
+      if {$height < [get_grid_wire_width $layer2]} {
+        # If the intersection doesnt cover the whole width of the top level wire, then ignore
+        utl::warn "PDN" 42 "No via added at ([expr 1.0 * $xMin / $def_units] [expr 1.0 * $yMin / $def_units] [expr 1.0 * $xMax / $def_units] [expr 1.0 * $yMax / $def_units]) because the full height of $layer2 ([expr 1.0 * [get_grid_wire_width $layer2] / $def_units]) is not covered by the overlap."
+        continue
+      }
+    } else {
+      if {$width < [get_grid_wire_width $layer2]} {
+        # If the intersection doesnt cover the whole width of the top level wire, then ignore
+        utl::warn "PDN" 43 "No via added at ([expr 1.0 * $xMin / $def_units] [expr 1.0 * $yMin / $def_units] [expr 1.0 * $xMax / $def_units] [expr 1.0 * $yMax / $def_units]) because the full width of $layer2 ([expr 1.0 * [get_grid_wire_width $layer2] / $def_units]) is not covered by the overlap."
+        continue
+      }
+    }
+
+    set rule_name ${l1}${layer2}_${width}x${height}
+    if {![dict exists $logical_viarules $rule_name]} {
+      dict set logical_viarules $rule_name [list lower $l1 upper $layer2 width $width height $height]
+    }
+    lappend intersections "rule $rule_name x [expr ($xMax + $xMin) / 2] y [expr ($yMax + $yMin) / 2]"
+  }
+
+  # debug "Added [llength $intersections] intersections"
+
+  return [generate_vias $l1 $l2 $intersections $connection]
+}
+
+proc add_stripe {layer type polygon_set} {
+  variable stripes
+  # debug "start"
+  lappend stripes($layer,$type) $polygon_set
+  # debug "end"
+}
+
+proc merge_stripes {} {
+  variable stripes
+  variable stripe_locs
+
+  foreach stripe_set [array names stripes] {
+    # debug "$stripe_set [llength $stripes($stripe_set)]"
+    if {[llength $stripes($stripe_set)] > 0} {
+      set merged_stripes [shapes_to_polygonSet $stripes($stripe_set)]
+      if {[array names stripe_locs $stripe_set] != ""} {
+        # debug "$stripe_locs($stripe_set)"
+        set stripe_locs($stripe_set) [odb::orSet $stripe_locs($stripe_set) $merged_stripes]
+      } else {
+        set stripe_locs($stripe_set) $merged_stripes
+      }
+    }
+    set stripes($stripe_set) {}
+  }
+}
+
+proc get_core_ring_vertical_layer_name {} {
+  variable grid_data
+
+  if {![dict exists $grid_data core_ring]} {
+    return ""
+  }
+
+  foreach layer_name [dict keys [dict get $grid_data core_ring]] {
+    if {[get_dir $layer_name] == "ver"} {
+      return $layer_name
+    }
+  }
+
+  return ""
+}
+
+proc is_extend_to_core_ring {layer_name} {
+  variable grid_data
+
+  if {![dict exists $grid_data rails $layer_name extend_to_core_ring]} {
+    return 0
+  }
+  if {![dict get $grid_data rails $layer_name extend_to_core_ring]} {
+    return 0
+  }
+  if {[get_core_ring_vertical_layer_name] == ""} {
+    return 0
+  }
+  return 1
+}
+
+# proc to generate follow pin layers or standard cell rails
+proc generate_lower_metal_followpin_rails {} {
+  variable block
+  variable grid_data
+  variable design_data
+
+  set stdcell_area [get_extent [get_stdcell_area]]
+  set stdcell_min_x [lindex $stdcell_area 0]
+  set stdcell_max_x [lindex $stdcell_area 2]
+
+  if {[set ring_vertical_layer [get_core_ring_vertical_layer_name]] != ""} {
+    # debug "Ring vertical layer: $ring_vertical_layer"
+    # debug "Grid_data: $grid_data"
+    if {[dict exists $grid_data core_ring $ring_vertical_layer pad_offset]} {
+      set pad_area [find_pad_offset_area]
+      set offset [expr [dict get $grid_data core_ring $ring_vertical_layer pad_offset]]
+      set ring_adjustment [expr $stdcell_min_x - ([lindex $pad_area 0] + $offset)]
+    }
+    if {[dict exists $grid_data core_ring $ring_vertical_layer core_offset]} {
+      set ring_adjustment [expr \
+        [dict get $grid_data core_ring $ring_vertical_layer core_offset] + \
+        [dict get $grid_data core_ring $ring_vertical_layer spacing] + \
+        3 * [dict get $grid_data core_ring $ring_vertical_layer width] / 2 \
+      ]
+    }
+  }
+
+  foreach row [$block getRows] {
+    set orient [$row getOrient]
+    set box [$row getBBox]
+    switch -exact $orient {
+      R0 {
+        set vdd_y [$box yMax]
+        set vss_y [$box yMin]
+      }
+      MX {
+        set vdd_y [$box yMin]
+        set vss_y [$box yMax]
+      }
+      default {
+        utl::error "PDN" 25 "Unexpected row orientation $orient for row [$row getName]."
+      }
+    }
+
+    foreach lay [get_rails_layers] {
+      set xMin [$box xMin]
+      set xMax [$box xMax]
+      if {[is_extend_to_core_ring $lay]} {
+        # debug "Extending to core_ring - adjustment $ring_adjustment ($xMin/$xMax) ($stdcell_min_x/$stdcell_max_x)"
+        set voltage_domain [get_voltage_domain $xMin [$box yMin] $xMax [$box yMax]]
+        if {$voltage_domain == [dict get $design_data core_domain]} {
+          if {$xMin == $stdcell_min_x} {
+            set xMin [expr $xMin - $ring_adjustment]
+          }
+          if {$xMax == $stdcell_max_x} {
+            set xMax [expr $xMax + $ring_adjustment]
+          }
+        } else {
+          #Create lower metal followpin rails for voltage domains where the starting positions are not stdcell_min_x
+          set core_power [get_voltage_domain_power [dict get $design_data core_domain]]
+          set core_ground [get_voltage_domain_ground [dict get $design_data core_domain]]
+          set domain_power [get_voltage_domain_power $voltage_domain]
+          set domain_ground [get_voltage_domain_ground $voltage_domain]
+
+          set first_rect [lindex [[$block findRegion $voltage_domain] getBoundaries] 0]
+          set domain_xMin [$first_rect xMin]
+          set domain_xMax [$first_rect xMax]
+
+          if {$xMin == $domain_xMin} {
+            set xMin [expr $xMin - $ring_adjustment]
+          }
+          if {$xMax == $domain_xMax} {
+            set xMax [expr $xMax + $ring_adjustment]
+          }
+        }
+        # debug "Extended  to core_ring - adjustment $ring_adjustment ($xMin/$xMax)"
+      }
+      set width [dict get $grid_data rails $lay width]
+      # debug "VDD: $xMin [expr $vdd_y - $width / 2] $xMax [expr $vdd_y + $width / 2]"
+      set vdd_box [::odb::newSetFromRect $xMin [expr $vdd_y - $width / 2] $xMax [expr $vdd_y + $width / 2]]
+      set vdd_name [get_voltage_domain_power [get_voltage_domain $xMin [expr $vdd_y - $width / 2] $xMax [expr $vdd_y + $width / 2]]]
+      set vss_box [::odb::newSetFromRect $xMin [expr $vss_y - $width / 2] $xMax [expr $vss_y + $width / 2]]
+      set vss_name [get_voltage_domain_ground [get_voltage_domain $xMin [expr $vss_y - $width / 2] $xMax [expr $vss_y + $width / 2]]]
+      # generate power_rails using first domain_power
+      set first_power_name [lindex $vdd_name 0]
+      # debug "[$box xMin] [expr $vdd_y - $width / 2] [$box xMax] [expr $vdd_y + $width / 2]"
+      if {$first_power_name == [get_voltage_domain_power [dict get $design_data core_domain]]} {
+        add_stripe $lay "POWER" $vdd_box
+      } else {
+        add_stripe $lay "POWER_$first_power_name" $vdd_box
+      }
+      if {$vss_name == [get_voltage_domain_ground [dict get $design_data core_domain]]} {
+        add_stripe $lay "GROUND" $vss_box
+      } else {
+        add_stripe $lay "GROUND_$vss_name" $vss_box
+      }
+    }
+  }
+}
+
+proc starts_with {lay} {
+  variable grid_data
+  variable stripes_start_with
+
+  if {[dict exists $grid_data straps $lay starts_with]} {
+    set starts_with [dict get $grid_data straps $lay starts_with]
+  } elseif {[dict exists $grid_data starts_with]} {
+    set starts_with [dict get $grid_data starts_with]
+  } else {
+    set starts_with $stripes_start_with
+  }
+  return $starts_with
+}
+
+# proc for creating pdn mesh for upper metal layers
+proc generate_upper_metal_mesh_stripes {tag layer layer_info area} {
+# If the grid_data defines a spacing for the layer, then:
+#    place the second stripe spacing + width away from the first,
+# otherwise:
+#    place the second stripe pitch / 2 away from the first,
+#
+  set width [dict get $layer_info width]
+  set start_with [starts_with $layer]
+  # debug "Starts with: $start_with"
+
+  if {[get_dir $layer] == "hor"} {
+    set offset [expr [lindex $area 1] + [dict get $layer_info offset]]
+    if {![regexp "$start_with.*" $tag match]} { ;#If not starting from bottom with this net, 
+      if {[dict exists $layer_info spacing]} {
+        set offset [expr {$offset + [dict get $layer_info spacing] + [dict get $layer_info width]}]
+      } else {
+        set offset [expr {$offset + ([dict get $layer_info pitch] / 2)}]
+      }
+    }
+    for {set y $offset} {$y < [expr {[lindex $area 3] - [dict get $layer_info width]}]} {set y [expr {[dict get $layer_info pitch] + $y}]} {
+      set box [::odb::newSetFromRect [lindex $area 0] [expr $y - $width / 2] [lindex $area 2] [expr $y + $width / 2]]
+      add_stripe $layer $tag $box
+    }
+  } elseif {[get_dir $layer] == "ver"} {
+    set offset [expr [lindex $area 0] + [dict get $layer_info offset]]
+
+    if {![regexp "$start_with.*" $tag match]} { ;#If not starting from bottom with this net, 
+      if {[dict exists $layer_info spacing]} {
+        set offset [expr {$offset + [dict get $layer_info spacing] + [dict get $layer_info width]}]
+      } else {
+        set offset [expr {$offset + ([dict get $layer_info pitch] / 2)}]
+      }
+    }
+    for {set x $offset} {$x < [expr {[lindex $area 2] - [dict get $layer_info width]}]} {set x [expr {[dict get $layer_info pitch] + $x}]} {
+      set box [::odb::newSetFromRect [expr $x - $width / 2] [lindex $area 1] [expr $x + $width / 2] [lindex $area 3]]
+      add_stripe $layer $tag $box
+    }
+  } else {
+    utl::error "PDN" 26 "Invalid direction \"[get_dir $layer]\" for metal layer ${layer}. Should be either \"hor\" or \"ver\"."
+  }
+}
+
+proc adjust_area_for_core_rings {layer area number} {
+  variable grid_data
+
+  # When core_rings overlap with the stdcell area, we need to block out the area
+  # where the core rings have been placed.
+  if {[dict exists $grid_data core_ring_area $layer]} {
+    set core_ring_area [dict get $grid_data core_ring_area $layer]
+    set grid_area [odb::newSetFromRect {*}$area]
+    set grid_area [odb::subtractSet $grid_area $core_ring_area]
+    set area [get_extent $grid_area]
+  }
+
+  # Calculate how far to extend the grid to meet with the core rings
+  if {[dict exists $grid_data core_ring $layer pad_offset]} {
+    set pad_area [find_pad_offset_area]
+    set width [dict get $grid_data core_ring $layer width]
+    set offset [expr [dict get $grid_data core_ring $layer pad_offset]]
+    set spacing [dict get $grid_data core_ring $layer spacing]
+    set xMin [expr [lindex $pad_area 0] + $offset]
+    set yMin [expr [lindex $pad_area 1] + $offset]
+    set xMax [expr [lindex $pad_area 2] - $offset]
+    set yMax [expr [lindex $pad_area 3] - $offset]
+  } elseif {[dict exists $grid_data core_ring $layer core_offset]} {
+    set offset [dict get $grid_data core_ring $layer core_offset]
+    set width [dict get $grid_data core_ring $layer width]
+    set spacing [dict get $grid_data core_ring $layer spacing]
+    # debug "Area: $area"
+    # debug "Offset: $offset, Width $width, Spacing $spacing"
+
+    # The area figure includes a y offset for the width of the stdcell rail - so need to subtract it here
+    set rail_width [get_rails_max_width]
+    
+    # set extension area according to the number of power rings of the voltage domain, the default number is 2 
+    set xMin [expr [lindex $area 0] - $offset - $width - $spacing - $width / 2 - ($number - 2) * ($width + $spacing)]
+    set yMin [expr [lindex $area 1] - $offset - $width - $spacing - $width / 2 + $rail_width / 2 - ($number - 2) * ($width + $spacing)]
+    set xMax [expr [lindex $area 2] + $offset + $width + $spacing + $width / 2 + ($number - 2) * ($width + $spacing)]
+    set yMax [expr [lindex $area 3] + $offset + $width + $spacing + $width / 2 - $rail_width / 2 + ($number - 2) * ($width + $spacing)]
+  }
+  if {[get_dir $layer] == "hor"} {
+    set extended_area [list $xMin [lindex $area 1] $xMax [lindex $area 3]]
+  } else {
+    set extended_area [list [lindex $area 0] $yMin [lindex $area 2] $yMax]
+  }
+  return $extended_area
+}
+
+## this is a top-level proc to generate PDN stripes and insert vias between these stripes
+proc generate_stripes {tag net_name} {
+  variable plan_template
+  variable template
+  variable grid_data
+  variable block
+  variable design_data
+  variable voltage_domains
+
+  # debug "start: grid_name: [dict get $grid_data name]"
+  if {![dict exists $grid_data straps]} {return}
+  foreach lay [dict keys [dict get $grid_data straps]] {
+    # debug "    Layer $lay ..."
+    #Upper layer stripes
+    if {[dict exists $grid_data straps $lay width]} {
+      set area [dict get $grid_data area]
+      # debug "Area $area"
+      # Calculate the numebr of rings of core_domain
+      set ring_number 2 
+      if {[dict exists $grid_data core_ring] && [dict exists $grid_data core_ring $lay]} {
+        set area [adjust_area_for_core_rings $lay $area $ring_number]
+      }
+      # debug "area=$area (spec area=[dict get $grid_data area])"
+      # Create stripes for core domain's pwr/gnd nets
+      
+      if {$net_name == [get_voltage_domain_power [dict get $design_data core_domain]] ||
+          $net_name == [get_voltage_domain_ground [dict get $design_data core_domain]]} {
+        generate_upper_metal_mesh_stripes $tag $lay [dict get $grid_data straps $lay] $area
+        # Split core domains pwr/gnd nets when they cross other voltage domains that have different pwr/gnd nets
+        update_mesh_stripes_with_volatge_domains $tag $lay $net_name
+      }
+      # Create stripes for each voltage domains
+      foreach domain_name [dict keys $voltage_domains] {
+        if {$domain_name == [dict get $design_data core_domain]} {continue}
+        set domain [$block findRegion $domain_name]
+        set rect [lindex [$domain getBoundaries] 0]
+        set domain_name [$domain getName]
+        set domain_xMin [$rect xMin]
+        set domain_yMin [$rect yMin]
+        set domain_xMax [$rect xMax]
+        set domain_yMax [$rect yMax]
+        set width [dict get $grid_data core_ring $lay width]
+        set spacing [dict get $grid_data core_ring $lay spacing]
+        set rail_width [get_rails_max_width]
+        # Do not create duplicate stripes if the voltage domain has the same pwr/gnd nets as the core domain
+        if {($net_name == [get_voltage_domain_power $domain_name] && $net_name != [get_voltage_domain_power [dict get $design_data core_domain]]) ||
+             ($net_name == [get_voltage_domain_ground $domain_name] && $net_name != [get_voltage_domain_ground [dict get $design_data core_domain]])} {
+          set area [list $domain_xMin [expr $domain_yMin - $rail_width / 2] $domain_xMax [expr $domain_yMax + $rail_width / 2]]
+          set area [adjust_area_for_core_rings $lay $area 2]
+          set tag "$tag\_$net_name"
+          generate_upper_metal_mesh_stripes $tag $lay [dict get $grid_data straps $lay] $area
+        }
+        if {[lsearch -exact [get_voltage_domain_secondary_power $domain_name] $net_name] > -1} {
+          #Calculate the ring number of power_domain
+          set ring_number [lsearch -exact [get_voltage_domain_secondary_power $domain_name] $net_name]
+          set area [list [expr $domain_xMin + $ring_number * ($width + $spacing)] [expr $domain_yMin - $rail_width / 2] [expr $domain_xMax + $ring_number * ($width + $spacing)] [expr $domain_yMax + $rail_width / 2]]
+          set area [adjust_area_for_core_rings $lay $area [expr 3 + $ring_number]]
+          set tag "$tag\_$net_name"
+          generate_upper_metal_mesh_stripes $tag $lay [dict get $grid_data straps $lay] $area
+        }
+      }
+    } else {
+      foreach x [lsort -integer [dict keys $plan_template]] {
+        foreach y [lsort -integer [dict keys [dict get $plan_template $x]]] {
+          set template_name [dict get $plan_template $x $y]
+          set layer_info [dict get $grid_data straps $lay $template_name]
+          set area [list $x $y [expr $x + [dict get $template width]] [expr $y + [dict get $template height]]]
+          generate_upper_metal_mesh_stripes $tag $lay $layer_info $area
+        }
+      }
+    }
+  }
+}
+
+proc cut_blocked_areas {tag} {
+  variable stripe_locs
+  variable grid_data
+
+  if {![dict exists  $grid_data straps]} {return}
+
+  foreach layer_name [dict keys [dict get $grid_data straps]] {
+    set width [get_grid_wire_width $layer_name]
+
+    set blockages [get_blockages]
+    if {[dict exists $blockages $layer_name]} {
+      set stripe_locs($layer_name,$tag) [::odb::subtractSet $stripe_locs($layer_name,$tag) [dict get $blockages $layer_name]]
+
+      # Trim any shapes that are less than the width of the wire
+      set size_by [expr $width / 2 - 1]
+      set trimmed_set [::odb::shrinkSet $stripe_locs($layer_name,$tag) $size_by]
+      set stripe_locs($layer_name,$tag) [::odb::bloatSet $trimmed_set $size_by]
+    }
+  }
+}
+
+proc generate_grid_vias {tag net_name} {
+  variable vias
+  variable grid_data
+  variable design_data
+
+  if {$net_name != [get_voltage_domain_power [dict get $design_data core_domain]] &&
+      $net_name != [get_voltage_domain_ground [dict get $design_data core_domain]]} {
+    set tag "$tag\_$net_name"
+  }
+
+  #Via stacks
+  # debug "grid_data $grid_data"
+  if {[dict exists $grid_data connect]} {
+    # debug "Adding vias for $net_name ([llength [dict get $grid_data connect]] connections)..."
+    foreach connection [dict get $grid_data connect] {
+        set l1 [lindex $connection 0]
+        set l2 [lindex $connection 1]
+        # debug "    $l1 to $l2"
+        set connections [generate_via_stacks $l1 $l2 $tag $connection]
+        lappend vias [list net_name $net_name connections $connections]
+    }
+  }
+  # debug "End"
+}
+
+proc get_core_ring_centre {type side layer_info} {
+  variable grid_data
+
+  set spacing [dict get $layer_info spacing]
+  set width [dict get $layer_info width]
+
+  if {[dict exists $layer_info pad_offset]} {
+    set area [find_pad_offset_area]
+    lassign $area xMin yMin xMax yMax
+    set offset [expr [dict get $layer_info pad_offset] + $width / 2]
+    # debug "area        $area"
+    # debug "pad_offset  $offset"
+    # debug "spacing     $spacing"
+    # debug "width       $width"
+    switch $type {
+      "GROUND" {
+        switch $side {
+          "t" {return [expr $yMax - $offset]}
+          "b" {return [expr $yMin + $offset]}
+          "l" {return [expr $xMin + $offset]}
+          "r" {return [expr $xMax - $offset]}
+        }
+      }
+      "POWER" {
+        switch $side {
+          "t" {return [expr $yMax - $offset - $spacing - $width]}
+          "b" {return [expr $yMin + $offset + $spacing + $width]}
+          "l" {return [expr $xMin + $offset + $spacing + $width]}
+          "r" {return [expr $xMax - $offset - $spacing - $width]}
+        }
+      }
+    }
+  } elseif {[dict exists $layer_info core_offset]} {
+    set area [find_core_area]
+    set xMin [lindex $area 0]
+    set yMin [lindex $area 1]
+    set xMax [lindex $area 2]
+    set yMax [lindex $area 3]
+
+    set offset [dict get $layer_info core_offset]
+    # debug "area        $area"
+    # debug "core_offset $offset"
+    # debug "spacing     $spacing"
+    # debug "width       $width"
+    switch $type {
+      "POWER" {
+        switch $side {
+          "t" {return [expr $yMax + $offset]}
+          "b" {return [expr $yMin - $offset]}
+          "l" {return [expr $xMin - $offset]}
+          "r" {return [expr $xMax + $offset]}
+        }
+      }
+      "GROUND" {
+        switch $side {
+          "t" {return [expr $yMax + $offset + $spacing + $width]}
+          "b" {return [expr $yMin - $offset - $spacing - $width]}
+          "l" {return [expr $xMin - $offset - $spacing - $width]}
+          "r" {return [expr $xMax + $offset + $spacing + $width]}
+        }
+      }
+    }
+  }
+}
+
+proc real_value {value} {
+  variable def_units
+
+  return [expr $value * 1.0 / $def_units]
+}
+
+proc find_pad_offset_area {} {
+  variable block
+  variable grid_data
+  variable design_data
+
+  if {!([dict exists $grid_data pwr_pads] && [dict exists $grid_data gnd_pads])} {
+    utl::error "PDN" 48 "Need to define pwr_pads and gnd_pads in config file to use pad_offset option."
+  }
+
+  if {![dict exists $design_data config pad_offset_area]} {
+    set pad_names {}
+    dict for {pin_name pads} [dict get $grid_data pwr_pads] {
+      set pad_names [concat $pad_names $pads]
+    }
+    dict for {pin_name pads} [dict get $grid_data gnd_pads] {
+      set pad_names [concat $pad_names $pads]
+    }
+    set pad_names [lsort -unique $pad_names]
+    set die_area [dict get $design_data config die_area]
+    set xMin [lindex $die_area 0]
+    set yMin [lindex $die_area 1]
+    set xMax [lindex $die_area 2]
+    set yMax [lindex $die_area 3]
+
+    # debug "pad_names: $pad_names"
+    set found_b 0
+    set found_r 0
+    set found_t 0
+    set found_l 0
+    foreach inst [$block getInsts] {
+      if {[lsearch $pad_names [[$inst getMaster] getName]] > -1} {
+        # debug "inst_master: [[$inst getMaster] getName]"
+        set quadrant [get_design_quadrant {*}[$inst getOrigin]]
+        switch $quadrant {
+          "b" {
+            # debug "inst: [$inst getName], side: $quadrant, yMax: [real_value [[$inst getBBox] yMax]]"
+            set found_b 1
+            if {$yMin < [set y [[$inst getBBox] yMax]]} {
+              set yMin $y
+            }
+          }
+          "r" {
+            # debug "inst: [$inst getName], side: $quadrant, xMin: [real_value [[$inst getBBox] xMin]]"
+            set found_r 1
+            if {$xMax > [set x [[$inst getBBox] xMin]]} {
+              set xMax $x
+            }
+          }
+          "t" {
+            # debug "inst: [$inst getName], side: $quadrant, yMin: [real_value [[$inst getBBox] yMin]]"
+            set found_t 1
+            if {$yMax > [set y [[$inst getBBox] yMin]]} {
+              set yMax $y
+            }
+          }
+          "l" {
+            # debug "inst: [$inst getName], side: $quadrant, xMax: [real_value [[$inst getBBox] xMax]]"
+            set found_l 1
+            if {$xMin < [set x [[$inst getBBox] xMax]]} {
+              set xMin $x
+            }
+          }
+        }
+      }
+    }
+    if {$found_b == 0} {
+      utl::warn "PDN" 64 "No power/ground pads found on bottom edge."
+    }
+    if {$found_r == 0} {
+      utl::warn "PDN" 65 "No power/ground pads found on right edge."
+    }
+    if {$found_t == 0} {
+      utl::warn "PDN" 66 "No power/ground pads found on top edge."
+    }
+    if {$found_l == 0} {
+      utl::warn "PDN" 67 "No power/ground pads found on left edge."
+    }
+    if {$found_b == 0 || $found_r == 0 || $found_t == 0 || $found_l == 0} {
+      utl::error "PDN" 68 "Cannot place core rings without pwr/gnd pads on each side."
+    }
+    # debug "pad_area: ([real_value $xMin] [real_value $yMin]) ([real_value $xMax] [real_value $yMax])"
+    dict set design_data config pad_offset_area [list $xMin $yMin $xMax $yMax]
+  }
+
+  return [dict get $design_data config pad_offset_area]
+}
+
+proc generate_core_rings {core_ring_data} {
+  variable grid_data
+
+  dict for {layer layer_info} $core_ring_data {
+    if {[dict exists $layer_info pad_offset]} {
+      set area [find_pad_offset_area]
+      set offset [expr [dict get $layer_info pad_offset] + [dict get $layer_info width] / 2]
+
+      set xMin [lindex $area 0]
+      set yMin [lindex $area 1]
+      set xMax [lindex $area 2]
+      set yMax [lindex $area 3]
+
+      set spacing [dict get $layer_info spacing]
+      set width [dict get $layer_info width]
+
+      set outer_lx [expr $xMin + $offset]
+      set outer_ly [expr $yMin + $offset]
+      set outer_ux [expr $xMax - $offset]
+      set outer_uy [expr $yMax - $offset]
+
+      set inner_lx [expr $xMin + $offset + $spacing + $width]
+      set inner_ly [expr $yMin + $offset + $spacing + $width]
+      set inner_ux [expr $xMax - $offset - $spacing - $width]
+      set inner_uy [expr $yMax - $offset - $spacing - $width]
+    } elseif {[dict exists $layer_info core_offset]} {
+
+      set area [list {*}[[ord::get_db_core] ll] {*}[[ord::get_db_core] ur]]
+      set offset [dict get $layer_info core_offset]
+
+      set xMin [lindex $area 0]
+      set yMin [lindex $area 1]
+      set xMax [lindex $area 2]
+      set yMax [lindex $area 3]
+
+      set spacing [dict get $layer_info spacing]
+      set width [dict get $layer_info width]
+
+      set inner_lx [expr $xMin - $offset]
+      set inner_ly [expr $yMin - $offset]
+      set inner_ux [expr $xMax + $offset]
+      set inner_uy [expr $yMax + $offset]
+
+      set outer_lx [expr $xMin - $offset - $spacing - $width]
+      set outer_ly [expr $yMin - $offset - $spacing - $width]
+      set outer_ux [expr $xMax + $offset + $spacing + $width]
+      set outer_uy [expr $yMax + $offset + $spacing + $width]
+    }
+
+    if {[get_dir $layer] == "hor"} {
+      set lower_power \
+        [odb::newSetFromRect \
+          [expr $inner_lx - $width / 2] \
+          [expr $inner_ly - $width / 2] \
+          [expr $inner_ux + $width / 2] \
+          [expr $inner_ly + $width / 2] \
+        ]
+      
+      set upper_power \
+        [odb::newSetFromRect \
+          [expr $inner_lx - $width / 2] \
+          [expr $inner_uy - $width / 2] \
+          [expr $inner_ux + $width / 2] \
+          [expr $inner_uy + $width / 2] \
+        ]
+
+      set lower_ground \
+        [odb::newSetFromRect \
+          [expr $outer_lx - $width / 2] \
+          [expr $outer_ly - $width / 2] \
+          [expr $outer_ux + $width / 2] \
+          [expr $outer_ly + $width / 2] \
+        ]
+      set upper_ground \
+        [odb::newSetFromRect \
+          [expr $outer_lx - $width / 2] \
+          [expr $outer_uy - $width / 2] \
+          [expr $outer_ux + $width / 2] \
+          [expr $outer_uy + $width / 2] \
+        ]
+ 
+      add_stripe $layer "POWER" $upper_power
+      add_stripe $layer "POWER" $lower_power
+      add_stripe $layer "GROUND" $upper_ground
+      add_stripe $layer "GROUND" $lower_ground
+
+      set core_rings [odb::orSets [list \
+        [odb::newSetFromRect [expr $outer_lx - $width / 2] [expr $outer_ly - $width / 2] [expr $outer_ux + $width / 2] [expr $inner_ly + $width / 2]] \
+        [odb::newSetFromRect [expr $outer_lx - $width / 2] [expr $inner_uy - $width / 2] [expr $outer_ux + $width / 2] [expr $outer_uy + $width / 2]] \
+      ]]
+
+      set core_ring_area [odb::bloatSet $core_rings $spacing]
+      dict set grid_data core_ring_area $layer $core_ring_area
+
+    } else {
+      set lhs_power \
+        [odb::newSetFromRect \
+          [expr $inner_lx - $width / 2] \
+          [expr $inner_ly - $width / 2] \
+          [expr $inner_lx + $width / 2] \
+          [expr $inner_uy + $width / 2] \
+        ]
+      set rhs_power \
+        [odb::newSetFromRect \
+          [expr $inner_ux - $width / 2] \
+          [expr $inner_ly - $width / 2] \
+          [expr $inner_ux + $width / 2] \
+          [expr $inner_uy + $width / 2] \
+        ]
+
+      set lhs_ground \
+        [odb::newSetFromRect \
+          [expr $outer_lx - $width / 2] \
+          [expr $outer_ly - $width / 2] \
+          [expr $outer_lx + $width / 2] \
+          [expr $outer_uy + $width / 2] \
+        ]
+      set rhs_ground \
+        [odb::newSetFromRect \
+          [expr $outer_ux - $width / 2] \
+          [expr $outer_ly - $width / 2] \
+          [expr $outer_ux + $width / 2] \
+          [expr $outer_uy + $width / 2] \
+        ]
+
+      add_stripe $layer "POWER" $lhs_power
+      add_stripe $layer "POWER" $rhs_power
+      add_stripe $layer "GROUND" $lhs_ground
+      add_stripe $layer "GROUND" $rhs_ground
+      
+      set core_rings [odb::orSets [list \
+        [odb::newSetFromRect [expr $outer_lx - $width / 2] [expr $outer_ly - $width / 2] [expr $inner_lx + $width / 2] [expr $outer_uy + $width / 2]] \
+        [odb::newSetFromRect [expr $inner_ux - $width / 2] [expr $outer_ly - $width / 2] [expr $outer_ux + $width / 2] [expr $outer_uy + $width / 2]] \
+      ]]
+     
+      set core_ring_area [odb::bloatSet $core_rings $spacing]
+      dict set grid_data core_ring_area $layer $core_ring_area
+
+    }
+  }
+  set ring_areas {}
+  foreach layer [dict keys [dict get $grid_data core_ring_area]] {
+    lappend ring_areas [dict get $grid_data core_ring_area $layer]
+  }
+  dict set grid_data core_ring_area combined [odb::orSets $ring_areas]
+}
+
+proc get_macro_boundaries {} {
+  variable instances
+
+  set boundaries {}
+  foreach instance [dict keys $instances] {
+    lappend boundaries [dict get $instances $instance macro_boundary]
+  }
+
+  return $boundaries
+}
+
+proc get_stdcell_specification {} {
+  variable design_data
+
+  if {[dict exists $design_data grid stdcell]} {
+    set grid_name [lindex [dict keys [dict get $design_data grid stdcell]] 0]
+    return [dict get $design_data grid stdcell $grid_name]
+  } else {
+    if {![dict exists $design_data grid stdcell]} {
+      utl::error "PDN" 17 "No stdcell grid specification found - no rails can be inserted."
+    }
+  }
+
+  return {}
+}
+
+proc get_rail_width {} {
+  variable default_grid_data
+
+  set max_width 0
+  foreach layer [get_rails_layers] {
+    set max_width [expr max($max_width,[get_grid_wire_width $layer])]
+  }
+  if {![dict exists $default_grid_data units]} {
+    set max_width [ord::microns_to_dbu $max_width]
+  }
+  return $max_width
+}
+
+
+proc get_macro_blocks {} {
+  variable macros
+
+  if {[llength $macros] > 0} {return $macros}
+
+  # debug "start"
+  foreach lib [[ord::get_db] getLibs] {
+    foreach cell [$lib getMasters] {
+      if {![$cell isBlock] && ![$cell isPad]} {continue}
+      set macro_name [$cell getName]
+      dict set macros $macro_name width  [$cell getWidth]
+      dict set macros $macro_name height [$cell getHeight]
+
+      set blockage_layers {}
+      foreach obs [$cell getObstructions] {
+        set layer_name [[$obs getTechLayer] getName]
+        dict set blockage_layers $layer_name 1
+      }
+      dict set macros $macro_name blockage_layers [dict keys $blockage_layers]
+
+      set pin_layers {}
+      set power_pins {}
+      set ground_pins {}
+      set first_shape 1
+
+      foreach term [$cell getMTerms] {
+        set sig_type [$term getSigType]
+        if {$sig_type == "POWER"} {
+          lappend power_pins [$term getName]
+        } elseif {$sig_type == "GROUND"} {
+          lappend ground_pins [$term getName]
+        } else {
+          continue
+        }
+        
+        foreach pin [$term getMPins] {
+          foreach shape [$pin getGeometry] {
+            lappend pin_layers [[$shape getTechLayer] getName]
+            if {$first_shape == 1} {
+              set xMin [$shape xMin]
+              set xMax [$shape xMax]
+              set yMin [$shape yMin]
+              set yMax [$shape yMax]
+              set first_shape 0
+            } else {
+              set xMin [expr min($xMin,[$shape xMin])]
+              set xMax [expr max($xMax,[$shape xMax])]
+              set yMin [expr min($yMin,[$shape yMin])]
+              set yMax [expr max($yMax,[$shape yMax])]
+            }
+          }
+        }
+      }
+
+      dict set macros $macro_name pin_layers [lsort -unique $pin_layers]
+      dict set macros $macro_name power_pins [lsort -unique $power_pins]
+      dict set macros $macro_name ground_pins [lsort -unique $ground_pins]
+      if {$first_shape == 0}  {
+        dict set macros $macro_name pins_area [list $xMin $yMin $xMax $yMax]
+      } else {
+        dict set macros $macro_name pins_area [list 0 0 0 0]
+      }
+    }
+  }
+
+  return $macros
+}
+
+proc filtered_insts_within {instances boundary} {
+  set filtered_instances {}
+  dict for {instance_name instance} $instances {
+    # If there are no shapes left after 'and'ing the boundard with the cell, then
+    # the cell lies outside the area where we are adding a power grid.
+    set llx [dict get $instance xmin]
+    set lly [dict get $instance ymin]
+    set urx [dict get $instance xmax]
+    set ury [dict get $instance ymax]
+
+    set box [odb::newSetFromRect $llx $lly $urx $ury]
+    if {[llength [odb::getPolygons [odb::andSet $boundary $box]]] != 0} {
+      dict set filtered_instances $instance_name $instance
+    }
+  }
+  return $filtered_instances
+}
+
+proc import_macro_boundaries {} {
+  variable libs
+  variable instances
+
+  set macros [get_macro_blocks]
+  set instances [find_instances_of [dict keys $macros]]
+
+  # debug "end"
+}
+
+proc get_instances {} {
+  variable instances
+
+  if {[llength $instances] > 0} {return $instances}
+
+  set block [ord::get_db_block]
+  foreach inst [$block getInsts] {
+    if {![[$inst getMaster] isBlock] && ![[$inst getMaster] isPad]} {continue}
+    set instance {}
+    dict set instance name [$inst getName]
+    dict set instance inst $inst
+    dict set instance macro [[$inst getMaster] getName]
+    dict set instance x [lindex [$inst getOrigin] 0]
+    dict set instance y [lindex [$inst getOrigin] 1]
+    dict set instance xmin [[$inst getBBox] xMin]
+    dict set instance ymin [[$inst getBBox] yMin]
+    dict set instance xmax [[$inst getBBox] xMax]
+    dict set instance ymax [[$inst getBBox] yMax]
+    dict set instance orient [$inst getOrient]
+
+
+    set llx [dict get $instance xmin]
+    set lly [dict get $instance ymin]
+    set urx [dict get $instance xmax]
+    set ury [dict get $instance ymax]
+    dict set instance macro_boundary [list $llx $lly $urx $ury]
+    dict set instances [$inst getName] $instance
+
+    set_instance_halo [$inst getName] [get_default_halo]
+  }
+
+  return $instances
+}
+
+proc get_master_pg_pins_area {macro_name} {
+  variable macros
+
+  return [dict get $macros $macro_name pins_area]
+}
+
+proc get_instance_pg_pins_area {inst_name} {
+  variable instances
+
+  set instance [dict get $instances $inst_name]
+  set inst [dict get $instance inst]
+
+  set master_area [transform_box {*}[get_master_pg_pins_area [[$inst getMaster] getName]] [$inst getOrigin] [$inst getOrient]]
+}
+
+proc set_instance_halo {inst_name halo} {
+  variable instances 
+
+  set instance [dict get $instances $inst_name]
+  set inst [dict get $instance inst]
+
+  if {[$inst getHalo] != "NULL"} {
+    set halo [list \
+      [[$inst getHalo] xMin] \
+      [[$inst getHalo] yMin] \
+      [[$inst getHalo] xMax] \
+      [[$inst getHalo] yMax] \
+    ]
+  }
+  dict set instances $inst_name halo $halo
+  # debug "Inst: [$inst getName], halo: [dict get $instances $inst_name halo]"
+
+  set llx [expr round([dict get $instance xmin] - [lindex $halo 0])]
+  set lly [expr round([dict get $instance ymin] - ([lindex $halo 1] - [get_rail_width] / 2))]
+  set urx [expr round([dict get $instance xmax] + [lindex $halo 2])]
+  set ury [expr round([dict get $instance ymax] + ([lindex $halo 3] - [get_rail_width] / 2))]
+
+  dict set instances $inst_name halo_boundary [list $llx $lly $urx $ury]
+}
+
+proc find_instances_of {macro_names} {
+  variable design_data
+  variable macros
+
+  set selected_instances {}
+
+  dict for {inst_name instance} [get_instances] {
+    set macro_name [dict get $instance macro]
+    if {[lsearch -exact $macro_names $macro_name] == -1} {continue}
+    dict set selected_instances $inst_name $instance
+  }
+
+  return $selected_instances
+}
+
+proc export_opendb_vias {} {
+  variable physical_viarules
+  variable block
+  variable tech
+  # debug "[llength $physical_viarules]"
+  dict for {name rules} $physical_viarules {
+    foreach rule $rules {
+      # Dont create illegal vias
+      if {[dict exists $rule illegal]} {continue}
+      if {[dict exists $rule fixed]} {continue}
+
+      # debug "$rule"
+      set via [$block findVia [dict get $rule name]]
+      if {$via == "NULL"} {
+        set via [odb::dbVia_create $block [dict get $rule name]]
+        # debug "Via $via"
+
+        $via setViaGenerateRule [$tech findViaGenerateRule [dict get $rule rule]]
+        set params [$via getViaParams]
+        $params setBottomLayer [$tech findLayer [lindex [dict get $rule layers] 0]]
+        $params setCutLayer [$tech findLayer [lindex [dict get $rule layers] 1]]
+        $params setTopLayer [$tech findLayer [lindex [dict get $rule layers] 2]]
+        $params setXCutSize [lindex [dict get $rule cutsize] 0]
+        $params setYCutSize [lindex [dict get $rule cutsize] 1]
+        $params setXCutSpacing [lindex [dict get $rule cutspacing] 0]
+        $params setYCutSpacing [lindex [dict get $rule cutspacing] 1]
+        $params setXBottomEnclosure [lindex [dict get $rule enclosure] 0]
+        $params setYBottomEnclosure [lindex [dict get $rule enclosure] 1]
+        $params setXTopEnclosure [lindex [dict get $rule enclosure] 2]
+        $params setYTopEnclosure [lindex [dict get $rule enclosure] 3]
+        $params setNumCutRows [lindex [dict get $rule rowcol] 0]
+        $params setNumCutCols [lindex [dict get $rule rowcol] 1]
+
+        $via setViaParams $params
+      }
+    }
+  }
+  # debug "end"
+}
+
+proc get_global_connect_list_default {voltage_domain is_region} {
+  variable block
+  variable voltage_domains
+
+  foreach net_type "primary_power primary_ground" {
+    set net_name [dict get $voltage_domains $voltage_domain $net_type]
+    foreach sub_net $net_name {
+      set net [$block findNet $sub_net]
+      foreach term [get_valid_mterms $sub_net] {
+        if {$is_region} {
+          pdn::add_global_connect $block $voltage_domain ".*" $term $net
+        } else {
+          pdn::add_global_connect ".*" $term $net
+        }
+      }
+    }
+  }
+}
+
+proc get_global_connect_list {net_name} {
+  variable design_data
+  variable global_connections
+  variable voltage_domains
+
+  set connect_patterns {}
+  if {[dict exist $global_connections $net_name]} {
+    foreach pattern [dict get $global_connections $net_name] {
+      lappend connect_patterns $pattern
+    }
+  }
+
+  return $connect_patterns
+}
+
+proc export_opendb_global_connection {} {
+  variable block
+  variable design_data
+  variable global_connections
+  variable voltage_domains
+
+  ## Do global connect statements first
+  get_global_connect_list_default [dict get $design_data core_domain] false
+  
+  foreach net_type "power_nets ground_nets" {
+    foreach net_name [dict get $design_data $net_type] {
+      set net [$block findNet $net_name]
+      foreach pattern [get_global_connect_list $net_name] {
+        pdn::add_global_connect [dict get $pattern inst_name] [dict get $pattern pin_name] $net
+      }
+    }
+  }
+
+  ## Do regions second
+  set core_domain_name [dict get $design_data core_domain]
+  foreach voltage_domain [dict keys $voltage_domains] {
+    if {$voltage_domain != $core_domain_name} {
+      get_global_connect_list_default $voltage_domain true
+
+      foreach {net_type netname} [dict get $voltage_domains $voltage_domain] {
+        set net [$block findNet $net_name]
+        # loop over all patterns
+        foreach pattern [get_global_connect_list $net_name] {
+          pdn::add_global_connect $block $voltage_domain [dict get $pattern inst_name] [dict get $pattern pin_name] $net
+        }
+      }
+    }
+  }
+
+  pdn::global_connect $block
+}
+
+proc export_opendb_specialnet {net_name signal_type} {
+  variable block
+  variable instances
+  variable metal_layers
+  variable tech
+  variable stripe_locs
+  variable global_connections
+  variable design_data
+
+  set net [$block findNet $net_name]
+  if {$net == "NULL"} {
+    set net [odb::dbNet_create $block $net_name]
+  }
+  $net setSpecial
+  $net setSigType $signal_type
+  # debug "net $net_name. signaltype, $signal_type, global_connections: $global_connections"
+
+  if {[check_snet_is_unique $net]} {
+    $net setWildConnected
+  }
+  set swire [odb::dbSWire_create $net "ROUTED"]
+  if {$net_name != [get_voltage_domain_power [dict get $design_data core_domain]] &&
+      $net_name != [get_voltage_domain_ground [dict get $design_data core_domain]]} {
+    set signal_type "$signal_type\_$net_name"
+  }
+
+  # debug "layers - $metal_layers"
+  foreach lay $metal_layers {
+    if {[array names stripe_locs "$lay,$signal_type"] == ""} {continue}
+
+    set layer [find_layer $lay]
+    foreach rect [::odb::getRectangles $stripe_locs($lay,$signal_type)] {
+      set xMin [$rect xMin]
+      set xMax [$rect xMax]
+      set yMin [$rect yMin]
+      set yMax [$rect yMax]
+
+      set width [expr $xMax - $xMin]
+      set height [expr $yMax - $yMin]
+
+      set wire_type "STRIPE"
+      if {[is_rails_layer $lay]} {set wire_type "FOLLOWPIN"}
+      # debug "$xMin $yMin $xMax $yMax $wire_type"
+      odb::dbSBox_create $swire $layer $xMin $yMin $xMax $yMax $wire_type
+    }
+  }
+
+  variable vias
+  # debug "vias - [llength $vias]"
+  foreach via $vias {
+    if {[dict get $via net_name] == $net_name} {
+      # For each layer between l1 and l2, add vias at the intersection
+      foreach via_inst [dict get $via connections] {
+        # debug "$via_inst"
+        set via_name [dict get $via_inst name]
+        set x        [dict get $via_inst x]
+        set y        [dict get $via_inst y]
+        # debug "$via_name $x $y [$block findVia $via_name]"
+        if {[set defvia [$block findVia $via_name]] != "NULL"} {
+          odb::dbSBox_create $swire $defvia $x $y "STRIPE"
+        } elseif {[set techvia [$tech findVia $via_name]] != "NULL"} {
+          odb::dbSBox_create $swire $techvia $x $y "STRIPE"
+        } else {
+          utl::error "PDN" 69 "Cannot find via $via_name."
+        }
+        # debug "via created"
+      }
+    }
+  }
+  # debug "end"
+}
+
+proc export_opendb_specialnets {} {
+  variable block
+  variable design_data
+
+  foreach net_name [dict get $design_data power_nets] {
+    export_opendb_specialnet $net_name "POWER"
+  }
+
+  foreach net_name [dict get $design_data ground_nets] {
+    export_opendb_specialnet $net_name "GROUND"
+  }
+
+  export_opendb_global_connection
+}
+
+proc export_opendb_power_pin {net_name signal_type} {
+  variable metal_layers
+  variable block
+  variable stripe_locs
+  variable tech
+  variable voltage_domains
+  variable design_data
+
+  if {![dict exists $design_data grid stdcell]} {return}
+
+  set pins_layers {}
+  dict for {grid_name grid} [dict get $design_data grid stdcell] {
+    if {[dict exists $grid pins]} {
+      lappend pins_layers {*}[dict get $grid pins]
+    }
+  }
+  set pins_layers [lsort -unique $pins_layers]
+  if {[llength $pins_layers] == 0} {return}
+
+  set net [$block findNet $net_name]
+  if {$net == "NULL"} {
+    utl::error PDN 70 "Cannot find net $net_name in the design."
+  }
+  set bterms [$net getBTerms]
+  if {[llength $bterms] < 1} {
+    set bterm [odb::dbBTerm_create $net "${net_name}"]
+    if {$bterm == "NULL"} {
+      utl::error PDN 71 "Cannot create terminal for net $net_name."
+    }
+  }
+  # debug $bterm
+  foreach bterm [$net getBTerms] {
+    $bterm setSigType $signal_type
+  }
+  set bterm [lindex [$net getBTerms] 0]
+  set bpin [odb::dbBPin_create $bterm]
+  $bpin setPlacementStatus "FIRM"
+
+  dict for {domain domain_info} $voltage_domains {
+    if {$domain != [dict get $design_data core_domain] &&
+        $net_name == [dict get $domain_info primary_power]} {
+      set r_pin "r_$net_name"
+      set r_net [odb::dbNet_create $block $r_pin]
+      set r_bterm [odb::dbBTerm_create $r_net "${r_pin}"]
+
+      set r_bpin [odb::dbBPin_create $r_bterm]
+      $r_bpin setPlacementStatus "FIRM"
+    }
+  }
+
+  if {$net_name != [get_voltage_domain_power [dict get $design_data core_domain]] &&
+      $net_name != [get_voltage_domain_ground [dict get $design_data core_domain]]} {
+    set signal_type "$signal_type\_$net_name"
+  }
+
+  foreach lay [lreverse $metal_layers] {
+    if {[array names stripe_locs "$lay,$signal_type"] == "" ||
+        [lsearch -exact $pins_layers $lay] == -1} {continue}
+    foreach shape [::odb::getPolygons $stripe_locs($lay,$signal_type)] {
+      set points [::odb::getPoints $shape]
+      if {[llength $points] != 4} {
+        # We already issued a message for this - no need to repeat
+        continue
+      }
+      set xMin [expr min([[lindex $points 0] getX], [[lindex $points 1] getX], [[lindex $points 2] getX], [[lindex $points 3] getX])]
+      set xMax [expr max([[lindex $points 0] getX], [[lindex $points 1] getX], [[lindex $points 2] getX], [[lindex $points 3] getX])]
+      set yMin [expr min([[lindex $points 0] getY], [[lindex $points 1] getY], [[lindex $points 2] getY], [[lindex $points 3] getY])]
+      set yMax [expr max([[lindex $points 0] getY], [[lindex $points 1] getY], [[lindex $points 2] getY], [[lindex $points 3] getY])]
+
+      set layer [$tech findLayer $lay]
+      odb::dbBox_create $bpin $layer $xMin $yMin $xMax $yMax
+      if {[info exists r_bpin]} {
+        odb::dbBox_create $r_bpin $layer $xMin $yMin $xMax $yMax
+      }
+
+    }
+  }
+}
+
+proc export_opendb_power_pins {} {
+  variable block
+  variable design_data
+
+  foreach net_name [dict get $design_data power_nets] {
+    export_opendb_power_pin $net_name "POWER"
+  }
+
+  foreach net_name [dict get $design_data ground_nets] {
+    export_opendb_power_pin $net_name "GROUND"
+  }
+
+}
+
+## procedure for file existence check, returns 0 if file does not exist or file exists, but empty
+proc file_exists_non_empty {filename} {
+  return [expr [file exists $filename] && [file size $filename] > 0]
+}
+
+proc get {args} {
+  variable design_data
+
+  return [dict get $design_data {*}$args]
+}
+proc get_macro_power_pins {inst_name} {
+  set specification [select_instance_specification $inst_name]
+  if {[dict exists $specification power_pins]} {
+    return [dict get $specification power_pins]
+  }
+  return "VDDPE VDDCE"
+}
+proc get_macro_ground_pins {inst_name} {
+  set specification [select_instance_specification $inst_name]
+  if {[dict exists $specification ground_pins]} {
+    return [dict get $specification ground_pins]
+  }
+  return "VSSE"
+}
+
+proc transform_box {xmin ymin xmax ymax origin orientation} {
+  switch -exact $orientation {
+    R0    {set new_box [list $xmin $ymin $xmax $ymax]}
+    R90   {set new_box [list [expr -1 * $ymax] $xmin [expr -1 * $ymin] $xmax]}
+    R180  {set new_box [list [expr -1 * $xmax] [expr -1 * $ymax] [expr -1 * $xmin] [expr -1 * $ymin]]}
+    R270  {set new_box [list $ymin [expr -1 * $xmax] $ymax [expr -1 * $xmin]]}
+    MX    {set new_box [list $xmin [expr -1 * $ymax] $xmax [expr -1 * $ymin]]}
+    MY    {set new_box [list [expr -1 * $xmax] $ymin [expr -1 * $xmin] $ymax]}
+    MXR90 {set new_box [list $ymin $xmin $ymax $xmax]}
+    MYR90 {set new_box [list [expr -1 * $ymax] [expr -1 * $xmax] [expr -1 * $ymin] [expr -1 * $xmin]]}
+    default {utl::error "PDN" 27 "Illegal orientation $orientation specified."}
+  }
+  return [list \
+    [expr [lindex $new_box 0] + [lindex $origin 0]] \
+    [expr [lindex $new_box 1] + [lindex $origin 1]] \
+    [expr [lindex $new_box 2] + [lindex $origin 0]] \
+    [expr [lindex $new_box 3] + [lindex $origin 1]] \
+  ]
+}
+
+proc set_template_size {width height} {
+  variable template
+  variable def_units
+
+  dict set template width [expr round($width * $def_units)]
+  dict set template height [expr round($height * $def_units)]
+}
+
+proc get_memory_instance_pg_pins {} {
+  variable block
+  variable metal_layers
+
+  # debug "start"
+  set boundary [odb::newSetFromRect {*}[get_core_area]]
+
+  foreach inst [$block getInsts] {
+    set inst_name [$inst getName]
+    set master [$inst getMaster]
+
+    if {![$master isBlock]} {continue}
+
+    # If there are no shapes left after 'and'ing the boundard with the cell, then
+    # the cell lies outside the area where we are adding a power grid.
+    set bbox [$inst getBBox]
+    set box [odb::newSetFromRect [$bbox xMin] [$bbox yMin] [$bbox xMax] [$bbox yMax]]
+    if {[llength [odb::getPolygons [odb::andSet $boundary $box]]] == 0} {
+      # debug "Instance [$inst getName] does not lie in the cell area"
+      continue
+    }
+
+    # debug "cell name - [$master getName]"
+
+    foreach term_name [concat [get_macro_power_pins $inst_name] [get_macro_ground_pins $inst_name]] {
+      set master [$inst getMaster]
+      set mterm [$master findMTerm $term_name]
+      if {$mterm == "NULL"} {
+        utl::warn "PDN" 37 "Cannot find pin $term_name on instance [$inst getName] ([[$inst getMaster] getName])."
+        continue
+      }
+
+      set type [$mterm getSigType]
+      foreach mPin [$mterm getMPins] {
+        foreach geom [$mPin getGeometry] {
+          set layer [[$geom getTechLayer] getName]
+          if {[lsearch -exact $metal_layers $layer] == -1} {continue}
+
+          set box [transform_box [$geom xMin] [$geom yMin] [$geom xMax] [$geom yMax] [$inst getOrigin] [$inst getOrient]]
+
+          set width  [expr abs([lindex $box 2] - [lindex $box 0])]
+          set height [expr abs([lindex $box 3] - [lindex $box 1])]
+
+          if {$width > $height} {
+            set layer_name ${layer}_PIN_hor
+          } else {
+            set layer_name ${layer}_PIN_ver
+          }
+          # debug "Adding pin for [$inst getName]:[$mterm getName] to layer $layer_name ($box)"
+          add_stripe $layer_name $type [odb::newSetFromRect {*}$box]
+        }
+      }
+    }
+  }
+  # debug "Total walltime till macro pin geometry creation = [expr {[expr {[clock clicks -milliseconds] - $::start_time}]/1000.0}] seconds"
+  # debug "end"
+}
+
+proc set_core_area {xmin ymin xmax ymax} {
+  variable design_data
+
+  dict set design_data config core_area [list $xmin $ymin $xmax $ymax]
+}
+
+proc get_core_area {} {
+  variable design_data
+
+  return [get_extent [get_stdcell_area]]
+}
+
+proc write_pdn_strategy {} {
+  variable design_data
+
+  if {[dict exists $design_data grid]} {
+    set_pdn_string_property_value "strategy" [dict get $design_data grid]
+  }
+
+}
+
+proc init_tech {} {
+  variable db
+  variable block
+  variable tech
+  variable libs
+  variable def_units
+
+  set db [ord::get_db]
+  set tech [ord::get_db_tech]
+  set libs [$db getLibs]
+  set block [ord::get_db_block]
+
+  set def_units [$block getDefUnits]
+
+  init_metal_layers
+  init_via_tech
+
+}
+
+proc add_power_net {net_name} {
+  variable power_nets
+
+  if {[lsearch -exact $power_nets $net_name] == -1} {
+    lappend power_nets $net_name
+  }
+}
+
+proc add_ground_net {net_name} {
+  variable ground_nets
+
+  if {[lsearch -exact $ground_nets $net_name] == -1} {
+    lappend ground_nets $net_name
+  }
+}
+
+proc get_default_halo {} {
+  if {[info vars ::halo] != ""} {
+    if {[llength $::halo] == 1} {
+      set default_halo "$::halo $::halo $::halo $::halo"
+    } elseif {[llength $::halo] == 2} {
+      set default_halo "$::halo $::halo"
+    } elseif {[llength $::halo] == 4} {
+      set default_halo $::halo
+    } else {
+      utl::error "PDN" 29 "Illegal number of elements defined for ::halo \"$::halo\" (1, 2 or 4 allowed)."
+    }
+  } else {
+    set default_halo "0 0 0 0"
+  }
+  return [lmap x $default_halo {ord::microns_to_dbu $x}]
+}
+
+proc get_row_height {} {
+  set first_row [lindex [[ord::get_db_block] getRows] 0]
+  set row_site [$first_row getSite]
+
+  return [$row_site getHeight]
+}
+
+proc init {args} {
+  variable db
+  variable block
+  variable tech
+  variable libs
+  variable design_data
+  variable def_output
+  variable default_grid_data
+  variable design_name
+  variable stripe_locs
+  variable site
+  variable row_height
+  variable metal_layers
+  variable def_units
+  variable stripes_start_with
+  variable physical_viarules
+  variable stdcell_area
+  variable voltage_domains
+  variable global_connections
+  variable default_global_connections
+  variable power_nets
+  variable ground_nets
+
+  # debug "start" 
+  init_tech 
+
+  set design_name [$block getName]
+
+  set physical_viarules {}
+  set stdcell_area ""
+ 
+  set die_area [$block getDieArea]
+
+  utl::info "PDN" 8 "Design name is $design_name."
+  set def_output "${design_name}_pdn.def"
+
+  # debug "examine vars"
+  if {$power_nets == {}} {
+    if {[info vars ::power_nets] == ""} {
+      set power_nets "VDD"
+    } else {
+      set power_nets $::power_nets
+    }
+  }
+  
+  if {$ground_nets == {}} {
+    if {[info vars ::ground_nets] == ""} {
+      set ground_nets "VSS"
+    } else {
+      set ground_nets $::ground_nets
+    }
+  }
+
+  if {[info vars ::core_domain] == ""} {
+    set core_domain "CORE"
+    if {![dict exists $voltage_domains $core_domain primary_power]} {
+      dict set voltage_domains $core_domain primary_power [lindex $power_nets 0]
+    }
+    if {![dict exists $voltage_domains $core_domain primary_ground]} {
+      dict set voltage_domains $core_domain primary_ground [lindex $ground_nets 0]
+    }
+  } else {
+    set core_domain $::core_domain
+  }
+
+  if {[info vars ::stripes_start_with] == ""} {
+    set stripes_start_with "GROUND"
+  } else {
+    set stripes_start_with $::stripes_start_with
+  }
+  
+  dict set design_data power_nets $power_nets
+  dict set design_data ground_nets $ground_nets
+  dict set design_data core_domain $core_domain
+
+  # Sourcing user inputs file
+  #
+  set row_height [get_row_height]
+
+  ##### Get information from BEOL LEF
+  utl::info "PDN" 9 "Reading technology data."
+
+  if {[info vars ::layers] != ""} {
+    foreach layer $::layers {
+      if {[dict exists $::layers $layer widthtable]} {
+        dict set ::layers $layer widthtable [lmap x [dict get $::layers $layer widthtable] {expr $x * $def_units}]
+      }
+    }
+    set_layer_info $::layers
+  }
+
+  dict set design_data config def_output   $def_output
+  dict set design_data config design       $design_name
+  dict set design_data config die_area     [list [$die_area xMin]  [$die_area yMin] [$die_area xMax] [$die_area yMax]]
+
+  array unset stripe_locs
+
+  ########################################
+  # Remove existing power/ground nets
+  #######################################
+  foreach pg_net [concat [dict get $design_data power_nets] [dict get $design_data ground_nets]] {
+    set net [$block findNet $pg_net]
+    if {$net != "NULL"} {
+      foreach swire [$net getSWires] {
+        odb::dbSWire_destroy $swire
+      }
+    }
+  }
+
+  # debug "Set the core area"
+  # Set the core area
+  if {[info vars ::core_area_llx] != "" && [info vars ::core_area_lly] != "" && [info vars ::core_area_urx] != "" && [info vars ::core_area_ury] != ""} {
+     # The core area is larger than the stdcell area by half a rail, since the stdcell rails extend beyond the rails
+     set_core_area \
+       [expr round($::core_area_llx * $def_units)] \
+       [expr round($::core_area_lly * $def_units)] \
+       [expr round($::core_area_urx * $def_units)] \
+       [expr round($::core_area_ury * $def_units)]
+  } else {
+    set_core_area {*}[get_extent [get_stdcell_plus_area]]
+  }
+
+  ##### Basic sanity checks to see if inputs are given correctly
+  foreach layer [get_rails_layers] {
+    if {[lsearch -exact $metal_layers $layer] < 0} {
+      utl::error "PDN" 30 "Layer specified for stdcell rails '$layer' not in list of layers."
+    }
+  }
+  # debug "end"
+
+  return $design_data
+}
+
+proc convert_layer_spec_to_def_units {data} {
+  foreach key {width pitch spacing offset pad_offset core_offset} {
+    if {[dict exists $data $key]} {
+      dict set data $key [ord::microns_to_dbu [dict get $data $key]]
+    }
+  }
+  return $data
+}
+
+proc specify_grid {type specification} {
+  if {![dict exists $specification type]} {
+    dict set specification type $type
+  }
+  verify_grid $specification
+}
+
+proc get_quadrant {rect x y} {
+  set dw [expr [lindex $rect 2] - [lindex $rect 0]]
+  set dh [expr [lindex $rect 3] - [lindex $rect 1]]
+
+  set test_x [expr $x - [lindex $rect 0]]
+  set test_y [expr $y - [lindex $rect 1]]
+  # debug "$dw * $test_y ([expr $dw * $test_y]) > expr $dh * $test_x ([expr $dh * $test_x])"
+  if {$dw * $test_y > $dh * $test_x} {
+    # Top or left
+    if {($dw * $test_y) + ($dh * $test_x) > ($dw * $dh)} {
+      # Top or right
+      return "t"
+    } else {
+      # Bottom or left
+      return "l"
+    }
+  } else {
+    # Bottom or right
+    if {($dw * $test_y) + ($dh * $test_x) > ($dw * $dh)} {
+      # Top or right
+      return "r"
+    } else {
+      # Bottom or left
+      return "b"
+    }
+  }
+}
+
+proc get_design_quadrant {x y} {
+  variable design_data
+
+  set die_area [dict get $design_data config die_area]
+  return [get_quadrant $die_area $x $y]
+}
+
+proc get_core_facing_pins {instance pin_name side layer} {
+  variable block
+  set geoms {}
+  set core_pins {}
+  set inst [$block findInst [dict get $instance name]]
+  if {[set iterm [$inst findITerm $pin_name]] == "NULL"} {
+    utl::warn "PDN" 55 "Cannot find pin $pin_name on inst [$inst getName]."
+    return {}
+  }
+  if {[set mterm [$iterm getMTerm]] == "NULL"} {
+    utl::warn "PDN" 56 "Cannot find master pin $pin_name for cell [[$inst getMaster] getName]."
+    return {}
+  }
+  set pins [$mterm getMPins]
+
+  # debug "start"
+  foreach pin $pins {
+    foreach geom [$pin getGeometry] {
+      if {[[$geom getTechLayer] getName] != $layer} {continue}
+      lappend geoms $geom
+    }
+  }
+  # debug "$pins"
+  foreach geom $geoms {
+    set ipin [transform_box [$geom xMin] [$geom yMin] [$geom xMax] [$geom yMax] [$inst getOrigin] [$inst getOrient]]
+    # debug "$ipin [[$inst getBBox] xMin] [[$inst getBBox] yMin] [[$inst getBBox] xMax] [[$inst getBBox] yMax] "
+    switch $side {
+      "t" {
+        if {[lindex $ipin 1] == [[$inst getBBox] yMin]} {
+          lappend core_pins [list \
+            centre [expr ([lindex $ipin 2] + [lindex $ipin 0]) / 2] \
+            width [expr [lindex $ipin 2] - [lindex $ipin 0]] \
+          ]
+        }
+      }
+      "b" {
+        if {[lindex $ipin 3] == [[$inst getBBox] yMax]} {
+          lappend core_pins [list \
+            centre [expr ([lindex $ipin 2] + [lindex $ipin 0]) / 2] \
+            width [expr [lindex $ipin 2] - [lindex $ipin 0]] \
+          ]
+        }
+      }
+      "l" {
+        if {[lindex $ipin 2] == [[$inst getBBox] xMax]} {
+          lappend core_pins [list \
+            centre [expr ([lindex $ipin 3] + [lindex $ipin 1]) / 2] \
+            width [expr [lindex $ipin 3] - [lindex $ipin 1]] \
+          ]
+        }
+      }
+      "r" {
+        if {[lindex $ipin 0] == [[$inst getBBox] xMin]} {
+          lappend core_pins [list \
+            centre [expr ([lindex $ipin 3] + [lindex $ipin 1]) / 2] \
+            width [expr [lindex $ipin 3] - [lindex $ipin 1]] \
+          ]
+        }
+      }
+    }
+  }
+  # debug "$core_pins"
+  return $core_pins
+}
+
+proc connect_pads_to_core_ring {type pin_name pads} {
+  variable grid_data
+  variable pad_cell_blockages
+
+  dict for {inst_name instance} [find_instances_of $pads] {
+    set side [get_design_quadrant [dict get $instance x] [dict get $instance y]]
+    switch $side {
+      "t" {
+        set required_direction "ver"
+      }
+      "b" {
+        set required_direction "ver"
+      }
+      "l" {
+        set required_direction "hor"
+      }
+      "r" {
+        set required_direction "hor"
+      }
+    }
+    foreach non_pref_layer [dict keys [dict get $grid_data core_ring]] {
+      if {[get_dir $non_pref_layer] != $required_direction} {
+        set non_pref_layer_info [dict get $grid_data core_ring $non_pref_layer]
+        break
+      }
+    }
+    # debug "find_layer"
+    foreach pref_layer [dict keys [dict get $grid_data core_ring]] {
+      if {[get_dir $pref_layer] == $required_direction} {
+        break
+      }
+    }
+    switch $side {
+      "t" {
+        set y_min [expr [get_core_ring_centre $type $side $non_pref_layer_info] - [dict get $grid_data core_ring $non_pref_layer width] / 2]
+        set y_min_blk [expr $y_min - [dict get $grid_data core_ring $non_pref_layer spacing]]
+        set y_max [dict get $instance ymin]
+        # debug "t: [dict get $instance xmin] $y_min_blk [dict get $instance xmax] [dict get $instance ymax]"
+        add_padcell_blockage $pref_layer [odb::newSetFromRect [dict get $instance xmin] $y_min_blk [dict get $instance xmax] [dict get $instance ymax]]
+      }
+      "b" {
+        # debug "[get_core_ring_centre $type $side $non_pref_layer_info] + [dict get $grid_data core_ring $non_pref_layer width] / 2"
+        set y_max [expr [get_core_ring_centre $type $side $non_pref_layer_info] + [dict get $grid_data core_ring $non_pref_layer width] / 2]
+        set y_max_blk [expr $y_max + [dict get $grid_data core_ring $non_pref_layer spacing]]
+        set y_min [dict get $instance ymax]
+        # debug "b: [dict get $instance xmin] [dict get $instance ymin] [dict get $instance xmax] $y_max"
+        add_padcell_blockage $pref_layer [odb::newSetFromRect [dict get $instance xmin] [dict get $instance ymin] [dict get $instance xmax] $y_max_blk]
+        # debug "end b"
+      }
+      "l" {
+        set x_max [expr [get_core_ring_centre $type $side $non_pref_layer_info] + [dict get $grid_data core_ring $non_pref_layer width] / 2]
+        set x_max_blk [expr $x_max + [dict get $grid_data core_ring $non_pref_layer spacing]]
+        set x_min [dict get $instance xmax]
+        # debug "l: [dict get $instance xmin] [dict get $instance ymin] $x_max [dict get $instance ymax]"
+        add_padcell_blockage $pref_layer [odb::newSetFromRect [dict get $instance xmin] [dict get $instance ymin] $x_max_blk [dict get $instance ymax]]
+      }
+      "r" {
+        set x_min [expr [get_core_ring_centre $type $side $non_pref_layer_info] - [dict get $grid_data core_ring $non_pref_layer width] / 2]
+        set x_min_blk [expr $x_min - [dict get $grid_data core_ring $non_pref_layer spacing]]
+        set x_max [dict get $instance xmin]
+        # debug "r: $x_min_blk [dict get $instance ymin] [dict get $instance xmax] [dict get $instance ymax]"
+        add_padcell_blockage $pref_layer [odb::newSetFromRect $x_min_blk [dict get $instance ymin] [dict get $instance xmax] [dict get $instance ymax]]
+      }
+    }
+
+    # debug "$pref_layer"
+    foreach pin_geometry [get_core_facing_pins $instance $pin_name $side $pref_layer] {
+      set centre [dict get $pin_geometry centre]
+      set width  [dict get $pin_geometry width]
+
+      variable tech
+      if {[[set layer [$tech findLayer $pref_layer]] getMaxWidth] != "NULL" && $width > [$layer getMaxWidth]} {
+        set width [$layer getMaxWidth]
+      }
+      if {$required_direction == "hor"} {
+        # debug "added_strap $pref_layer $type $x_min [expr $centre - $width / 2] $x_max [expr $centre + $width / 2]"
+        add_stripe $pref_layer "PAD_$type" [odb::newSetFromRect $x_min [expr $centre - $width / 2] $x_max [expr $centre + $width / 2]]
+      } else {
+        # debug "added_strap $pref_layer $type [expr $centre - $width / 2] $y_min [expr $centre + $width / 2] $y_max"
+        add_stripe $pref_layer "PAD_$type" [odb::newSetFromRect [expr $centre - $width / 2] $y_min [expr $centre + $width / 2] $y_max]
+      }
+    }
+  }
+  # debug "end"
+}
+
+proc add_pad_straps {tag} {
+  variable stripe_locs
+
+  foreach pad_connection [array names stripe_locs "*,PAD_*"] {
+    if {![regexp "(.*),PAD_$tag" $pad_connection - layer]} {continue}
+    # debug "$pad_connection"
+    if {[array names stripe_locs "$layer,$tag"] != ""} {
+      # debug add_pad_straps "Before: $layer [llength [::odb::getPolygons $stripe_locs($layer,$tag)]]"
+      # debug add_pad_straps "Adding: [llength [::odb::getPolygons $stripe_locs($pad_connection)]]"
+      add_stripe $layer $tag $stripe_locs($pad_connection)
+      # debug add_pad_straps "After:  $layer [llength [::odb::getPolygons $stripe_locs($layer,$tag)]]"
+    }
+  }
+}
+
+proc print_spacing_table {layer_name} {
+  set layer [find_layer $layer_name]
+  if {[$layer hasTwoWidthsSpacingRules]} {
+    set table_size [$layer getTwoWidthsSpacingTableNumWidths]
+    for {set i 0} {$i < $table_size} {incr i} {
+      set width [$layer getTwoWidthsSpacingTableWidth $i]
+      set report_width "WIDTH $width"
+      if {[$layer getTwoWidthsSpacingTableHasPRL $i]} {
+        set prl [$layer getTwoWidthsSpacingTablePRL $i]
+        set report_prl " PRL $prl"
+      } else {
+        set report_prl ""
+      }
+      set report_spacing " [$layer getTwoWidthsSpacingTableEntry 0 $i] "
+    }
+    utl::report "${report_width}${report_prl}${report_spacing}"
+  }
+}
+
+proc get_twowidths_table {table_type} {
+  variable metal_layers
+  set twowidths_table {}
+
+  foreach layer_name $metal_layers {
+    set spacing_table [get_spacingtables $layer_name]
+    set prls {}
+
+    if {[dict exists $spacing_table TWOWIDTHS $table_type]} {
+      set layer_spacing_table [dict get $spacing_table TWOWIDTHS $table_type]
+      set table_size [dict size $layer_spacing_table]
+      set table_widths [dict keys $layer_spacing_table]
+
+      for {set i 0} {$i < $table_size} {incr i} {
+
+        set width [lindex $table_widths $i]
+        set spacing [lindex [dict get $layer_spacing_table $width spacings] $i]
+
+        if {[dict get $layer_spacing_table $width prl] != 0} {
+          set prl [dict get $layer_spacing_table $width prl]
+          set update_prls {}
+          dict for {prl_entry prl_setting} $prls {
+            if {$prl <= [lindex $prl_entry 0]} {break}
+            dict set update_prls $prl_entry $prl_setting
+            dict set twowidths_table $layer_name $width $prl_entry $prl_setting
+          }
+          dict set update_prls $prl $spacing
+          dict set twowidths_table $layer_name $width $prl $spacing
+          set prls $update_prls
+        } else {
+          set prls {}
+          dict set prls 0 $spacing
+          dict set twowidths_table $layer_name $width 0 $spacing
+        }
+      }
+    }
+  }
+
+  return $twowidths_table
+}
+
+proc get_twowidths_tables {} {
+  variable twowidths_table
+  variable twowidths_table_wrongdirection
+
+  set twowidths_table [get_twowidths_table NONE]
+  set twowidths_table_wrongdirection [get_twowidths_table WRONGDIRECTION]
+}
+
+proc select_from_table {table width} {
+  foreach value [lreverse [lsort -integer [dict keys $table]]] {
+    if {$width > $value} {
+      return $value
+    }
+  }
+  return [lindex [dict keys $table] 0]
+}
+
+proc get_preferred_direction_spacing {layer_name width prl} {
+  variable twowidths_table
+
+  # debug "$layer_name $width $prl"
+  # debug "twowidths_table $twowidths_table"
+  if {$twowidths_table == {}} {
+    return [[find_layer $layer_name] getSpacing]
+  } else {
+    set width_key [select_from_table [dict get $twowidths_table $layer_name] $width]
+    set prl_key   [select_from_table [dict get $twowidths_table $layer_name $width_key] $prl]
+  }
+
+  return [dict get $twowidths_table $layer_name $width_key $prl_key]
+}
+
+proc get_nonpreferred_direction_spacing {layer_name width prl} {
+  variable twowidths_table_wrongdirection
+
+  # debug "twowidths_table_wrong_direction $twowidths_table_wrongdirection"
+  if {[dict exists $twowidths_table_wrongdirection $layer_name]} {
+    set width_key [select_from_table [dict get $twowidths_table_wrongdirection $layer_name] $width]
+    set prl_key   [select_from_table [dict get $twowidths_table_wrongdirection $layer_name $width_key] $prl]
+  } else {
+    return [get_preferred_direction_spacing $layer_name $width $prl]
+  }
+
+  return [dict get $twowidths_table_wrongdirection $layer_name $width_key $prl_key]
+}
+
+proc create_obstructions {layer_name polygons} {
+  set layer [find_layer $layer_name]
+  set min_spacing [get_preferred_direction_spacing $layer_name 0 0]
+
+  # debug "Num polygons [llength $polygons]"
+
+  foreach polygon $polygons {
+    set points [::odb::getPoints $polygon]
+    if {[llength $points] != 4} {
+      utl::warn "PDN" 6 "Unexpected number of points in stripe of $layer_name."
+      continue
+    }
+    set xMin [expr min([[lindex $points 0] getX], [[lindex $points 1] getX], [[lindex $points 2] getX], [[lindex $points 3] getX])]
+    set xMax [expr max([[lindex $points 0] getX], [[lindex $points 1] getX], [[lindex $points 2] getX], [[lindex $points 3] getX])]
+    set yMin [expr min([[lindex $points 0] getY], [[lindex $points 1] getY], [[lindex $points 2] getY], [[lindex $points 3] getY])]
+    set yMax [expr max([[lindex $points 0] getY], [[lindex $points 1] getY], [[lindex $points 2] getY], [[lindex $points 3] getY])]
+
+    if {[get_dir $layer_name] == "hor"} {
+      set required_spacing_pref    [get_preferred_direction_spacing $layer_name [expr $yMax - $yMin] [expr $xMax - $xMin]]
+      set required_spacing_nonpref [get_nonpreferred_direction_spacing $layer_name [expr $xMax - $xMin] [expr $yMax - $yMin]]
+
+      set y_change [expr $required_spacing_pref    - $min_spacing]
+      set x_change [expr $required_spacing_nonpref - $min_spacing]
+    } else {
+      set required_spacing_pref    [get_preferred_direction_spacing $layer_name [expr $xMax - $xMin] [expr $yMax - $yMin]]
+      set required_spacing_nonpref [get_nonpreferred_direction_spacing $layer_name [expr $yMax - $yMin] [expr $xMax - $xMin]]
+
+      set x_change [expr $required_spacing_pref    - $min_spacing]
+      set y_change [expr $required_spacing_nonpref - $min_spacing]
+    }
+
+    create_obstruction_object_blockage $layer $min_spacing [expr $xMin - $x_change] [expr $yMin - $y_change] [expr $xMax + $x_change] [expr $yMax + $y_change]
+  }
+}
+
+proc combine {lside rside} {
+  # debug "l [llength $lside] r [llength $rside]"
+  if {[llength $lside] > 1} {
+    set lside [combine [lrange $lside 0 [expr [llength $lside] / 2 - 1]] [lrange $lside [expr [llength $lside] / 2] end]]
+  }
+  if {[llength $rside] > 1} {
+    set rside [combine [lrange $rside 0 [expr [llength $rside] / 2 - 1]] [lrange $rside [expr [llength $rside] / 2] end]]
+  }
+  return [odb::orSet $lside $rside]
+}
+
+proc shapes_to_polygonSet {shapes} {
+  if {[llength $shapes] == 1} {
+    return $shapes
+  }
+  return [combine [lrange $shapes 0 [expr [llength $shapes] / 2 - 1]] [lrange $shapes [expr [llength $shapes] / 2] end]]
+}
+
+proc generate_obstructions {layer_name} {
+  variable stripe_locs
+
+  # debug "layer $layer_name"
+  get_twowidths_tables
+
+  set block_shapes {}
+  foreach tag {"POWER" "GROUND"} {
+    if {[array names stripe_locs $layer_name,$tag] == ""} {
+      # debug "No polygons on $layer_name,$tag"
+      continue
+    }
+    if {$block_shapes == {}} {
+      set block_shapes $stripe_locs($layer_name,$tag)
+    } else {
+      set block_shapes [odb::orSet $block_shapes $stripe_locs($layer_name,$tag)]
+    }
+  }
+  set via_shapes 0
+  variable vias
+  # debug "vias - [llength $vias]"
+  foreach via $vias {
+    # For each layer between l1 and l2, add vias at the intersection
+    foreach via_inst [dict get $via connections] {
+      # debug "$via_inst"
+      set via_name [dict get $via_inst name]
+      set x        [dict get $via_inst x]
+      set y        [dict get $via_inst y]
+
+      set lower_layer_name [lindex [dict get $via_inst layers] 0]
+      set upper_layer_name [lindex [dict get $via_inst layers] 2]
+
+      if {$lower_layer_name == $layer_name && [dict exists $via_inst lower_rect]} {
+        lappend block_shapes [odb::newSetFromRect {*}[transform_box {*}[dict get $via_inst lower_rect] [list $x $y] "R0"]]
+        incr via_shapes
+      } elseif {$upper_layer_name == $layer_name && [dict exists $via_inst upper_rect]} {
+        lappend block_shapes [odb::newSetFromRect {*}[transform_box {*}[dict get $via_inst upper_rect] [list $x $y] "R0"]]
+        incr via_shapes
+      }
+    }
+  }
+  # debug "Via shapes $layer_name $via_shapes"
+  if {$block_shapes != {}} {
+  # debug "create_obstructions [llength $block_shapes]"
+    create_obstructions $layer_name [odb::getPolygons [shapes_to_polygonSet $block_shapes]]
+  }
+  # debug "end"
+}
+
+proc create_obstruction_object_blockage {layer min_spacing xMin yMin xMax yMax} {
+  variable block
+
+
+  set layer_pitch [get_pitch $layer]
+  set layer_width [$layer getWidth]
+  # debug "Layer - [$layer getName], pitch $layer_pitch, width $layer_width"
+  set tracks [$block findTrackGrid $layer]
+  set offsetX [lindex [$tracks getGridX] 0]
+  set offsetY [lindex [$tracks getGridY] 0]
+
+  # debug "OBS: [$layer getName] $xMin $yMin $xMax $yMax (dx [expr $xMax - $xMin] dy [expr $yMax - $yMin])"
+  # debug "Offsets: x $offsetX y $offsetY"
+  set relative_xMin [expr $xMin - $offsetX]
+  set relative_xMax [expr $xMax - $offsetX]
+  set relative_yMin [expr $yMin - $offsetY]
+  set relative_yMax [expr $yMax - $offsetY]
+  # debug "relative to core area $relative_xMin $relative_yMin $relative_xMax $relative_yMax"
+
+  # debug "OBS: [$layer getName] $xMin $yMin $xMax $yMax"
+  # Determine which tracks are blocked
+  if {[get_dir [$layer getName]] == "hor"} {
+    set pitch_start [expr $relative_yMin / $layer_pitch]
+    if {$relative_yMin % $layer_pitch >= ($min_spacing + $layer_width / 2)} {
+      incr pitch_start
+    }
+    set pitch_end [expr $relative_yMax / $layer_pitch]
+    if {$relative_yMax % $layer_pitch > $layer_width / 2} {
+      incr pitch_end
+    }
+    # debug "pitch: start $pitch_start end $pitch_end"
+    for {set i $pitch_start} {$i <= $pitch_end} {incr i} {
+      set obs [odb::dbObstruction_create $block $layer \
+        $xMin \
+        [expr $i * $layer_pitch + $offsetY - $layer_width / 2] \
+        $xMax \
+        [expr $i * $layer_pitch + $offsetY + $layer_width / 2] \
+      ]
+    }
+  } else {
+    set pitch_start [expr $relative_xMin / $layer_pitch]
+    if {$relative_xMin % $layer_pitch >= ($min_spacing + $layer_width / 2)} {
+      incr pitch_start
+    }
+    set pitch_end [expr $relative_xMax / $layer_pitch]
+    if {$relative_xMax % $layer_pitch > $layer_width / 2} {
+      incr pitch_end
+    }
+    # debug "pitch: start $pitch_start end $pitch_end"
+    for {set i $pitch_start} {$i <= $pitch_end} {incr i} {
+      set obs [odb::dbObstruction_create $block $layer \
+        [expr $i * $layer_pitch + $offsetX - $layer_width / 2] \
+        $yMin \
+        [expr $i * $layer_pitch + $offsetX + $layer_width / 2] \
+        $yMax \
+      ]
+    }
+  }
+}
+
+proc create_obstruction_object_net {layer min_spacing xMin yMin xMax yMax} {
+  variable block
+  variable obstruction_index
+
+  incr obstruction_index
+  set net_name "obstruction_$obstruction_index"
+  if {[set obs_net [$block findNet $net_name]] == "NULL"} {
+    set obs_net [odb::dbNet_create $block $net_name]
+  }
+  # debug "obs_net [$obs_net getName]"
+  if {[set wire [$obs_net getWire]] == "NULL"} {
+    set wire [odb::dbWire_create $obs_net]
+  }
+  # debug "Wire - net [[$wire getNet] getName]"
+  set encoder [odb::dbWireEncoder]
+  $encoder begin $wire
+
+  set layer_pitch [$layer getPitch]
+  set layer_width [$layer getWidth]
+  # debug "Layer - [$layer getName], pitch $layer_pitch, width $layer_width"
+  set core_area [get_core_area]
+  # debug "core_area $core_area"
+  set relative_xMin [expr $xMin - [lindex $core_area 0]]
+  set relative_xMax [expr $xMax - [lindex $core_area 0]]
+  set relative_yMin [expr $yMin - [lindex $core_area 1]]
+  set relative_yMax [expr $yMax - [lindex $core_area 1]]
+  # debug "relative to core area $relative_xMin $relative_yMin $relative_xMax $relative_yMax"
+
+  # debug "OBS: [$layer getName] $xMin $yMin $xMax $yMax"
+  # Determine which tracks are blocked
+  if {[get_dir [$layer getName]] == "hor"} {
+    set pitch_start [expr $relative_yMin / $layer_pitch]
+    if {$relative_yMin % $layer_pitch > ($min_spacing + $layer_width / 2)} {
+      incr pitch_start
+    }
+    set pitch_end [expr $relative_yMax / $layer_pitch]
+    if {$relative_yMax % $layer_pitch > $layer_width / 2} {
+      incr pitch_end
+    }
+    for {set i $pitch_start} {$i <= $pitch_end} {incr i} {
+      $encoder newPath $layer ROUTED
+      $encoder addPoint [expr $relative_xMin + [lindex $core_area 0]] [expr $i * $layer_pitch + [lindex $core_area 1]]
+      $encoder addPoint [expr $relative_xMax + [lindex $core_area 0]] [expr $i * $layer_pitch + [lindex $core_area 1]]
+    }
+  } else {
+    set pitch_start [expr $relative_xMin / $layer_pitch]
+    if {$relative_xMin % $layer_pitch > ($min_spacing + $layer_width / 2)} {
+      incr pitch_start
+    }
+    set pitch_end [expr $relative_xMax / $layer_pitch]
+    if {$relative_xMax % $layer_pitch > $layer_width / 2} {
+      incr pitch_end
+    }
+    for {set i $pitch_start} {$i <= $pitch_end} {incr i} {
+      $encoder newPath $layer ROUTED
+      $encoder addPoint [expr $i * $layer_pitch + [lindex $core_area 0]] [expr $relative_yMin + [lindex $core_area 1]]
+      $encoder addPoint [expr $i * $layer_pitch + [lindex $core_area 0]] [expr $relative_yMax + [lindex $core_area 1]]
+    }
+  }
+  $encoder end
+}
+
+proc add_grid {} {
+  variable design_data
+  variable grid_data
+
+  if {[dict exists $grid_data core_ring]} {
+    set area [dict get $grid_data area]
+    # debug "Area $area"
+    
+    generate_core_rings [dict get $grid_data core_ring]
+    
+    if {[dict exists $grid_data gnd_pads]} {
+      dict for {pin_name cells} [dict get $grid_data gnd_pads] {
+        connect_pads_to_core_ring "GROUND" $pin_name $cells
+      }
+    }
+    if {[dict exists $grid_data pwr_pads]} {
+      dict for {pin_name cells} [dict get $grid_data pwr_pads] {
+        connect_pads_to_core_ring "POWER" $pin_name $cells
+      }
+    }
+    
+    generate_voltage_domain_rings [dict get $grid_data core_ring]
+    # merge_stripes
+    # set intersections [odb::andSet $stripe_locs(G1,POWER) $stripe_locs(G2,POWER)]
+    # debug "# intersections [llength [odb::getPolygons $intersections]]"
+    # foreach pwr_net [dict get $design_data power_nets] {
+    #   generate_grid_vias "POWER" $pwr_net
+    # }
+    # foreach gnd_net [dict get $design_data ground_nets] {
+    #   generate_grid_vias "GROUND" $gnd_net
+    # }
+    apply_padcell_blockages
+  }
+
+  set area [dict get $grid_data area]
+
+  if {[dict exists $grid_data rails]} {
+    # debug "Adding stdcell rails"
+    # debug "area: [dict get $grid_data area]"
+    set area [dict get $grid_data area]
+    # debug "Area $area"
+    generate_lower_metal_followpin_rails
+  }
+
+  ## Power nets
+  foreach pwr_net [dict get $design_data power_nets] {
+    set tag "POWER"
+    generate_stripes $tag $pwr_net
+  }
+
+  ## Ground nets
+  foreach gnd_net [dict get $design_data ground_nets] {
+    set tag "GROUND"
+    generate_stripes $tag $gnd_net
+  }
+
+  merge_stripes
+
+  ## Power nets
+  # debug "Power straps"
+  foreach pwr_net [dict get $design_data power_nets] {
+    set tag "POWER"
+    cut_blocked_areas $tag
+    add_pad_straps $tag
+  }
+
+  ## Ground nets
+  # debug "Ground straps"
+  foreach gnd_net [dict get $design_data ground_nets] {
+    set tag "GROUND"
+    cut_blocked_areas $tag
+    add_pad_straps $tag
+  }
+  merge_stripes
+
+  if {[dict exists $grid_data obstructions]} {
+    utl::info "PDN" 32 "Generating blockages for TritonRoute."
+    # debug "Obstructions: [dict get $grid_data obstructions]"
+    foreach layer_name [dict get $grid_data obstructions] {
+      generate_obstructions $layer_name
+    }
+  }
+  # debug "end"
+}
+
+proc select_instance_specification {instance} {
+  variable design_data
+  variable instances
+
+  if {![dict exists $instances $instance grid]} {
+    utl::error PAD 248 "Instance $instance is not associated with any grid"
+  }
+  return [dict get $design_data grid macro [dict get $instances $instance grid]]
+}
+
+proc get_instance_specification {instance} {
+  variable instances
+
+  set specification [select_instance_specification $instance]
+
+  if {![dict exists $specification blockages]} {
+    dict set specification blockages {}
+  }
+  dict set specification area [dict get $instances $instance macro_boundary]
+
+  return $specification
+}
+
+proc get_pitch {layer} {
+  if {[$layer hasXYPitch]} {
+    if {[get_dir [$layer getName]] == "hor"} {
+      return [$layer getPitchY]
+    } else {
+      return [$layer getPitchX]
+    }
+  } else {
+    return [$layer getPitch]
+  }
+}
+
+proc get_layer_number {layer_name} {
+  set layer [[ord::get_db_tech] findLayer $layer_name]
+  if {$layer == "NULL"} {
+    utl::error PDN 160 "Cannot find layer $layer_name."
+  }
+  return [$layer getNumber]
+}
+
+proc init_metal_layers {} {
+  variable metal_layers
+  variable layers
+  variable block
+
+  set tech [ord::get_db_tech]
+  set block [ord::get_db_block]
+  set metal_layers {}
+
+  foreach layer [$tech getLayers] {
+    if {[$layer getType] == "ROUTING"} {
+      set_prop_lines $layer LEF58_TYPE
+      # Layers that have LEF58_TYPE are not normal ROUTING layers, so should not be considered
+      if {![empty_propline]} {continue}
+
+      set layer_name [$layer getName]
+      lappend metal_layers $layer_name
+
+      # debug "Direction ($layer_name): [$layer getDirection]"
+      if {[$layer getDirection] == "HORIZONTAL"} {
+        dict set layers $layer_name direction "hor"
+      } else {
+        dict set layers $layer_name direction "ver"
+      }
+      dict set layers $layer_name pitch [get_pitch $layer]
+
+      set tracks [$block findTrackGrid $layer]
+      if {$tracks == "NULL"} {
+        utl::warn "PDN" 35 "No track information found for layer $layer_name."
+      } else {
+        dict set layers $layer_name offsetX [lindex [$tracks getGridX] 0]
+        dict set layers $layer_name offsetY [lindex [$tracks getGridY] 0]
+      }
+    }
+  }
+}
+
+proc get_instance_llx {instance} {
+  variable instances
+  return [lindex [dict get $instances $instance halo_boundary] 0]
+}
+
+proc get_instance_lly {instance} {
+  variable instances
+  return [lindex [dict get $instances $instance halo_boundary] 1]
+}
+
+proc get_instance_urx {instance} {
+  variable instances
+  return [lindex [dict get $instances $instance halo_boundary] 2]
+}
+
+proc get_instance_ury {instance} {
+  variable instances
+  return [lindex [dict get $instances $instance halo_boundary] 3]
+}
+
+proc get_macro_blockage_layers {instance} {
+  variable metal_layers
+
+  set specification [select_instance_specification $instance]
+  if {[dict exists $specification blockages]} {
+    # debug "Block [dict get $specification blockages] for $instance"
+    return [dict get $specification blockages]
+  }
+  return $metal_layers
+}
+
+proc report_layer_details {layer} {
+  variable def_units
+
+  set str " - "
+  foreach element {width pitch spacing offset pad_offset core_offset} {
+    if {[dict exists $layer $element]} {
+      set str [format "$str $element: %.3f " [expr 1.0 * [dict get $layer $element] / $def_units]]
+    }
+  }
+  return $str
+}
+
+proc print_strategy {type specification} {
+  if {[dict exists $specification name]} {
+    set header "Type: ${type}, [dict get $specification name]"
+  } else {
+    set header "Type: $type"
+  }
+
+  if {$type == "macro"} {
+    if {[dict exists $specification grid_over_pg_pins]} {
+      if {[dict get $specification grid_over_pg_pins] == 1} {
+        set header "$header -grid_over_pg_pins"
+      } else {
+        set header "$header -grid_over_boundary"
+      }
+    }
+  }
+
+  utl::report $header
+
+  if {[dict exists $specification core_ring]} {
+    utl::report "    Core Rings"
+    dict for {layer_name layer} [dict get $specification core_ring] {
+      set str "      Layer: $layer_name"
+      if {[dict exists $layer width]} {
+        set str "$str [report_layer_details $layer]"
+        utl::report $str
+      } else {
+        utl::report $str
+        foreach template [dict keys $layer] {
+          utl::report -nonewline [format "          %-14s %s" $template [report_layer_details [dict get $layer $template]]]
+        }
+      }
+    }
+  }
+  if {[dict exists $specification rails]} {
+    utl::report "    Stdcell Rails"
+    dict for {layer_name layer} [dict get $specification rails] {
+      if {[dict exists $layer width]} {
+        utl::report "      Layer: $layer_name [report_layer_details $layer]"
+      } else {
+        utl::report "      Layer: $layer_name"
+        foreach template [dict keys $layer] {
+          utl::report [format "          %-14s %s" $template [report_layer_details [dict get $layer $template]]]
+        }
+      }
+    }
+  }
+  if {[dict exists $specification instance]} {
+    utl::report "    Instance: [dict get $specification instance]"
+  }
+  if {[dict exists $specification macro]} {
+    utl::report "    Macro: [dict get $specification macro]"
+  }
+  if {[dict exists $specification orient]} {
+    utl::report "    Macro orientation: [dict get $specification orient]"
+  }
+  if {[dict exists $specification straps]} {
+    utl::report "    Straps"
+    dict for {layer_name layer} [dict get $specification straps] {
+      if {[dict exists $layer width]} {
+        utl::report "      Layer: $layer_name [report_layer_details $layer]"
+      } else {
+        utl::report "      Layer: $layer_name"
+        foreach template [dict keys $layer] {
+          utl::report [format "          %-14s %s" $template [report_layer_details [dict get $layer $template]]]
+        }
+      }
+    }
+  }
+  if {[dict exists $specification connect]} {
+    utl::report "    Connect: [dict get $specification connect]"
+  }
+}
+
+proc read_template_placement {} {
+  variable plan_template
+  variable def_units
+  variable prop_line
+
+  if {![is_defined_pdn_property "plan_template"]} {
+    define_template_grid
+  } else {
+    set plan_template {}
+    set prop_line [get_pdn_string_property_value "plan_template"]
+    while {![empty_propline]} {
+      set line [read_propline]
+      if {[llength $line] == 0} {continue}
+      set x  [expr round([lindex $line 0] * $def_units)]
+      set y  [expr round([lindex $line 1] * $def_units)]
+      set x1 [expr round([lindex $line 2] * $def_units)]
+      set y1 [expr round([lindex $line 3] * $def_units)]
+      set template [lindex $line end]
+
+      dict set plan_template $x $y $template
+    }
+  }
+}
+
+proc is_defined_pdn_property {name} {
+  variable block
+
+  if {[set pdn_props [::odb::dbBoolProperty_find $block PDN]] == "NULL"} {
+    return 0
+  }
+
+  if {[::odb::dbStringProperty_find $pdn_props $name] == "NULL"} {
+    return 0
+  }
+  return 1
+}
+
+proc get_pdn_string_property {name} {
+  variable block
+
+  if {[set pdn_props [::odb::dbBoolProperty_find $block PDN]] == "NULL"} {
+    set pdn_props [::odb::dbBoolProperty_create $block PDN 1]
+  }
+
+  if {[set prop [::odb::dbStringProperty_find $pdn_props $name]] == "NULL"} {
+    set prop [::odb::dbStringProperty_create $pdn_props $name ""]
+  }
+
+  return $prop
+}
+
+proc set_pdn_string_property_value {name value} {
+  set prop [get_pdn_string_property $name]
+  $prop setValue $value
+}
+
+proc get_pdn_string_property_value {name} {
+  set prop [get_pdn_string_property $name]
+
+  return [$prop getValue]
+}
+
+proc write_template_placement {} {
+  variable plan_template
+  variable template
+  variable def_units
+
+  set str ""
+  foreach x [lsort -integer [dict keys $plan_template]] {
+    foreach y [lsort -integer [dict keys [dict get $plan_template $x]]] {
+      set str [format "${str}%.3f %.3f %.3f %.3f %s ;\n" \
+        [expr 1.0 * $x / $def_units] [expr 1.0 * $y / $def_units] \
+        [expr 1.0 * ($x + [dict get $template width]) / $def_units] [expr 1.0 * ($y + [dict get $template height]) / $def_units] \
+        [dict get $plan_template $x $y]
+      ]
+    }
+  }
+
+  set_pdn_string_property_value "plan_template" $str
+}
+
+proc get_extent {polygon_set} {
+  set first_point  [lindex [odb::getPoints [lindex [odb::getPolygons $polygon_set] 0]] 0]
+  set minX [set maxX [$first_point getX]]
+  set minY [set maxY [$first_point getY]]
+
+  foreach shape [odb::getPolygons $polygon_set] {
+    foreach point [odb::getPoints $shape] {
+      set x [$point getX]
+      set y [$point getY]
+      set minX [expr min($minX,$x)]
+      set maxX [expr max($maxX,$x)]
+      set minY [expr min($minY,$y)]
+      set maxY [expr max($maxY,$y)]
+    }
+  }
+
+  return [list $minX $minY $maxX $maxY]
+}
+
+proc round_to_routing_grid {layer_name location} {
+  variable tech
+  variable block
+
+  set grid [$block findTrackGrid [$tech findLayer $layer_name]]
+
+  if {[get_dir $layer_name] == "hor"} {
+    set grid_points [$grid getGridY]
+  } else {
+    set grid_points [$grid getGridX]
+  }
+
+  set size [llength $grid_points]
+  set pos [expr ($size + 1) / 2]
+
+  if {[lsearch -exact $grid_points $location] != -1} {
+    return $location
+  }
+  set prev_pos -1
+  set size [expr ($size + 1) / 2]
+  while {!(([lindex $grid_points $pos] < $location) && ($location < [lindex $grid_points [expr $pos + 1]]))} {
+    if {$prev_pos == $pos} {utl::error "PDN" 51 "Infinite loop detected trying to round to grid."}
+    set prev_pos $pos
+    set size [expr ($size + 1) / 2]
+
+    if {$location > [lindex $grid_points $pos]} {
+      set pos [expr $pos + $size]
+    } else {
+      set pos [expr $pos - $size]
+    }
+    # debug "[lindex $grid_points $pos] < $location < [lindex $grid_points [expr $pos + 1]]"
+    # debug [expr (([lindex $grid_points $pos] < $location) && ($location < [lindex $grid_points [expr $pos + 1]]))]
+  }
+
+  return [lindex $grid_points $pos]
+}
+
+proc identify_channels {lower_layer_name upper_layer_name tag} {
+  variable block
+  variable stripe_locs
+
+  set channels {}
+  set wire_groups {}
+
+  set upper_pitch_check [expr round(1.1 * [get_grid_wire_pitch $upper_layer_name])]
+  set lower_pitch_check [expr round(1.1 * [get_grid_wire_pitch $lower_layer_name])]
+  # debug "stripes $lower_layer_name, tag: $tag, $stripe_locs($lower_layer_name,$tag)"
+  # debug "Direction (lower-$lower_layer_name): [get_dir $lower_layer_name] (upper-$upper_layer_name): [get_dir $upper_layer_name]"
+  # debug "Pitch check (lower): [ord::dbu_to_microns $lower_pitch_check], (upper): [ord::dbu_to_microns $upper_pitch_check]"
+  if {[get_dir $lower_layer_name] ==  "hor"} {
+    set channel_wires [odb::subtractSet $stripe_locs($lower_layer_name,$tag) [odb::bloatSet [odb::shrinkSet $stripe_locs($lower_layer_name,$tag) $upper_pitch_check 0] $upper_pitch_check 0]]
+    # Group wires with same xMin and xMax so that the channels form rectangles
+    foreach wire [odb::getRectangles $channel_wires] {
+      set xMin [$wire xMin]
+      set xMax [$wire xMax]
+      dict lappend wire_groups "$xMin,$xMax" [odb::newSetFromRect [$wire xMin] [$wire yMin] [$wire xMax] [$wire yMax]]
+    }
+    if {[dict size $wire_groups] > 1} {
+      dict for {position wires} $wire_groups {
+        lappend channels [odb::shrinkSet [odb::bloatSet [odb::orSets $wires] 0 $lower_pitch_check] 0 $lower_pitch_check]
+      }
+    }
+
+    set channels [odb::orSets $channels]
+    # debug "Channel wires: [llength [odb::getRectangles $channel_wires]]"
+    # debug "Channels: [llength [odb::getRectangles $channels]]"
+  } else {
+    set channel_wires [odb::subtractSet $stripe_locs($lower_layer_name,$tag) [odb::bloatSet [odb::shrinkSet $stripe_locs($lower_layer_name,$tag) 0 $upper_pitch_check] 0 $upper_pitch_check]]
+    # Group wires with same yMin and yMax so that the channels form rectangles
+    foreach wire [odb::getRectangles $channel_wires] {
+      set yMin [$wire yMin]
+      set yMax [$wire yMax]
+      dict lappend wire_groups "$yMin,$yMax" [odb::newSetFromRect [$wire xMin] [$wire yMin] [$wire xMax] [$wire yMax]]
+    }
+    if {[dict size $wire_groups] > 1} {
+      dict for {position wires} $wire_groups {
+        lappend channels [odb::shrinkSet [odb::bloatSet [odb::orSets $wires] $lower_pitch_check 0] $lower_pitch_check 0]
+      }
+    }
+
+    set channels [odb::orSets $channels]
+    # debug "Channel wires: [llength [odb::getRectangles $channel_wires]]"
+    # debug "Channels: [llength [odb::getRectangles $channels]]"
+  }
+
+  foreach rect [odb::getRectangles $channels] {
+    # debug "([ord::dbu_to_microns [$rect xMin]] [ord::dbu_to_microns [$rect yMin]]) - ([ord::dbu_to_microns [$rect xMax]] [ord::dbu_to_microns [$rect yMax]])"
+  }
+  # debug "Number of channels [llength [::odb::getPolygons $channels]]"
+
+  return $channels
+}
+
+
+proc repair_channel {channel layer_name tag min_size} {
+  variable stripe_locs
+
+  if {[get_dir $layer_name] == "hor"} {
+    set channel_height [$channel dx]
+  } else {
+    set channel_height [$channel dy]
+  }
+  set width [get_grid_wire_width $layer_name]
+
+  set xMin [$channel xMin]
+  set xMax [$channel xMax]
+  set yMin [$channel yMin]
+  set yMax [$channel yMax]
+
+  if {$tag == "POWER"} {
+    set other_tag "GROUND"
+  } else {
+    set other_tag "POWER"
+  }
+
+  if {[channel_has_pg_strap $channel $layer_name $other_tag]} {
+    set other_strap [lindex [odb::getRectangles [odb::andSet [odb::newSetFromRect $xMin $yMin $xMax $yMax] $stripe_locs($layer_name,$other_tag)]] 0]
+
+    if {[get_dir $layer_name] == "hor"} {
+      set center [expr ($xMax + $xMin) / 2]
+      set mid_channel [expr ($yMax + $yMin) / 2]
+      if {$xMax - $xMin < $min_size} {
+        set xMin [expr $center - $min_size / 2]
+        set xMax [expr $center + $min_size / 2]
+      }
+      set channel_spacing [get_grid_channel_spacing $layer_name [expr $xMax - $xMin]]
+
+      set other_strap_mid [expr ([$other_strap yMin] + [$other_strap yMax]) / 2]
+      if {($mid_channel <= $other_strap_mid) && ([$other_strap yMin] - $channel_spacing - $width > $yMin)} {
+        # debug "Stripe below $other_strap"
+        set stripe [odb::newSetFromRect $xMin [expr [$other_strap yMin] - $channel_spacing - $width] $xMax [expr [$other_strap yMin] - $channel_spacing]]
+      } elseif {($mid_channel > $other_strap_mid) && ([$other_strap yMax] + $channel_spacing + $width < $yMax)} {
+        # debug "Stripe above $other_strap"
+        set stripe [odb::newSetFromRect $xMin [expr [$other_strap yMax] + $channel_spacing] $xMax [expr [$other_strap yMax] + $channel_spacing + $width]]
+      } else {
+	set stripe {}
+        utl::warn PDN 169 "Cannot fit additional $tag horizontal strap in channel ([ord::dbu_to_microns $xMin] [ord::dbu_to_microns $yMin]) - ([ord::dbu_to_microns $xMax], [ord::dbu_to_microns $yMax])"
+      }
+    } else {
+      set center [expr ($yMax + $yMin) / 2]
+      set mid_channel [expr ($xMax + $xMin) / 2]
+      if {$yMax - $yMin < $min_size} {
+        set yMin [expr $center - $min_size / 2]
+        set yMax [expr $center + $min_size / 2]
+      }
+      set channel_spacing [get_grid_channel_spacing $layer_name [expr $yMax - $yMin]]
+
+      set other_strap_mid [expr ([$other_strap xMin] + [$other_strap xMax]) / 2]
+      if {($mid_channel <= $other_strap_mid) && ([$other_strap xMin] - $channel_spacing - $width > $xMin)} {
+        # debug "Stripe left of $other_strap on layer $layer_name, spacing: $channel_spacing, width $width, strap_edge: [$other_strap xMin]"
+        set stripe [odb::newSetFromRect [expr [$other_strap xMin] - $channel_spacing - $width] $yMin [expr [$other_strap xMin] - $channel_spacing] $yMax]
+      } elseif {($mid_channel > $other_strap_mid) && ([$other_strap xMax] + $channel_spacing + $width < $xMax)} {
+        # debug "Stripe right of $other_strap"
+        set stripe [odb::newSetFromRect [expr [$other_strap xMax] + $channel_spacing] $yMin [expr [$other_strap xMax] + $channel_spacing + $width] $yMax]
+      } else {
+	set stripe {}
+        utl::warn PDN 170 "Cannot fit additional $tag vertical strap in channel ([ord::dbu_to_microns $xMin] [ord::dbu_to_microns $yMin]) - ([ord::dbu_to_microns $xMax], [ord::dbu_to_microns $yMax])"
+      }
+    }
+  } else {
+    if {[get_dir $layer_name] == "hor"} {
+      set channel_spacing [get_grid_channel_spacing $layer_name [expr $xMax - $xMin]]
+      set routing_grid [round_to_routing_grid $layer_name [expr ($yMax + $yMin - $channel_spacing) / 2]]
+      if {([expr $routing_grid - $width / 2] < $yMin) || ([expr $routing_grid + $width / 2] > $yMax)} {
+        utl::warn "PDN" 171 "Channel ([ord::dbu_to_microns $xMin] [ord::dbu_to_microns $yMin] [ord::dbu_to_microns $xMax] [ord::dbu_to_microns $yMax]) too narrow. Channel on layer $layer_name must be at least [ord::dbu_to_microns [expr round(2.0 * $width + $channel_spacing)]] wide."
+      }
+
+      set stripe [odb::newSetFromRect $xMin [expr $routing_grid - $width / 2] $xMax [expr $routing_grid + $width / 2]]
+    } else {
+      set channel_spacing [get_grid_channel_spacing $layer_name [expr $yMax - $yMin]]
+      set routing_grid [round_to_routing_grid $layer_name [expr ($xMax + $xMin - $channel_spacing) / 2]]
+
+      if {([expr $routing_grid - $width / 2] < $xMin) || ([expr $routing_grid + $width / 2] > $xMax)} {
+        utl::warn "PDN" 172 "Channel ([ord::dbu_to_microns $xMin] [ord::dbu_to_microns $yMin] [ord::dbu_to_microns $xMax] [ord::dbu_to_microns $yMax]) too narrow. Channel on layer $layer_name must be at least [ord::dbu_to_microns [expr round(2.0 * $width + $channel_spacing)]] wide."
+      }
+
+      set stripe [odb::newSetFromRect [expr $routing_grid - $width / 2] $yMin [expr $routing_grid + $width / 2] $yMax]
+    }
+  }
+
+  if {$stripe != {}} {
+    add_stripe $layer_name $tag $stripe
+  }
+}
+
+proc channel_has_pg_strap {channel layer_name tag}  {
+  variable stripe_locs
+  # debug "start, channel: $channel, layer: $layer_name"
+  # debug "       ([ord::dbu_to_microns [$channel xMin]] [ord::dbu_to_microns [$channel yMin]]) - ([ord::dbu_to_microns [$channel xMax]] [ord::dbu_to_microns [$channel yMax]])"
+
+  set power_strap 0
+  set ground_strap 0
+
+  set channel_set [odb::newSetFromRect [$channel xMin] [$channel yMin] [$channel xMax] [$channel yMax]]
+  set check_set [odb::andSet $stripe_locs($layer_name,$tag) $channel_set]
+
+  foreach rect [odb::getRectangles $check_set] {
+    if {[get_dir $layer_name] == "ver" && [$rect dx] < [get_grid_wire_width $layer_name]} {continue}
+    if {[get_dir $layer_name] == "hor" && [$rect dy] < [get_grid_wire_width $layer_name]} {continue}
+    # debug "Overlap found"
+    # debug "       Direction: [get_dir $layer_name]"
+    # debug "       Layer width: [get_grid_wire_width $layer_name]"
+    # debug "       ([ord::dbu_to_microns [$rect xMin]] [ord::dbu_to_microns [$rect yMin]]) - ([ord::dbu_to_microns [$rect xMax]] [ord::dbu_to_microns [$rect yMax]])"
+    return 1
+  }
+
+  # debug "end: channel needs repair"
+  return 0
+}
+
+proc process_channels {} {
+  set layers [get_grid_channel_layers]
+  set lower_layers [lrange $layers 0 end-1]
+  set upper_layers [lrange $layers 1 end]
+  foreach lower_layer_name $lower_layers upper_layer_name $upper_layers {
+    foreach tag {POWER GROUND} {
+      set channels [identify_channels $lower_layer_name $upper_layer_name $tag]
+      if {$channels == {}} {continue}
+      # debug "Tag: $tag, Channels found: [llength [odb::getPolygons $channels]]"
+      foreach channel [::odb::getRectangles $channels] {
+        if {![channel_has_pg_strap $channel $upper_layer_name $tag]} {
+          set next_upper_layer_idx [expr [lsearch -exact $layers $upper_layer_name] + 1]
+          if {$next_upper_layer_idx < [llength $layers]} {
+            set next_upper_layer [lindex $layers $next_upper_layer_idx]
+            set min_size [expr [get_grid_wire_pitch $next_upper_layer] + [get_grid_wire_width $next_upper_layer]]
+          } else {
+            set min_size 0
+          }
+          # debug "Repair channel: ([ord::dbu_to_microns [$channel xMin]] [ord::dbu_to_microns [$channel yMin]])-([ord::dbu_to_microns [$channel xMax]] [ord::dbu_to_microns [$channel yMax]]]), tag: $tag, layer: $upper_layer_name, min_size: $min_size"
+          repair_channel $channel $upper_layer_name $tag $min_size
+        }
+      }
+      merge_stripes
+    }
+  }
+}
+
+proc get_stdcell_plus_area {} {
+  variable stdcell_area
+  variable stdcell_plus_area
+
+  if {$stdcell_area == ""} {
+    get_stdcell_area
+  }
+  # debug "stdcell_area      [get_extent $stdcell_area]"
+  # debug "stdcell_plus_area [get_extent $stdcell_plus_area]"
+  return $stdcell_plus_area
+}
+
+proc get_stdcell_area {} {
+  variable stdcell_area
+  variable stdcell_plus_area
+
+  if {$stdcell_area != ""} {return $stdcell_area}
+  set rails_width [get_rails_max_width]
+
+  set rows [[ord::get_db_block] getRows]
+  set first_row [[lindex $rows 0] getBBox]
+
+  set minX [$first_row xMin]
+  set maxX [$first_row xMax]
+  set minY [$first_row yMin]
+  set maxY [$first_row yMax]
+  set stdcell_area [odb::newSetFromRect $minX $minY $maxX $maxY]
+  set stdcell_plus_area [odb::newSetFromRect $minX [expr $minY - $rails_width / 2] $maxX [expr $maxY + $rails_width / 2]]
+
+  foreach row [lrange $rows 1 end] {
+    set box [$row getBBox]
+    set minX [$box xMin]
+    set maxX [$box xMax]
+    set minY [$box yMin]
+    set maxY [$box yMax]
+    set stdcell_area [odb::orSet $stdcell_area [odb::newSetFromRect $minX $minY $maxX $maxY]]
+    set stdcell_plus_area [odb::orSet $stdcell_plus_area [odb::newSetFromRect $minX [expr $minY - $rails_width / 2] $maxX [expr $maxY + $rails_width / 2]]]
+  }
+
+  return $stdcell_area
+}
+
+proc find_core_area {} {
+  variable block
+
+  set area [get_stdcell_area]
+
+  return [get_extent $area]
+}
+
+proc get_rails_max_width {} {
+  variable design_data
+  variable default_grid_data
+
+  set max_width 0
+  foreach layer [get_rails_layers] {
+     if {[dict exists $default_grid_data rails $layer]} {
+       if {[set width [dict get $default_grid_data rails $layer width]] > $max_width} {
+         set max_width $width
+       }
+     }
+  }
+  if {![dict exists $default_grid_data units]} {
+    set max_width [ord::microns_to_dbu $max_width]
+  }
+  return $max_width
+}
+
+
+# This is a proc to get the first voltage domain that overlaps with the input box
+proc get_voltage_domain {llx lly urx ury} {
+  variable block
+  variable design_data
+  variable voltage_domains
+
+
+  set name [dict get $design_data core_domain]
+  foreach domain_name [dict keys $voltage_domains] {
+    if {$domain_name == [dict get $design_data core_domain]} {continue}
+    set domain [$block findRegion $domain_name]
+    set rect [lindex [$domain getBoundaries] 0]
+
+    set domain_xMin [$rect xMin]
+    set domain_yMin [$rect yMin]
+    set domain_xMax [$rect xMax]
+    set domain_yMax [$rect yMax]
+
+    if {!($domain_yMin >= $ury || $domain_xMin >= $urx || $domain_xMax <= $llx || $domain_yMax <= $lly)} {
+      set name [$domain getName]
+      break
+    }
+  }
+  return $name
+}
+
+proc get_voltage_domain_power {domain} {
+  variable voltage_domains
+
+  return [dict get $voltage_domains $domain primary_power]
+}
+
+proc get_voltage_domain_secondary_power {domain} {
+  variable voltage_domains
+  
+  if {[dict exists $voltage_domains $domain secondary_power]} {
+    return [dict get $voltage_domains $domain secondary_power]
+  } else {
+    return []
+  }
+}
+
+proc get_voltage_domain_ground {domain} {
+  variable voltage_domains
+
+  return [dict get $voltage_domains $domain primary_ground]
+}
+
+# This proc is to split core domain's power stripes if they cross interal voltage domains that have different pwr/gnd nets
+proc update_mesh_stripes_with_volatge_domains {tag lay snet_name} {
+  variable block
+  variable stripes
+  variable grid_data
+  variable design_data
+  variable voltage_domains
+
+  set rails_width [get_rails_max_width]
+
+  set stdcell_area [get_extent [get_stdcell_area]]
+  set stdcell_min_x [lindex $stdcell_area 0]
+  set stdcell_min_y [lindex $stdcell_area 1]
+  set stdcell_max_x [lindex $stdcell_area 2]
+  set stdcell_max_y [lindex $stdcell_area 3]
+
+  set ring_adjustment 0
+  if {[set ring_vertical_layer [get_core_ring_vertical_layer_name]] != ""} {
+    if {[dict exists $grid_data core_ring $ring_vertical_layer pad_offset]} {
+      set pad_area [find_pad_offset_area]
+      set offset [expr [dict get $grid_data core_ring $ring_vertical_layer pad_offset]]
+      set ring_adjustment [expr $stdcell_min_x - ([lindex $pad_area 0] + $offset)]
+    }
+    if {[dict exists $grid_data core_ring $ring_vertical_layer core_offset]} {
+      set ring_adjustment [expr \
+        [dict get $grid_data core_ring $ring_vertical_layer core_offset] + \
+        [dict get $grid_data core_ring $ring_vertical_layer spacing] + \
+        3 * [dict get $grid_data core_ring $ring_vertical_layer width] / 2 \
+      ]
+    }
+  }
+
+  set first_row [lindex [$block getRows] 0]
+  set row_site [$first_row getSite]
+  set site_width [$row_site getWidth]
+  set row_height [$row_site getHeight]
+
+  # This voltage domain to core domain margin is hard coded for now
+  set MARGIN 6
+  set X_MARGIN [expr ($MARGIN * $row_height / $site_width) * $site_width]
+  set Y_MARGIN [expr $MARGIN * $row_height]
+
+  foreach domain_name [dict keys $voltage_domains] {
+    if {$domain_name == [dict get $design_data core_domain]} {continue}
+    set domain [$block findRegion $domain_name]
+    set first_rect [lindex [$domain getBoundaries] 0]
+
+    # voltage domain area
+    set domain_xMin [expr [$first_rect xMin]]
+    set domain_yMin [expr [$first_rect yMin]]
+    set domain_xMax [expr [$first_rect xMax]]
+    set domain_yMax [expr [$first_rect yMax]]
+
+    # voltage domain area + margin
+    set domain_boundary_xMin [expr [$first_rect xMin] - $X_MARGIN]
+    set domain_boundary_yMin [expr [$first_rect yMin] - $Y_MARGIN + $rails_width / 2]
+    set domain_boundary_xMax [expr [$first_rect xMax] + $X_MARGIN]
+    set domain_boundary_yMax [expr [$first_rect yMax] + $Y_MARGIN - $rails_width / 2]
+
+    if {[get_dir $lay] == "hor"} {
+      if {$domain_boundary_xMin < $stdcell_min_x + $site_width} {
+        set domain_boundary_xMin [expr $stdcell_min_x - $ring_adjustment]
+      }
+      if {$domain_boundary_xMax > $stdcell_max_x - $site_width} {
+        set domain_boundary_xMax [expr $stdcell_max_x + $ring_adjustment]
+      }
+    } else {
+      if {$domain_boundary_yMin < $stdcell_min_y + $row_height} {
+        set domain_boundary_yMin [expr $stdcell_min_y - $ring_adjustment]
+      }
+      if {$domain_boundary_yMax > $stdcell_max_y - $row_height} {
+        set domain_boundary_yMax [expr $stdcell_max_y + $ring_adjustment]
+      }
+    }
+
+    # Core domain's pwr/gnd nets that are not shared should not cross the entire voltage domain area
+    set boundary_box \
+        [odb::newSetFromRect \
+          $domain_boundary_xMin \
+          $domain_boundary_yMin \
+          $domain_boundary_xMax \
+          $domain_boundary_yMax \
+        ]
+
+    if {[get_dir $lay] == "hor"} {
+      set domain_box \
+        [odb::newSetFromRect \
+          $domain_boundary_xMin \
+          $domain_yMin \
+          $domain_boundary_xMax \
+          $domain_yMax \
+        ]
+    } else {
+      set domain_box \
+        [odb::newSetFromRect \
+          $domain_xMin \
+          $domain_boundary_yMin \
+          $domain_xMax \
+          $domain_boundary_yMax \
+        ]
+    }
+    # Core domain's pwr/gnd nets shared with a voltage domain should not cross the domains' pwr/gnd rings
+    set boundary_box_for_crossing_core_net [odb::subtractSet $boundary_box $domain_box]
+
+    for {set i 0} {$i < [llength $stripes($lay,$tag)]} {incr i} {
+      set updated_polygonSet [lindex $stripes($lay,$tag) $i]
+      # Check if core domain's power is the same as voltage domain's power 
+      if {$snet_name == [get_voltage_domain_power $domain_name] ||
+          $snet_name == [get_voltage_domain_ground $domain_name]} {
+        set updated_polygonSet [odb::subtractSet $updated_polygonSet $boundary_box_for_crossing_core_net]
+      } else {
+        set updated_polygonSet [odb::subtractSet $updated_polygonSet $boundary_box]
+      }
+      # This if statemet prevents from deleting domain rings
+      if {[llength [odb::getPolygons $updated_polygonSet]] > 0} {
+        set stripes($lay,$tag) [lreplace $stripes($lay,$tag) $i $i $updated_polygonSet]
+      }
+    }
+  }
+}
+
+# This proc is to check if a pwr/gnd net is unique for all voltage domains, the setWildConnected can be used
+proc check_snet_is_unique {net} {
+  variable voltage_domains
+
+  set is_unique_power 1
+  foreach vd_key [dict keys $voltage_domains] {
+    if {[dict get $voltage_domains $vd_key primary_power] != [$net getName]} {
+      set is_unique_power 0
+      break
+    }
+  }
+
+  set is_unique_ground 1
+  foreach vd_key [dict keys $voltage_domains] {
+    if {[dict get $voltage_domains $vd_key primary_ground] != [$net getName]} {
+      set is_unique_ground 0
+      break
+    }
+  }
+
+  return [expr $is_unique_power || $is_unique_ground]
+
+}
+
+# This proc generates power rings for voltage domains, tags for the core domain are POWER/GROUND, tags for the other
+# voltage domains are defined as POWER_<pwr-net> and GROUND_<gnd-net>
+proc generate_voltage_domain_rings {core_ring_data} {
+  variable block
+  variable voltage_domains
+  variable grid_data
+  variable design_data
+
+  foreach domain_name [dict keys $voltage_domains] {
+    if {$domain_name == [dict get $design_data core_domain]} {continue}
+    set domain [$block findRegion $domain_name]
+    set rect [lindex [$domain getBoundaries] 0]
+    set power_net [get_voltage_domain_power $domain_name]
+    set secondary_power_net [get_voltage_domain_secondary_power $domain_name]
+    set ground_net [get_voltage_domain_ground $domain_name]
+    
+    set domain_xMin [$rect xMin]
+    set domain_yMin [$rect yMin]
+    set domain_xMax [$rect xMax]
+    set domain_yMax [$rect yMax]
+    dict for {layer layer_info} $core_ring_data {
+      if {[dict exists $layer_info core_offset]} {
+        set offset [dict get $layer_info core_offset]
+
+        set spacing [dict get $layer_info spacing]
+        set width [dict get $layer_info width]
+
+        set inner_lx [expr $domain_xMin - $offset]
+        set inner_ly [expr $domain_yMin - $offset]
+        set inner_ux [expr $domain_xMax + $offset]
+        set inner_uy [expr $domain_yMax + $offset]
+
+        set outer_lx [expr $domain_xMin - $offset - $spacing - $width]
+        set outer_ly [expr $domain_yMin - $offset - $spacing - $width]
+        set outer_ux [expr $domain_xMax + $offset + $spacing + $width]
+        set outer_uy [expr $domain_yMax + $offset + $spacing + $width]
+      }
+      set number_of_rings 0
+      if {[get_dir $layer] == "hor"} {
+        set lower_inner_ring \
+          [odb::newSetFromRect \
+            [expr $inner_lx - $width / 2] \
+            [expr $inner_ly - $width / 2] \
+            [expr $inner_ux + $width / 2] \
+            [expr $inner_ly + $width / 2] \
+          ]
+        set upper_inner_ring \
+          [odb::newSetFromRect \
+            [expr $inner_lx - $width / 2] \
+            [expr $inner_uy - $width / 2] \
+            [expr $inner_ux + $width / 2] \
+            [expr $inner_uy + $width / 2] \
+          ]
+        set lower_outer_ring \
+          [odb::newSetFromRect \
+            [expr $outer_lx - $width / 2] \
+            [expr $outer_ly - $width / 2] \
+            [expr $outer_ux + $width / 2] \
+            [expr $outer_ly + $width / 2] \
+          ]
+        set upper_outer_ring \
+          [odb::newSetFromRect \
+            [expr $outer_lx - $width / 2] \
+            [expr $outer_uy - $width / 2] \
+            [expr $outer_ux + $width / 2] \
+            [expr $outer_uy + $width / 2] \
+          ]
+        
+        if {$power_net == [get_voltage_domain_power [dict get $design_data core_domain]]} {
+          add_stripe $layer "POWER" $lower_inner_ring
+          add_stripe $layer "POWER" $upper_inner_ring
+        } else {
+          add_stripe $layer "POWER_$power_net" $lower_inner_ring
+          add_stripe $layer "POWER_$power_net" $upper_inner_ring
+        }
+        if {$ground_net == [get_voltage_domain_ground [dict get $design_data core_domain]]} {
+          add_stripe $layer "GROUND" $lower_outer_ring
+          add_stripe $layer "GROUND" $upper_outer_ring
+        } else {
+          add_stripe $layer "GROUND_$ground_net" $lower_outer_ring
+          add_stripe $layer "GROUND_$ground_net" $upper_outer_ring
+        }
+        
+      	set number_of_rings [llength $secondary_power_net]
+        foreach secondary_power $secondary_power_net {
+          set outer_lx [expr $outer_lx - $spacing - $width]
+          set outer_ly [expr $outer_ly - $spacing - $width]
+          set outer_ux [expr $outer_ux + $spacing + $width] 
+    	    set outer_uy [expr $outer_uy + $spacing + $width]
+
+          set upper_domain_power \
+            [odb::newSetFromRect \
+              [expr $outer_lx - $width / 2] \
+              [expr $outer_uy - $width / 2] \
+              [expr $outer_ux + $width / 2] \
+              [expr $outer_uy + $width / 2] \
+            ]
+
+          set lower_domain_power \
+            [odb::newSetFromRect \
+              [expr $outer_lx - $width / 2] \
+              [expr $outer_ly - $width / 2] \
+              [expr $outer_ux + $width / 2] \
+              [expr $outer_ly + $width / 2] \
+            ]
+
+          add_stripe $layer "POWER_$secondary_power" $upper_domain_power
+          add_stripe $layer "POWER_$secondary_power" $lower_domain_power
+        }
+      } else {
+        set lhs_inner_ring \
+          [odb::newSetFromRect \
+            [expr $inner_lx - $width / 2] \
+            [expr $inner_ly - $width / 2] \
+            [expr $inner_lx + $width / 2] \
+            [expr $inner_uy + $width / 2] \
+          ]
+        set rhs_inner_ring \
+          [odb::newSetFromRect \
+            [expr $inner_ux - $width / 2] \
+            [expr $inner_ly - $width / 2] \
+            [expr $inner_ux + $width / 2] \
+            [expr $inner_uy + $width / 2] \
+          ]
+        set lhs_outer_ring \
+          [odb::newSetFromRect \
+            [expr $outer_lx - $width / 2] \
+            [expr $outer_ly - $width / 2] \
+            [expr $outer_lx + $width / 2] \
+            [expr $outer_uy + $width / 2] \
+          ]
+        set rhs_outer_ring \
+          [odb::newSetFromRect \
+            [expr $outer_ux - $width / 2] \
+            [expr $outer_ly - $width / 2] \
+            [expr $outer_ux + $width / 2] \
+            [expr $outer_uy + $width / 2] \
+          ]
+
+        if {$power_net == [get_voltage_domain_power [dict get $design_data core_domain]]} {
+          add_stripe $layer "POWER" $lhs_inner_ring
+          add_stripe $layer "POWER" $rhs_inner_ring
+        } else {
+          add_stripe $layer "POWER_$power_net" $lhs_inner_ring
+          add_stripe $layer "POWER_$power_net" $rhs_inner_ring
+        }
+        if {$ground_net == [get_voltage_domain_ground [dict get $design_data core_domain]]} {
+          add_stripe $layer "GROUND" $lhs_outer_ring
+          add_stripe $layer "GROUND" $rhs_outer_ring
+        } else {
+          add_stripe $layer "GROUND_$ground_net" $lhs_outer_ring
+          add_stripe $layer "GROUND_$ground_net" $rhs_outer_ring
+        }
+
+        foreach secondary_power $secondary_power_net {
+          set outer_lx [expr $outer_lx - $spacing - $width]
+          set outer_ly [expr $outer_ly - $spacing - $width]
+          set outer_ux [expr $outer_ux + $spacing + $width]
+          set outer_uy [expr $outer_uy + $spacing + $width]
+  
+          set lhs_domain_power \
+            [odb::newSetFromRect \
+              [expr $outer_lx - $width / 2] \
+              [expr $outer_ly - $width / 2] \
+              [expr $outer_lx + $width / 2] \
+              [expr $outer_uy + $width / 2] \
+            ]
+
+          set rhs_domain_power \
+            [odb::newSetFromRect \
+              [expr $outer_ux - $width / 2] \
+              [expr $outer_ly - $width / 2] \
+              [expr $outer_ux + $width / 2] \
+              [expr $outer_uy + $width / 2] \
+            ]
+
+          add_stripe $layer "POWER_$secondary_power" $lhs_domain_power
+          add_stripe $layer "POWER_$secondary_power" $rhs_domain_power
+        }
+      }
+    }
+  }
+}
+
+
+# This proc detects pins used in pdn.cfg for global connections
+proc get_valid_mterms {net_name} {
+  variable global_connections
+  variable default_global_connections
+ 
+  if {$global_connections == {}} {
+    set global_connections $default_global_connections
+  }
+
+  set mterms_list {}
+  if {![dict exists $global_connections $net_name]} {
+    utl::error PDN  174 "Net $net_name has no global connections defined."
+  }
+
+  foreach pattern [dict get $global_connections $net_name] {
+    lappend mterms_list [dict get $pattern pin_name]
+  }
+  return $mterms_list
+}
+
+proc core_area_boundary {} {
+  variable design_data
+  variable template
+  variable metal_layers
+  variable grid_data
+
+  set core_area [find_core_area]
+  # We need to allow the rails to extend by half a rails width in the y direction, since the rails overlap the core_area
+
+  set llx [lindex $core_area 0]
+  set lly [lindex $core_area 1]
+  set urx [lindex $core_area 2]
+  set ury [lindex $core_area 3]
+
+  if {[dict exists $template width]} {
+    set width [dict get $template width]
+  } else {
+    set width 2000
+  }
+  if {[dict exists $template height]} {
+    set height [dict get $template height]
+  } else {
+    set height 2000
+  }
+
+  # Add blockages around the outside of the core area in order to trim back the templates.
+  #
+  set boundary [odb::newSetFromRect [expr $llx - $width] [expr $lly - $height] $llx [expr $ury + $height]]
+  set boundary [odb::orSet $boundary [odb::newSetFromRect [expr $llx - $width] [expr $lly - $height] [expr $urx + $width] $lly]]
+  set boundary [odb::orSet $boundary [odb::newSetFromRect [expr $llx - $width] $ury [expr $urx + $width] [expr $ury + $height]]]
+  set boundary [odb::orSet $boundary [odb::newSetFromRect $urx [expr $lly - $height] [expr $urx + $width] [expr $ury + $height]]]
+  set boundary [odb::subtractSet $boundary [get_stdcell_plus_area]]
+
+  foreach layer $metal_layers {
+    if {[dict exists $grid_data core_ring] && [dict exists $grid_data core_ring $layer]} {continue}
+    dict set blockages $layer $boundary
+  }
+
+  return $blockages
+}
+
+proc get_instance_blockages {insts} {
+  variable instances
+  set blockages {}
+
+  foreach inst $insts {
+    foreach layer [get_macro_blockage_layers $inst] {
+      # debug "Inst $inst"
+      # debug "Macro boundary: [dict get $instances $inst macro_boundary]"
+      # debug "Halo boundary:  [dict get $instances $inst halo_boundary]"
+      set box [odb::newSetFromRect [get_instance_llx $inst] [get_instance_lly $inst] [get_instance_urx $inst] [get_instance_ury $inst]]
+      if {[dict exists $blockages $layer]} {
+        dict set blockages $layer [odb::orSet [dict get $blockages $layer] $box]
+      } else {
+        dict set blockages $layer $box
+      }
+    }
+  }
+
+  return $blockages
+}
+
+proc define_template_grid {} {
+  variable design_data
+  variable template
+  variable plan_template
+  variable block
+  variable default_grid_data
+  variable default_template_name
+
+  set core_area [dict get $design_data config core_area]
+  set llx [lindex $core_area 0]
+  set lly [lindex $core_area 1]
+  set urx [lindex $core_area 2]
+  set ury [lindex $core_area 3]
+
+  set core_width  [expr $urx - $llx]
+  set core_height [expr $ury - $lly]
+
+  set template_width  [dict get $template width]
+  set template_height [dict get $template height]
+  set x_sections [expr round($core_width  / $template_width)]
+  set y_sections [expr round($core_height / $template_height)]
+
+  dict set template offset x [expr [lindex $core_area 0] + ($core_width - $x_sections * $template_width) / 2]
+  dict set template offset y [expr [lindex $core_area 1] + ($core_height - $y_sections * $template_height) / 2]
+
+  if {$default_template_name == {}} {
+    set template_name [lindex [dict get $default_grid_data template names] 0]
+  } else {
+    set template_name $default_template_name
+  }
+
+  for {set i -1} {$i <= $x_sections} {incr i} {
+    for {set j -1} {$j <= $y_sections} {incr j} {
+      set llx [expr $i * $template_width + [dict get $template offset x]]
+      set lly [expr $j * $template_height + [dict get $template offset y]]
+
+      dict set plan_template $llx $lly $template_name
+    }
+  }
+  write_template_placement
+}
+
+proc set_blockages {these_blockages} {
+  variable blockages
+
+  set blockages $these_blockages
+}
+
+proc get_blockages {} {
+  variable blockages
+
+  return $blockages
+}
+
+proc add_blockage {layer blockage} {
+  variable blockages
+
+  if {[dict exists $blockages $layer]} {
+    dict set blockages $layer [odb::orSet [dict get $blockages $layer] $blockage]
+  } else {
+    dict set blockages $layer $blockage
+  }
+}
+
+proc add_padcell_blockage {layer blockage} {
+  variable padcell_blockages
+
+  if {[dict exists $padcell_blockages $layer]} {
+    dict set padcell_blockages $layer [odb::orSet [dict get $padcell_blockages $layer] $blockage]
+  } else {
+    dict set padcell_blockages $layer $blockage
+  }
+}
+
+proc apply_padcell_blockages {} {
+  variable padcell_blockages
+  variable global_connections
+
+  dict for {layer_name blockages} $padcell_blockages {
+    add_blockage $layer_name $blockages
+  }
+}
+
+proc add_blockages {more_blockages} {
+  variable blockages
+
+  dict for {layer blockage} $more_blockages {
+    add_blockage $layer $blockage
+  }
+}
+
+proc add_macro_based_grids {} {
+  variable grid_data
+  variable design_data
+  variable verbose
+
+  if {![dict exists $design_data grid macro]} {return}
+
+  foreach {key grid_data} [dict get $design_data grid macro] {
+    if {![dict exists $grid_data _related_instances]} {continue}
+    set instances [dict get $grid_data _related_instances]
+
+    set_blockages {}
+    if {[llength [dict keys $instances]] > 0} {
+      utl::info "PDN" 10 "Inserting macro grid for [llength [dict keys $instances]] macros."
+      foreach instance [dict keys $instances] {
+        if {$verbose == 1} {
+          utl::info "PDN" 34 "  - grid [dict get $grid_data name] for instance $instance"
+        }
+
+        if {[dict exists $grid_data grid_over_pg_pins]} {
+          # debug "Grid over pins: [get_instance_pg_pins_area $instance]"
+          dict set grid_data area [get_instance_pg_pins_area $instance]
+        } else {
+          # debug "Grid boundary: [get_instance_pg_pins_area $instance]"
+          dict set grid_data area [dict get $instances $instance macro_boundary]
+        }
+        add_grid
+
+        # debug "Generate vias for [dict get $design_data power_nets] [dict get $design_data ground_nets]"
+        foreach pwr_net [dict get $design_data power_nets] {
+          generate_grid_vias "POWER" $pwr_net
+        }
+        foreach gnd_net [dict get $design_data ground_nets] {
+          generate_grid_vias "GROUND" $gnd_net
+        }
+      }
+    }
+  }
+}
+
+proc plan_grid {} {
+  variable design_data
+  variable instances
+  variable default_grid_data
+  variable def_units
+  variable grid_data
+
+  ################################## Main Code #################################
+
+  if {![dict exists $design_data grid macro]} {
+    utl::warn "PDN" 18 "No macro grid specifications found - no straps added."
+  }
+
+  utl::info "PDN" 11 "****** INFO ******"
+
+  print_strategy stdcell [get_stdcell_specification]
+
+  if {[dict exists $design_data grid macro]} {
+    dict for {name specification} [dict get $design_data grid macro] {
+      print_strategy macro $specification
+    }
+  }
+
+  utl::info "PDN" 12 "**** END INFO ****"
+
+  set specification $default_grid_data
+  if {[dict exists $specification name]} {
+    utl::info "PDN" 13 "Inserting stdcell grid - [dict get $specification name]."
+  } else {
+    utl::info "PDN" 14 "Inserting stdcell grid."
+  }
+
+  if {![dict exists $specification area]} {
+    dict set specification area [dict get $design_data config core_area]
+  }
+
+  set grid_data $specification
+
+  set boundary [odb::newSetFromRect {*}[dict get $grid_data area]]
+  set insts_in_core_area [filtered_insts_within $instances $boundary]
+
+  set_blockages [get_instance_blockages [dict keys $insts_in_core_area]]
+  add_blockages [core_area_boundary]
+  if {[dict exists $specification template]} {
+    read_template_placement
+  }
+
+  add_grid
+  #Dinesh-A: Core Ring without Strap
+  if {[info exists $grid_data]} {
+  	process_channels
+  }
+
+  foreach pwr_net [dict get $design_data power_nets] {
+    generate_grid_vias "POWER" $pwr_net
+  }
+
+  foreach gnd_net [dict get $design_data ground_nets] {
+    generate_grid_vias "GROUND" $gnd_net
+  }
+
+  add_macro_based_grids
+ 
+}
+
+proc opendb_update_grid {} {
+  utl::info "PDN" 15 "Writing to database."
+  export_opendb_vias
+  export_opendb_specialnets
+  export_opendb_power_pins
+}
+  
+proc set_verbose {} {
+  variable verbose
+
+  set verbose 1
+}
+
+proc apply {args} {
+  variable verbose
+  variable default_grid_data
+
+  if {[llength $args] > 0 && $verbose} {
+    set config [lindex $args 0]
+    utl::info "PDN" 16 "Power Delivery Network Generator: Generating PDN\n  config: $config"
+  }
+
+  if {[llength $args] == 1} {
+    set PDN_cfg [lindex $args 0]
+    if {![file exists $PDN_cfg]} {
+      utl::error "PDN" 62 "File $PDN_cfg does not exist."
+    }
+ 
+    if {![file_exists_non_empty $PDN_cfg]} {
+      utl::error "PDN" 28 "File $PDN_cfg is empty."
+    }
+    source $PDN_cfg
+  }
+
+  init {*}$args
+  complete_macro_grid_specifications
+  set default_grid_data [get_stdcell_specification]
+
+  plan_grid
+
+  write_pdn_strategy
+
+  opendb_update_grid
+}
+}
diff --git a/hacks/src/OpenROAD/Resizer.cc b/hacks/src/OpenROAD/Resizer.cc
new file mode 100644
index 0000000..300c6c4
--- /dev/null
+++ b/hacks/src/OpenROAD/Resizer.cc
@@ -0,0 +1,4134 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2019, The Regents of the University of California
+// All rights reserved.
+//
+// BSD 3-Clause License
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice, this
+//   list of conditions and the following disclaimer.
+//
+// * 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.
+//
+// * Neither the name of the copyright holder nor the names of its
+//   contributors may be used to endorse or promote products derived from
+//   this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "rsz/Resizer.hh"
+
+#include "rsz/SteinerTree.hh"
+
+#include "gui/gui.h"
+#include "utl/Logger.h"
+
+#include "sta/Report.hh"
+#include "sta/FuncExpr.hh"
+#include "sta/PortDirection.hh"
+#include "sta/TimingRole.hh"
+#include "sta/Units.hh"
+#include "sta/Liberty.hh"
+#include "sta/TimingArc.hh"
+#include "sta/TimingModel.hh"
+#include "sta/Network.hh"
+#include "sta/Graph.hh"
+#include "sta/DcalcAnalysisPt.hh"
+#include "sta/ArcDelayCalc.hh"
+#include "sta/GraphDelayCalc.hh"
+#include "sta/Parasitics.hh"
+#include "sta/Sdc.hh"
+#include "sta/InputDrive.hh"
+#include "sta/Corner.hh"
+#include "sta/PathVertex.hh"
+#include "sta/SearchPred.hh"
+#include "sta/Bfs.hh"
+#include "sta/Search.hh"
+#include "sta/PathRef.hh"
+#include "sta/PathExpanded.hh"
+#include "sta/StaMain.hh"
+#include "sta/Fuzzy.hh"
+
+// http://vlsicad.eecs.umich.edu/BK/Slots/cache/dropzone.tamu.edu/~zhuoli/GSRC/fast_buffer_insertion.html
+
+namespace sta {
+extern const char *rsz_tcl_inits[];
+}
+
+namespace rsz {
+
+using std::abs;
+using std::min;
+using std::max;
+using std::string;
+using std::to_string;
+using std::vector;
+using std::map;
+using std::pair;
+using std::sqrt;
+
+using utl::RSZ;
+
+using odb::dbInst;
+using odb::dbPlacementStatus;
+using odb::Rect;
+using odb::dbOrientType;
+using odb::dbMPin;
+using odb::dbBox;
+using odb::dbMasterType;
+
+using sta::evalTclInit;
+using sta::makeBlockSta;
+using sta::Level;
+using sta::stringLess;
+using sta::Network;
+using sta::NetworkEdit;
+using sta::NetPinIterator;
+using sta::NetConnectedPinIterator;
+using sta::InstancePinIterator;
+using sta::LeafInstanceIterator;
+using sta::LibertyLibraryIterator;
+using sta::LibertyCellIterator;
+using sta::LibertyCellTimingArcSetIterator;
+using sta::TimingArcSet;
+using sta::TimingArcSetArcIterator;
+using sta::TimingArcSetSeq;
+using sta::GateTimingModel;
+using sta::TimingRole;
+using sta::FuncExpr;
+using sta::Term;
+using sta::Port;
+using sta::PinSeq;
+using sta::NetIterator;
+using sta::PinConnectedPinIterator;
+using sta::FindNetDrvrLoads;;
+using sta::VertexIterator;
+using sta::VertexOutEdgeIterator;
+using sta::Edge;
+using sta::Search;
+using sta::SearchPredNonReg2;
+using sta::ClkArrivalSearchPred;
+using sta::BfsBkwdIterator;
+using sta::BfsFwdIterator;
+using sta::BfsIndex;
+using sta::Clock;
+using sta::PathExpanded;
+using sta::INF;
+using sta::fuzzyEqual;
+using sta::fuzzyLess;
+using sta::fuzzyLessEqual;
+using sta::fuzzyGreater;
+using sta::fuzzyGreaterEqual;
+using sta::delayInf;
+using sta::stringPrint;
+using sta::Unit;
+using sta::ArcDelayCalc;
+using sta::Corners;
+using sta::InputDrive;
+
+extern "C" {
+extern int Rsz_Init(Tcl_Interp *interp);
+}
+
+Resizer::Resizer() :
+  StaState(),
+  wire_signal_res_(0.0),
+  wire_signal_cap_(0.0),
+  wire_clk_res_(0.0),
+  wire_clk_cap_(0.0),
+  max_area_(0.0),
+  openroad_(nullptr),
+  logger_(nullptr),
+  gui_(nullptr),
+  sta_(nullptr),
+  db_network_(nullptr),
+  db_(nullptr),
+  block_(nullptr),
+  core_exists_(false),
+  parasitics_src_(ParasiticsSrc::none),
+  design_area_(0.0),
+  max_(MinMax::max()),
+  buffer_lowest_drive_(nullptr),
+  buffer_med_drive_(nullptr),
+  buffer_highest_drive_(nullptr),
+  target_load_map_(nullptr),
+  level_drvr_vertices_valid_(false),
+  tgt_slews_{0.0, 0.0},
+  tgt_slew_corner_(nullptr),
+  tgt_slew_dcalc_ap_(nullptr),
+  unique_net_index_(1),
+  unique_inst_index_(1),
+  resize_count_(0),
+  inserted_buffer_count_(0),
+  max_wire_length_(0),
+  steiner_renderer_(nullptr),
+  rebuffer_net_count_(0)
+{
+}
+
+void
+Resizer::init(OpenRoad *openroad,
+              Tcl_Interp *interp,
+              Logger *logger,
+              Gui *gui,
+              dbDatabase *db,
+              dbSta *sta,
+              SteinerTreeBuilder *stt_builder,
+              GlobalRouter *global_router)
+{
+  openroad_ = openroad;
+  logger_ = logger;
+  gui_ = gui;
+  db_ = db;
+  block_ = nullptr;
+  sta_ = sta;
+  stt_builder_ = stt_builder;
+  global_router_ = global_router;
+  incr_groute_ = nullptr;
+  db_network_ = sta->getDbNetwork();
+  copyState(sta);
+  // Define swig TCL commands.
+  Rsz_Init(interp);
+  // Eval encoded sta TCL sources.
+  evalTclInit(interp, sta::rsz_tcl_inits);
+}
+
+////////////////////////////////////////////////////////////////
+
+double
+Resizer::coreArea() const
+{
+  return dbuToMeters(core_.dx()) * dbuToMeters(core_.dy());
+}
+
+double
+Resizer::utilization()
+{
+  ensureBlock();
+  ensureDesignArea();
+  double core_area = coreArea();
+  if (core_area > 0.0)
+    return design_area_ / core_area;
+  else
+    return 1.0;
+}
+
+double
+Resizer::maxArea() const
+{
+  return max_area_;
+}
+
+////////////////////////////////////////////////////////////////
+
+class VertexLevelLess
+{
+public:
+  VertexLevelLess(const Network *network);
+  bool operator()(const Vertex *vertex1,
+                  const Vertex *vertex2) const;
+
+protected:
+  const Network *network_;
+};
+
+VertexLevelLess::VertexLevelLess(const Network *network) :
+  network_(network)
+{
+}
+
+bool
+VertexLevelLess::operator()(const Vertex *vertex1,
+                            const Vertex *vertex2) const
+{
+  Level level1 = vertex1->level();
+  Level level2 = vertex2->level();
+  return (level1 < level2)
+    || (level1 == level2
+        // Break ties for stable results.
+        && stringLess(network_->pathName(vertex1->pin()),
+                      network_->pathName(vertex2->pin())));
+}
+
+
+////////////////////////////////////////////////////////////////
+
+// block_ indicates core_, design_area_, db_network_ etc valid.
+void
+Resizer::ensureBlock()
+{
+  // block_ indicates core_, design_area_
+  if (block_ == nullptr) {
+    block_ = db_->getChip()->getBlock();
+    block_->getCoreArea(core_);
+    core_exists_ = !(core_.xMin() == 0
+                     && core_.xMax() == 0
+                     && core_.yMin() == 0
+                     && core_.yMax() == 0);
+  }
+}
+
+void
+Resizer::init()
+{
+  // Abbreviated copyState
+  db_network_ = sta_->getDbNetwork();
+  sta_->ensureLevelized();
+  graph_ = sta_->graph();
+  ensureBlock();
+  ensureDesignArea();
+  ensureLevelDrvrVertices();
+  sta_->ensureClkNetwork();
+}
+
+void
+Resizer::removeBuffers()
+{
+  ensureBlock();
+  db_network_ = sta_->getDbNetwork();
+  // Disable incremental timing.
+  graph_delay_calc_->delaysInvalid();
+  search_->arrivalsInvalid();
+
+  int remove_count = 0;
+  for (dbInst *inst : block_->getInsts()) {
+    LibertyCell *lib_cell = db_network_->libertyCell(inst);
+    if (lib_cell && lib_cell->isBuffer()) {
+      Instance *buffer = db_network_->dbToSta(inst);
+      // Do not remove buffers connected to input/output ports
+      // because verilog netlists use the net name for the port.
+      if (!bufferBetweenPorts(buffer)) {
+        removeBuffer(buffer);
+        remove_count++;
+      }
+    }
+  }
+  level_drvr_vertices_valid_ = false;
+  logger_->info(RSZ, 26, "Removed {} buffers.", remove_count);
+}
+
+bool
+Resizer::bufferBetweenPorts(Instance *buffer)
+{
+  LibertyCell *lib_cell = network_->libertyCell(buffer);
+  LibertyPort *in_port, *out_port;
+  lib_cell->bufferPorts(in_port, out_port);
+  Pin *in_pin = db_network_->findPin(buffer, in_port);
+  Pin *out_pin = db_network_->findPin(buffer, out_port);
+  Net *in_net = db_network_->net(in_pin);
+  Net *out_net = db_network_->net(out_pin);
+  bool in_net_ports = hasPort(in_net);
+  bool out_net_ports = hasPort(out_net);
+  return in_net_ports && out_net_ports;
+}
+
+void
+Resizer::removeBuffer(Instance *buffer)
+{
+  LibertyCell *lib_cell = network_->libertyCell(buffer);
+  LibertyPort *in_port, *out_port;
+  lib_cell->bufferPorts(in_port, out_port);
+  Pin *in_pin = db_network_->findPin(buffer, in_port);
+  Pin *out_pin = db_network_->findPin(buffer, out_port);
+  Net *in_net = db_network_->net(in_pin);
+  Net *out_net = db_network_->net(out_pin);
+  bool out_net_ports = hasPort(out_net);
+  Net *survivor, *removed;
+  if (out_net_ports) {
+    survivor = out_net;
+    removed = in_net;
+  }
+  else {
+    // default or out_net_ports
+    // Default to in_net surviving so drivers (cached in dbNetwork)
+    // do not change.
+    survivor = in_net;
+    removed = out_net;
+  }
+
+  if (!sdc_->isConstrained(in_pin)
+      && !sdc_->isConstrained(out_pin)
+      && !sdc_->isConstrained(removed)
+      && !sdc_->isConstrained(buffer)) {
+    sta_->disconnectPin(in_pin);
+    sta_->disconnectPin(out_pin);
+    sta_->deleteInstance(buffer);
+
+    NetPinIterator *pin_iter = db_network_->pinIterator(removed);
+    while (pin_iter->hasNext()) {
+      Pin *pin = pin_iter->next();
+      Instance *pin_inst = db_network_->instance(pin);
+      if (pin_inst != buffer) {
+        Port *pin_port = db_network_->port(pin);
+        sta_->disconnectPin(pin);
+        sta_->connectPin(pin_inst, pin_port, survivor);
+      }
+    }
+    delete pin_iter;
+    sta_->deleteNet(removed);
+    parasitics_invalid_.erase(removed);
+  }
+}
+
+void
+Resizer::ensureLevelDrvrVertices()
+{
+  if (!level_drvr_vertices_valid_) {
+    level_drvr_vertices_.clear();
+    VertexIterator vertex_iter(graph_);
+    while (vertex_iter.hasNext()) {
+      Vertex *vertex = vertex_iter.next();
+      if (vertex->isDriver(network_))
+        level_drvr_vertices_.push_back(vertex);
+    }
+    sort(level_drvr_vertices_, VertexLevelLess(network_));
+    level_drvr_vertices_valid_ = true;
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::resizePreamble()
+{
+  init();
+  makeEquivCells();
+  findBuffers();
+  findTargetLoads();
+}
+
+static float
+bufferDrive(const LibertyCell *buffer)
+{
+  LibertyPort *input, *output;
+  buffer->bufferPorts(input, output);
+  return output->driveResistance();
+}
+
+void
+Resizer::findBuffers()
+{
+  LibertyLibraryIterator *lib_iter = network_->libertyLibraryIterator();
+  while (lib_iter->hasNext()) {
+    LibertyLibrary *lib = lib_iter->next();
+    for (LibertyCell *buffer : *lib->buffers()) {
+      if (!dontUse(buffer)
+          && isLinkCell(buffer)) {
+        buffer_cells_.push_back(buffer);
+      }
+    }
+  }
+  delete lib_iter;
+
+  if (buffer_cells_.empty())
+    logger_->error(RSZ, 22, "no buffers found.");
+
+  sort(buffer_cells_, [] (const LibertyCell *buffer1,
+                          const LibertyCell *buffer2) {
+                        return bufferDrive(buffer1) > bufferDrive(buffer2);
+                      });
+  buffer_lowest_drive_ = buffer_cells_[0];
+  buffer_med_drive_ = buffer_cells_[buffer_cells_.size() / 2];
+  buffer_highest_drive_ = buffer_cells_[buffer_cells_.size() - 1];
+}
+
+bool
+Resizer::isLinkCell(LibertyCell *cell)
+{
+  return network_->findLibertyCell(cell->name()) == cell;
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::bufferInputs()
+{
+  init();
+  inserted_buffer_count_ = 0;
+  incrementalParasiticsBegin();
+  InstancePinIterator *port_iter = network_->pinIterator(network_->topInstance());
+  while (port_iter->hasNext()) {
+    Pin *pin = port_iter->next();
+    Vertex *vertex = graph_->pinDrvrVertex(pin);
+    Net *net = network_->net(network_->term(pin));
+    if (network_->direction(pin)->isInput()
+        && !vertex->isConstant()
+        && !sta_->isClock(pin)
+        // Hands off special nets.
+        && !db_network_->isSpecial(net)
+        && hasPins(net))
+      // repair_design will resize to target slew.
+      bufferInput(pin, buffer_lowest_drive_);
+  }
+  delete port_iter;
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (inserted_buffer_count_ > 0) {
+    logger_->info(RSZ, 27, "Inserted {} input buffers.", inserted_buffer_count_);
+    level_drvr_vertices_valid_ = false;
+  }
+}
+   
+bool
+Resizer::hasPins(Net *net)
+{
+  NetPinIterator *pin_iter = db_network_->pinIterator(net);
+  bool has_pins = pin_iter->hasNext();
+  delete pin_iter;
+  return has_pins;
+}
+
+Instance *
+Resizer::bufferInput(const Pin *top_pin,
+                     LibertyCell *buffer_cell)
+{
+  Term *term = db_network_->term(top_pin);
+  Net *input_net = db_network_->net(term);
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  string buffer_name = makeUniqueInstName("input");
+  Instance *parent = db_network_->topInstance();
+  Net *buffer_out = makeUniqueNet();
+  Instance *buffer = makeInstance(buffer_cell,
+                                  buffer_name.c_str(),
+                                  parent);
+  if (buffer) {
+    journalMakeBuffer(buffer);
+    Point pin_loc = db_network_->location(top_pin);
+    Point buf_loc = core_exists_ ? core_.closestPtInside(pin_loc) : pin_loc;
+    setLocation(buffer, buf_loc);
+    designAreaIncr(area(db_network_->cell(buffer_cell)));
+    inserted_buffer_count_++;
+
+    NetPinIterator *pin_iter = db_network_->pinIterator(input_net);
+    while (pin_iter->hasNext()) {
+      Pin *pin = pin_iter->next();
+      // Leave input port pin connected to input_net.
+      if (pin != top_pin) {
+        sta_->disconnectPin(pin);
+        Port *pin_port = db_network_->port(pin);
+        sta_->connectPin(db_network_->instance(pin), pin_port, buffer_out);
+      }
+    }
+    delete pin_iter;
+    sta_->connectPin(buffer, input, input_net);
+    sta_->connectPin(buffer, output, buffer_out);
+
+    parasiticsInvalid(input_net);
+    parasiticsInvalid(buffer_out);
+  }
+  return buffer;
+}
+
+void
+Resizer::setLocation(Instance *inst,
+                     Point pt)
+{
+  // Stay inside the lines.
+  if (core_exists_)
+    pt = core_.closestPtInside(pt);
+
+  dbInst *dinst = db_network_->staToDb(inst);
+  dinst->setPlacementStatus(dbPlacementStatus::PLACED);
+  dinst->setLocation(pt.getX(), pt.getY());
+}
+
+void
+Resizer::bufferOutputs()
+{
+  init();
+  inserted_buffer_count_ = 0;
+  incrementalParasiticsBegin();
+  InstancePinIterator *port_iter = network_->pinIterator(network_->topInstance());
+  while (port_iter->hasNext()) {
+    Pin *pin = port_iter->next();
+    Vertex *vertex = graph_->pinLoadVertex(pin);
+    Net *net = network_->net(network_->term(pin));
+    if (network_->direction(pin)->isOutput()
+        && net
+        // DEF does not have tristate output types so we have look at the drivers.
+        && !hasTristateDriver(net)
+        && !vertex->isConstant()
+        // Hands off special nets.
+        && !db_network_->isSpecial(net)
+        && hasPins(net))
+      bufferOutput(pin, buffer_lowest_drive_);
+  }
+  delete port_iter;
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (inserted_buffer_count_ > 0) {
+    logger_->info(RSZ, 28, "Inserted {} output buffers.", inserted_buffer_count_);
+    level_drvr_vertices_valid_ = false;
+  }
+}
+
+bool
+Resizer::hasTristateDriver(const Net *net)
+{
+  PinSet *drivers = network_->drivers(net);
+  if (drivers) {
+    for (Pin *pin : *drivers) {
+      if (isTristateDriver(pin))
+        return true;
+    }
+  }
+  return false;
+}
+
+bool
+Resizer::isTristateDriver(const Pin *pin)
+{
+  // Note LEF macro PINs do not have a clue about tristates.
+  LibertyPort *port = network_->libertyPort(pin);
+  return port && port->direction()->isAnyTristate();
+}
+
+void
+Resizer::bufferOutput(Pin *top_pin,
+                      LibertyCell *buffer_cell)
+{
+  NetworkEdit *network = networkEdit();
+  Term *term = network_->term(top_pin);
+  Net *output_net = network_->net(term);
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  string buffer_name = makeUniqueInstName("output");
+  Instance *parent = network->topInstance();
+  Net *buffer_in = makeUniqueNet();
+  Instance *buffer = makeInstance(buffer_cell,
+                                  buffer_name.c_str(),
+                                  parent);
+  if (buffer) {
+    journalMakeBuffer(buffer);
+    setLocation(buffer, db_network_->location(top_pin));
+    designAreaIncr(area(db_network_->cell(buffer_cell)));
+    inserted_buffer_count_++;
+
+    NetPinIterator *pin_iter = network->pinIterator(output_net);
+    while (pin_iter->hasNext()) {
+      Pin *pin = pin_iter->next();
+      if (pin != top_pin) {
+        // Leave output port pin connected to output_net.
+        sta_->disconnectPin(pin);
+        Port *pin_port = network->port(pin);
+        sta_->connectPin(network->instance(pin), pin_port, buffer_in);
+      }
+    }
+    delete pin_iter;
+    sta_->connectPin(buffer, input, buffer_in);
+    sta_->connectPin(buffer, output, output_net);
+
+    parasiticsInvalid(buffer_in);
+    parasiticsInvalid(output_net);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+// Repair long wires, max slew, max capacitance, max fanout violations
+// The whole enchilada.
+// max_wire_length zero for none (meters)
+void
+Resizer::repairDesign(double max_wire_length,
+                      double slew_margin,
+                      double max_cap_margin)
+{
+  int repair_count, slew_violations, cap_violations;
+  int fanout_violations, length_violations;
+  repairDesign(max_wire_length, slew_margin, max_cap_margin,
+               repair_count, slew_violations, cap_violations,
+               fanout_violations, length_violations);
+
+  if (slew_violations > 0)
+    logger_->info(RSZ, 34, "Found {} slew violations.", slew_violations);
+  if (fanout_violations > 0)
+    logger_->info(RSZ, 35, "Found {} fanout violations.", fanout_violations);
+  if (cap_violations > 0)
+    logger_->info(RSZ, 36, "Found {} capacitance violations.", cap_violations);
+  if (length_violations > 0)
+    logger_->info(RSZ, 37, "Found {} long wires.", length_violations);
+  if (inserted_buffer_count_ > 0)
+    logger_->info(RSZ, 38, "Inserted {} buffers in {} nets.",
+                  inserted_buffer_count_,
+                  repair_count);
+  if (resize_count_ > 0)
+    logger_->info(RSZ, 39, "Resized {} instances.", resize_count_);
+}
+
+void
+Resizer::repairDesign(double max_wire_length, // zero for none (meters)
+                      double slew_margin,
+                      double max_cap_margin,
+                      int &repair_count,
+                      int &slew_violations,
+                      int &cap_violations,
+                      int &fanout_violations,
+                      int &length_violations)
+{
+  repair_count = 0;
+  slew_violations = 0;
+  cap_violations = 0;
+  fanout_violations = 0;
+  length_violations = 0;
+  inserted_buffer_count_ = 0;
+  resize_count_ = 0;
+
+  sta_->checkSlewLimitPreamble();
+  sta_->checkCapacitanceLimitPreamble();
+  sta_->checkFanoutLimitPreamble();
+
+  incrementalParasiticsBegin();
+  int max_length = metersToDbu(max_wire_length);
+  for (int i = level_drvr_vertices_.size() - 1; i >= 0; i--) {
+    Vertex *drvr = level_drvr_vertices_[i];
+    Pin *drvr_pin = drvr->pin();
+    Net *net = network_->isTopLevelPort(drvr_pin)
+      ? network_->net(network_->term(drvr_pin))
+      : network_->net(drvr_pin);
+    if (net
+        && !sta_->isClock(drvr_pin)
+        // Exclude tie hi/low cells and supply nets.
+        && !drvr->isConstant())
+      repairNet(net, drvr_pin, drvr, slew_margin, max_cap_margin,
+                true, true, true, max_length, true,
+                repair_count, slew_violations, cap_violations,
+                fanout_violations, length_violations);
+  }
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (inserted_buffer_count_ > 0)
+    level_drvr_vertices_valid_ = false;
+}
+
+// repairDesign but restricted to clock network and
+// no max_fanout/max_cap checks.
+void
+Resizer::repairClkNets(double max_wire_length) // max_wire_length zero for none (meters)
+{
+  init();
+  // Need slews to resize inserted buffers.
+  sta_->findDelays();
+
+  inserted_buffer_count_ = 0;
+  resize_count_ = 0;
+
+  int repair_count = 0;
+  int slew_violations = 0;
+  int cap_violations = 0;
+  int fanout_violations = 0;
+  int length_violations = 0;
+  int max_length = metersToDbu(max_wire_length);
+  incrementalParasiticsBegin();
+  for (Clock *clk : sdc_->clks()) {
+    for (const Pin *clk_pin : *sta_->pins(clk)) {
+      Net *net = network_->isTopLevelPort(clk_pin)
+        ? network_->net(network_->term(clk_pin))
+        : network_->net(clk_pin);
+      if (network_->isDriver(clk_pin)) {
+        Vertex *drvr = graph_->pinDrvrVertex(clk_pin);
+        // Do not resize clock tree gates.
+        repairNet(net, clk_pin, drvr, 0.0, 0.0,
+                  false, false, false, max_length, false,
+                  repair_count, slew_violations, cap_violations,
+                  fanout_violations, length_violations);
+      }
+    }
+  }
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (length_violations > 0)
+    logger_->info(RSZ, 47, "Found {} long wires.", length_violations);
+  if (inserted_buffer_count_ > 0) {
+    logger_->info(RSZ, 48, "Inserted {} buffers in {} nets.",
+                  inserted_buffer_count_,
+                  repair_count);
+    level_drvr_vertices_valid_ = false;
+  }
+}
+
+// Repair one net (for debugging)
+void
+Resizer::repairNet(Net *net,
+                   double max_wire_length, // meters
+                   double slew_margin,
+                   double max_cap_margin)
+{
+  init();
+
+  sta_->checkSlewLimitPreamble();
+  sta_->checkCapacitanceLimitPreamble();
+  sta_->checkFanoutLimitPreamble();
+
+  inserted_buffer_count_ = 0;
+  resize_count_ = 0;
+  resized_multi_output_insts_.clear();
+  int repair_count = 0;
+  int slew_violations = 0;
+  int cap_violations = 0;
+  int fanout_violations = 0;
+  int length_violations = 0;
+  int max_length = metersToDbu(max_wire_length);
+  PinSet *drivers = network_->drivers(net);
+  if (drivers && !drivers->empty()) {
+    PinSet::Iterator drvr_iter(drivers);
+    Pin *drvr_pin = drvr_iter.next();
+    Vertex *drvr = graph_->pinDrvrVertex(drvr_pin);
+    repairNet(net, drvr_pin, drvr, slew_margin, max_cap_margin,
+              true, true, true, max_length, true,
+              repair_count, slew_violations, cap_violations,
+              fanout_violations, length_violations);
+  }
+
+  if (slew_violations > 0)
+    logger_->info(RSZ, 51, "Found {} slew violations.", slew_violations);
+  if (fanout_violations > 0)
+    logger_->info(RSZ, 52, "Found {} fanout violations.", fanout_violations);
+  if (cap_violations > 0)
+    logger_->info(RSZ, 53, "Found {} capacitance violations.", cap_violations);
+  if (length_violations > 0)
+    logger_->info(RSZ, 54, "Found {} long wires.", length_violations);
+  if (inserted_buffer_count_ > 0) {
+    logger_->info(RSZ, 55, "Inserted {} buffers in {} nets.",
+                  inserted_buffer_count_,
+                  repair_count);
+    level_drvr_vertices_valid_ = false;
+  }
+  if (resize_count_ > 0)
+    logger_->info(RSZ, 56, "Resized {} instances.", resize_count_);
+  if (resize_count_ > 0)
+    logger_->info(RSZ, 57, "Resized {} instances.", resize_count_);
+}
+
+void
+Resizer::repairNet(Net *net,
+                   const Pin *drvr_pin,
+                   Vertex *drvr,
+                   double slew_margin,
+                   double max_cap_margin,
+                   bool check_slew,
+                   bool check_cap,
+                   bool check_fanout,
+                   int max_length, // dbu
+                   bool resize_drvr,
+                   int &repair_count,
+                   int &slew_violations,
+                   int &cap_violations,
+                   int &fanout_violations,
+                   int &length_violations)
+{
+  // Hands off special nets.
+  if (!db_network_->isSpecial(net)) {
+    SteinerTree *tree = makeSteinerTree(drvr_pin, true, max_steiner_pin_count_,
+                                        stt_builder_, db_network_, logger_);
+    if (tree) {
+      debugPrint(logger_, RSZ, "repair_net", 1, "repair net {}",
+                 sdc_network_->pathName(drvr_pin));
+      // Resize the driver to normalize slews before repairing limit violations.
+      if (resize_drvr)
+        resizeToTargetSlew(drvr_pin, true);
+      // For tristate nets all we can do is resize the driver.
+      if (!isTristateDriver(drvr_pin)) {
+        ensureWireParasitic(drvr_pin, net);
+        graph_delay_calc_->findDelays(drvr);
+
+        float max_load_slew = INF;
+        float max_cap = INF;
+        float max_fanout = INF;
+        bool repair_slew = false;
+        bool repair_cap = false;
+        bool repair_fanout = false;
+        bool repair_wire = false;
+        const Corner *corner = sta_->cmdCorner();
+        if (check_cap) {
+          float cap1, max_cap1, cap_slack1;
+          const Corner *corner1;
+          const RiseFall *tr1;
+          sta_->checkCapacitance(drvr_pin, nullptr, max_,
+                                 corner1, tr1, cap1, max_cap1, cap_slack1);
+          if (max_cap1 > 0.0 && corner1) {
+            max_cap1 *= (1.0 - max_cap_margin / 100.0);
+            max_cap = max_cap1;
+            if (cap1 > max_cap1) {
+              corner = corner1;
+              cap_violations++;
+              repair_cap = true;
+            }
+          }
+        }
+        if (check_fanout) {
+          float fanout, fanout_slack;
+          sta_->checkFanout(drvr_pin, max_,
+                            fanout, max_fanout, fanout_slack);
+          if (max_fanout > 0.0 && fanout_slack < 0.0) {
+            fanout_violations++;
+            repair_fanout = true;
+          }
+        }
+        int wire_length = findMaxSteinerDist(tree);
+        if (max_length
+            && wire_length > max_length) {
+          length_violations++;
+          repair_wire = true;
+        }
+        if (check_slew) {
+          float slew1, slew_slack1, max_slew1;
+          const Corner *corner1;
+          // Check slew at the driver.
+          checkSlew(drvr_pin, slew_margin, slew1, max_slew1, slew_slack1, corner1);
+          // Max slew violations at the driver pin are repaired by reducing the
+          // load capacitance. Wire resistance may shield capacitance from the
+          // driver but so this is conservative.
+          // Find max load cap that corresponds to max_slew.
+          LibertyPort *drvr_port = network_->libertyPort(drvr_pin);
+          if (corner1
+              && max_slew1 > 0.0 && drvr_port) {
+            float max_cap1 = findSlewLoadCap(drvr_port, max_slew1, corner1);
+            max_cap = min(max_cap, max_cap1);
+            corner = corner1;
+            debugPrint(logger_, RSZ, "repair_net", 2, "drvr_slew={} max_slew={} max_cap={} corner={}",
+                       delayAsString(slew1, this, 3),
+                       delayAsString(max_slew1, this, 3),
+                       units_->capacitanceUnit()->asString(max_cap1, 3),
+                       corner1->name());
+            if (slew_slack1 < 0.0)
+              repair_slew = true;
+          }
+          if (slew_slack1 < 0.0)
+            slew_violations++;
+
+          // Check slew at the loads.
+          // Note that many liberty libraries do not have max_transition attributes on
+          // input pins.
+          // Max slew violations at the load pins are repaired by reducing the
+          // wire length.
+          checkLoadSlews(drvr_pin, slew_margin, slew1, max_slew1, slew_slack1, corner1);
+          // Even when there are no load violations we need max_load_slew for
+          // sizing inserted buffers.
+          if (max_slew1 > 0.0) {
+            max_load_slew = max_slew1;
+            debugPrint(logger_, RSZ, "repair_net", 2, "load_slew={} max_load_slew={}",
+                       delayAsString(slew1, this, 3),
+                       delayAsString(max_load_slew, this, 3));
+            if (slew_slack1 < 0.0) {
+              // Don't double count violations on the same net.
+              if (!repair_slew)
+                slew_violations++;
+              corner = corner1;
+              repair_slew = true;
+            }
+          }
+        }
+
+        if (repair_slew
+            || repair_cap
+            || repair_fanout
+            || repair_wire) {
+          Point drvr_loc = db_network_->location(drvr->pin());
+          debugPrint(logger_, RSZ, "repair_net", 1, "driver {} ({} {}) l={}",
+                     sdc_network_->pathName(drvr_pin),
+                     units_->distanceUnit()->asString(dbuToMeters(drvr_loc.getX()), 1),
+                     units_->distanceUnit()->asString(dbuToMeters(drvr_loc.getY()), 1),
+                     units_->distanceUnit()->asString(dbuToMeters(wire_length), 1));
+          SteinerPt drvr_pt = tree->drvrPt(network_);
+          int wire_length;
+          float pin_cap, fanout;
+          PinSeq load_pins;
+          if (drvr_pt != SteinerTree::null_pt)
+            repairNet(tree, drvr_pt, SteinerTree::null_pt, net, drvr_pin,
+                      max_load_slew, max_cap, max_fanout, max_length, corner, 0,
+                      wire_length, pin_cap, fanout, load_pins);
+          repair_count++;
+
+          if (resize_drvr)
+            resizeToTargetSlew(drvr_pin, true);
+        }
+      }
+      delete tree;
+    }
+  }
+}
+
+bool
+Resizer::checkLimits(const Pin *drvr_pin,
+                     double slew_margin,
+                     double max_cap_margin,
+                     bool check_slew,
+                     bool check_cap,
+                     bool check_fanout)
+{
+  if (check_cap) {
+    float cap1, max_cap1, cap_slack1;
+    const Corner *corner1;
+    const RiseFall *tr1;
+    sta_->checkCapacitance(drvr_pin, nullptr, max_,
+                           corner1, tr1, cap1, max_cap1, cap_slack1);
+    max_cap1 *= (1.0 - max_cap_margin / 100.0);
+    if (cap1 < max_cap1)
+      return true;
+  }
+  if (check_fanout) {
+    float fanout, fanout_slack, max_fanout;
+    sta_->checkFanout(drvr_pin, max_,
+                      fanout, max_fanout, fanout_slack);
+    if (fanout_slack < 0.0)
+      return true;
+
+  }
+  if (check_slew) {
+    float slew1, slew_slack1, max_slew1;
+    const Corner *corner1;
+    checkSlew(drvr_pin, slew_margin, slew1, max_slew1, slew_slack1, corner1);
+    if (slew_slack1 < 0.0)
+      return true;
+    checkLoadSlews(drvr_pin, slew_margin, slew1, max_slew1, slew_slack1, corner1);
+    if (slew_slack1 < 0.0)
+      return true;
+  }
+  return false;
+}
+
+void
+Resizer::checkSlew(const Pin *drvr_pin,
+                   double slew_margin,
+                   // Return values.
+                   Slew &slew,
+                   float &limit,
+                   float &slack,
+                   const Corner *&corner)
+{
+  slack = INF;
+  limit = INF;
+  corner = nullptr;
+
+  const Corner *corner1;
+  const RiseFall *tr1;
+  Slew slew1;
+  float limit1, slack1;
+  sta_->checkSlew(drvr_pin, nullptr, max_, false,
+                  corner1, tr1, slew1, limit1, slack1);
+  if (corner1) {
+    limit1 *= (1.0 - slew_margin / 100.0);
+    slack1 = limit1 - slew1;
+    if (slack1 < slack) {
+      slew = slew1;
+      limit = limit1;
+      slack = slack1;
+      corner = corner1;
+    }
+  }
+}
+
+void
+Resizer::checkLoadSlews(const Pin *drvr_pin,
+                        double slew_margin,
+                        // Return values.
+                        Slew &slew,
+                        float &limit,
+                        float &slack,
+                        const Corner *&corner)
+{
+  slack = INF;
+  limit = INF;
+  PinConnectedPinIterator *pin_iter = network_->connectedPinIterator(drvr_pin);
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    if (pin != drvr_pin) {
+      const Corner *corner1;
+      const RiseFall *tr1;
+      Slew slew1;
+      float limit1, slack1;
+      sta_->checkSlew(pin, nullptr, max_, false,
+                      corner1, tr1, slew1, limit1, slack1);
+      if (corner1) {
+        limit1 *= (1.0 - slew_margin / 100.0);
+        limit = min(limit, limit1);
+        slack1 = limit1 - slew1;
+        if (slack1 < slack) {
+          slew = slew1;
+          slack = slack1;
+          corner = corner1;
+        }
+      }
+    }
+  }
+  delete pin_iter;
+}
+
+// Find the output port load capacitance that results in slew.
+double
+Resizer::findSlewLoadCap(LibertyPort *drvr_port,
+                         double slew,
+                         const Corner *corner)
+{
+  const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(max_);
+  // cap1 lower bound
+  // cap2 upper bound
+  double cap1 = 0.0;
+  double cap2 = slew / drvr_port->driveResistance() * 2;
+  double tol = .01; // 1%
+  double diff1 = gateSlewDiff(drvr_port, cap2, slew, dcalc_ap);
+  // binary search for diff = 0.
+  while (abs(cap1 - cap2) > max(cap1, cap2) * tol) {
+    if (diff1 < 0.0) {
+      cap1 = cap2;
+      cap2 *= 2;
+      diff1 = gateSlewDiff(drvr_port, cap2, slew, dcalc_ap);
+    }
+    else {
+      double cap3 = (cap1 + cap2) / 2.0;
+      double diff2 = gateSlewDiff(drvr_port, cap3, slew, dcalc_ap);
+      if (diff2 < 0.0) {
+        cap1 = cap3;
+      }
+      else {
+        cap2 = cap3;
+        diff1 = diff2;
+      }
+    }
+  }
+  return cap1;
+}
+
+// objective function
+double
+Resizer::gateSlewDiff(LibertyPort *drvr_port,
+                      double load_cap,
+                      double slew,
+                      const DcalcAnalysisPt *dcalc_ap)
+{
+  ArcDelay delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  gateDelays(drvr_port, load_cap, dcalc_ap, delays, slews);
+  Slew gate_slew = max(slews[RiseFall::riseIndex()], slews[RiseFall::fallIndex()]);
+  return gate_slew - slew;
+}
+
+void
+Resizer::repairNet(SteinerTree *tree,
+                   SteinerPt pt,
+                   SteinerPt prev_pt,
+                   Net *net,
+                   const Pin *drvr_pin,
+                   float max_load_slew,
+                   float max_cap,
+                   float max_fanout,
+                   int max_length, // dbu
+                   const Corner *corner,
+                   int level,
+                   // Return values.
+                   // Remaining parasiics after repeater insertion.
+                   int &wire_length, // dbu
+                   float &pin_cap,
+                   float &fanout,
+                   PinSeq &load_pins)
+{
+  Point pt_loc = tree->location(pt);
+  int pt_x = pt_loc.getX();
+  int pt_y = pt_loc.getY();
+  debugPrint(logger_, RSZ, "repair_net", 2, "{:{}s}pt ({} {})",
+             "", level,
+             units_->distanceUnit()->asString(dbuToMeters(pt_x), 1),
+             units_->distanceUnit()->asString(dbuToMeters(pt_y), 1));
+  double wire_cap = wireSignalCapacitance(corner);
+  double wire_res = wireSignalResistance(corner);
+  SteinerPt left = tree->left(pt);
+  int wire_length_left = 0;
+  float pin_cap_left = 0.0;
+  float fanout_left = 0.0;
+  PinSeq loads_left;
+  if (left != SteinerTree::null_pt)
+    repairNet(tree, left, pt, net, drvr_pin, max_load_slew, max_cap, max_fanout, max_length,
+              corner, level+1,
+              wire_length_left, pin_cap_left, fanout_left, loads_left);
+  SteinerPt right = tree->right(pt);
+  int wire_length_right = 0;
+  float pin_cap_right = 0.0;
+  float fanout_right = 0.0;
+  PinSeq loads_right;
+  if (right != SteinerTree::null_pt)
+    repairNet(tree, right, pt, net, drvr_pin, max_load_slew, max_cap, max_fanout, max_length,
+              corner, level+1,
+              wire_length_right, pin_cap_right, fanout_right, loads_right);
+  debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}left l={} pin_cap={} fanout={}, right l={} pin_cap={} fanout={}",
+             "", level,
+             units_->distanceUnit()->asString(dbuToMeters(wire_length_left), 1),
+             units_->capacitanceUnit()->asString(pin_cap_left, 3),
+             fanout_left,
+             units_->distanceUnit()->asString(dbuToMeters(wire_length_right), 1),
+             units_->capacitanceUnit()->asString(pin_cap_right, 3),
+             fanout_right);
+  // Add a buffer to left or right branch to stay under the max cap/length/fanout.
+  bool repeater_left = false;
+  bool repeater_right = false;
+  double cap_left = pin_cap_left + dbuToMeters(wire_length_left) * wire_cap;
+  double cap_right = pin_cap_right + dbuToMeters(wire_length_right) * wire_cap;
+  debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}cap_left={}, right_cap={}",
+             "", level,
+             units_->capacitanceUnit()->asString(cap_left, 3),
+             units_->capacitanceUnit()->asString(cap_right, 3));
+
+  double wire_length1 = dbuToMeters(wire_length_left + wire_length_right);
+  float load_cap = cap_left + cap_right;
+
+  LibertyCell *buffer_cell = findTargetCell(buffer_lowest_drive_, load_cap, false);
+  LibertyPort *input, *buffer_output;
+  buffer_cell->bufferPorts(input, buffer_output);
+  float r_buffer = buffer_output->driveResistance();
+  float r_drv = driveResistance(drvr_pin);
+  float r_drvr = max(r_drv, r_buffer);
+  // Elmore factor for 20-80% slew thresholds.
+  float k_threshold = 1.39;
+  Slew load_slew = (r_drvr + wire_length1 * wire_res) * load_cap * k_threshold;
+  debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}load_slew={} r_drvr={} r_buffer={}",
+             "", level,
+             delayAsString(load_slew, this, 3),
+             units_->resistanceUnit()->asString(r_drv, 3),
+             units_->resistanceUnit()->asString(r_buffer, 3));
+
+  bool slew_violation = load_slew > max_load_slew;
+  if (slew_violation) {
+    debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}slew violation", "", level);
+    if (cap_left > cap_right)
+      repeater_left = true;
+    else
+      repeater_right = true;
+  }
+
+  bool cap_violation = (cap_left + cap_right) > max_cap;
+  if (cap_violation) {
+    debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}cap violation", "", level);
+    if (cap_left > cap_right)
+      repeater_left = true;
+    else
+      repeater_right = true;
+  }
+  bool length_violation = max_length > 0
+    && (wire_length_left + wire_length_right) > max_length;
+  if (length_violation) {
+    debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}length violation", "", level);
+    if (wire_length_left > wire_length_right)
+      repeater_left = true;
+    else
+      repeater_right = true;
+  }
+  bool fanout_violation = max_fanout > 0
+    // Note that if both fanout_left==max_fanout and fanout_right==max_fanout
+    // there is no way repair the violation (adding a buffer to either branch
+    // results in max_fanout+1, which is a violation).
+    // Leave room for one buffer on the other branch by using >= to avoid
+    // this situation.
+    && (fanout_left + fanout_right) >= max_fanout;
+  if (fanout_violation) {
+    debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}fanout violation", "", level);
+    if (fanout_left > fanout_right)
+      repeater_left = true;
+    else
+      repeater_right = true;
+  }
+
+  if (repeater_left)
+    makeRepeater("left", tree, pt, buffer_cell, level,
+                 wire_length_left, pin_cap_left, fanout_left, loads_left);
+  if (repeater_right)
+    makeRepeater("right", tree, pt, buffer_cell, level,
+                 wire_length_right, pin_cap_right, fanout_right, loads_right);
+
+  // Update after left/right repeaters are inserted.
+  wire_length = wire_length_left + wire_length_right;
+  pin_cap = pin_cap_left + pin_cap_right;
+  fanout = fanout_left + fanout_right;
+
+  // Union left/right load pins.
+  for (Pin *load_pin : loads_left)
+    load_pins.push_back(load_pin);
+  for (Pin *load_pin : loads_right)
+    load_pins.push_back(load_pin);
+
+  // Steiner pt pin is the net driver if prev_pt is null.
+  if (prev_pt != SteinerTree::null_pt) {
+    const PinSeq *pt_pins = tree->pins(pt);
+    if (pt_pins) {
+      for (Pin *load_pin : *pt_pins) {
+        Point load_loc = db_network_->location(load_pin);
+        int load_dist = Point::manhattanDistance(load_loc, pt_loc);
+        debugPrint(logger_, RSZ, "repair_net", 2, "{:{}s}load {} ({} {}) dist={}",
+                   "", level,
+                   sdc_network_->pathName(load_pin),
+                   units_->distanceUnit()->asString(dbuToMeters(load_loc.getX()), 1),
+                   units_->distanceUnit()->asString(dbuToMeters(load_loc.getY()), 1),
+                   units_->distanceUnit()->asString(dbuToMeters(load_dist), 1));
+        LibertyPort *load_port = network_->libertyPort(load_pin);
+        if (load_port) {
+          pin_cap += load_port->capacitance();
+          fanout += portFanoutLoad(load_port);
+        }
+        else
+          fanout += 1;
+        load_pins.push_back(load_pin);
+      }
+    }
+
+    Point prev_loc = tree->location(prev_pt);
+    int length = Point::manhattanDistance(prev_loc, pt_loc);
+    wire_length += length;
+    // Back up from pt to prev_pt adding repeaters every max_length.
+    int prev_x = prev_loc.getX();
+    int prev_y = prev_loc.getY();
+    debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}wl={} l={}",
+               "", level,
+               units_->distanceUnit()->asString(dbuToMeters(wire_length), 1),
+               units_->distanceUnit()->asString(dbuToMeters(length), 1));
+    wire_length1 = dbuToMeters(wire_length);
+    load_cap = pin_cap + wire_length1 * wire_cap;
+
+    buffer_cell = findTargetCell(buffer_lowest_drive_, load_cap, false);
+    buffer_cell->bufferPorts(input, buffer_output);
+    r_buffer = buffer_output->driveResistance();
+    r_drv = driveResistance(drvr_pin);
+    r_drvr = max(r_drv, r_buffer);
+    load_slew = (r_drvr + wire_length1 * wire_res) * load_cap * k_threshold;
+    debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}load_slew={} r_drvr={} r_buffer={}",
+               "", level,
+               delayAsString(load_slew, this, 3),
+               units_->resistanceUnit()->asString(r_drv, 3),
+               units_->resistanceUnit()->asString(r_buffer, 3));
+
+    while ((max_length > 0 && wire_length > max_length)
+           || (wire_cap > 0.0
+               // Cannot fix max cap violations from pin cap by shortening wire.
+               && pin_cap < max_cap
+               && load_cap > max_cap)
+           || load_slew > max_load_slew) {
+      // Make the wire a bit shorter than necessary to allow for
+      // offset from instance origin to pin and detailed placement movement.
+      static double length_margin = .05;
+      bool split_wire = false;
+      int split_length = std::numeric_limits<int>::max();
+      if (max_length > 0 && wire_length > max_length) {
+        split_length = min(split_length, max_length);
+        split_wire = true;
+      }
+      if (wire_cap > 0.0
+          && pin_cap < max_cap
+          && load_cap > max_cap) {
+        split_length = min(split_length, metersToDbu((max_cap - pin_cap) / wire_cap));
+        split_wire = true;
+      }
+      if (load_slew > max_load_slew
+          // Check that zero length wire meets max slew.
+          && r_drvr*pin_cap*k_threshold < max_load_slew) {
+        // Using elmore delay to approximate wire
+        // load_slew = (Rdrvr + L*Rwire) * (L*Cwire + Cpin) * k_threshold
+        // Setting this to max_slew is a quadratic in L
+        // L^2*Rwire*Cwire + L*(Rdrvr*Cwire + Rwire*Cpin) + Rdrvr*Cpin - max_slew/k_threshold
+        // Solve using quadradic eqn for L.
+        float a = wire_res * wire_cap;
+        float b = r_drvr * wire_cap + wire_res * pin_cap;
+        float c = r_drvr * pin_cap - max_load_slew / k_threshold;
+        float l = (-b + sqrt(b*b - 4 * a * c)) / (2 * a);
+        if (l > 0.0) {
+          split_length = min(split_length, metersToDbu(l));
+          split_wire = true;
+        }
+      }
+      if (split_wire) {
+        // Distance from pt to repeater backward toward prev_pt.
+        double buf_dist = length - (wire_length - split_length * (1.0 - length_margin));
+        double dx = prev_x - pt_x;
+        double dy = prev_y - pt_y;
+        double d = (length == 0) ? 0.0 : buf_dist / length;
+        int buf_x = pt_x + d * dx;
+        int buf_y = pt_y + d * dy;
+        makeRepeater("wire", buf_x, buf_y, buffer_lowest_drive_, level,
+                     wire_length, pin_cap, fanout, load_pins);
+        // Update for the next round.
+        length -= buf_dist;
+        wire_length = length;
+        pt_x = buf_x;
+        pt_y = buf_y;
+
+        wire_length1 = dbuToMeters(wire_length);
+        load_cap = pin_cap + wire_length1 * wire_cap;
+        load_slew = (r_drvr + wire_length1 * wire_res) * load_cap * k_threshold;
+        debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}load_slew={}",
+                   "", level,
+                   delayAsString(load_slew, this, 3));
+        debugPrint(logger_, RSZ, "repair_net", 3, "{:{}s}wl={} l={}",
+                   "", level,
+                   units_->distanceUnit()->asString(dbuToMeters(wire_length), 1),
+                   units_->distanceUnit()->asString(dbuToMeters(length), 1));
+      }
+      else
+        break;
+    }
+  }
+}
+
+void
+Resizer::makeRepeater(const char *where,
+                      SteinerTree *tree,
+                      SteinerPt pt,
+                      LibertyCell *buffer_cell,
+                      int level,
+                      int &wire_length,
+                      float &pin_cap,
+                      float &fanout,
+                      PinSeq &load_pins)
+{
+  Point pt_loc = tree->location(pt);
+  makeRepeater(where, pt_loc.getX(), pt_loc.getY(), buffer_cell, level,
+               wire_length, pin_cap, fanout, load_pins);
+}
+
+void
+Resizer::makeRepeater(const char *where,
+                      int x,
+                      int y,
+                      LibertyCell *buffer_cell,
+                      int level,
+                      int &wire_length,
+                      float &pin_cap,
+                      float &fanout,
+                      PinSeq &load_pins)
+{
+  LibertyPort *buffer_input_port, *buffer_output_port;
+  buffer_cell->bufferPorts(buffer_input_port, buffer_output_port);
+
+  string buffer_name = makeUniqueInstName("repeater");
+  debugPrint(logger_, RSZ, "repair_net", 2, "{:{}s}{} {} ({} {})",
+             "", level,
+             where,
+             buffer_name.c_str(),
+             units_->distanceUnit()->asString(dbuToMeters(x), 1),
+             units_->distanceUnit()->asString(dbuToMeters(y), 1));
+
+  // Inserting a buffer is complicated by the fact that verilog netlists
+  // use the net name for input and output ports. This means the ports
+  // cannot be moved to a different net.
+
+  // This cannot depend on the net in caller because the buffer may be inserted
+  // between the driver and the loads changing the net as the repair works its
+  // way from the loads to the driver.
+
+  Net *net = nullptr, *in_net, *out_net;
+  bool have_output_port_load = false;
+  for (Pin *pin : load_pins) {
+    if (network_->isTopLevelPort(pin)) {
+      net = network_->net(network_->term(pin));
+      if (network_->direction(pin)->isAnyOutput()) {
+        have_output_port_load = true;
+        break;
+      }
+    }
+    else
+      net = network_->net(pin);
+  }
+  Instance *parent = db_network_->topInstance();
+
+  // If the net is driven by an input port,
+  // use the net as the repeater input net so the port stays connected to it.
+  if (hasInputPort(net)
+      || !have_output_port_load) {
+    in_net = net;
+    out_net = makeUniqueNet();
+    // Copy signal type to new net.
+    dbNet *out_net_db = db_network_->staToDb(out_net);
+    dbNet *in_net_db = db_network_->staToDb(in_net);
+    out_net_db->setSigType(in_net_db->getSigType());
+
+    // Move load pins to out_net.
+    for (Pin *pin : load_pins) {
+      Port *port = network_->port(pin);
+      Instance *inst = network_->instance(pin);
+      sta_->disconnectPin(pin);
+      sta_->connectPin(inst, port, out_net);
+    }
+  }
+  else {
+    // One of the loads is an output port.
+    // Use the net as the repeater output net so the port stays connected to it.
+    in_net = makeUniqueNet();
+    out_net = net;
+    // Copy signal type to new net.
+    dbNet *out_net_db = db_network_->staToDb(out_net);
+    dbNet *in_net_db = db_network_->staToDb(in_net);
+    in_net_db->setSigType(out_net_db->getSigType());
+
+    // Move non-repeater load pins to in_net.
+    PinSet load_pins1;
+    for (Pin *pin : load_pins)
+      load_pins1.insert(pin);
+
+    NetPinIterator *pin_iter = network_->pinIterator(out_net);
+    while (pin_iter->hasNext()) {
+      Pin *pin = pin_iter->next();
+      if (!load_pins1.hasKey(pin)) {
+        Port *port = network_->port(pin);
+        Instance *inst = network_->instance(pin);
+        sta_->disconnectPin(pin);
+        sta_->connectPin(inst, port, in_net);
+      }
+    }
+  }
+
+  Instance *buffer = makeInstance(buffer_cell,
+                                  buffer_name.c_str(),
+                                  parent);
+  journalMakeBuffer(buffer);
+  Point buf_loc(x, y);
+  setLocation(buffer, buf_loc);
+  designAreaIncr(area(db_network_->cell(buffer_cell)));
+  inserted_buffer_count_++;
+
+  sta_->connectPin(buffer, buffer_input_port, in_net);
+  sta_->connectPin(buffer, buffer_output_port, out_net);
+
+  parasiticsInvalid(in_net);
+  parasiticsInvalid(out_net);
+
+  // Resize repeater as we back up by levels.
+  Pin *drvr_pin = network_->findPin(buffer, buffer_output_port);
+  resizeToTargetSlew(drvr_pin, false);
+  buffer_cell = network_->libertyCell(buffer);
+  buffer_cell->bufferPorts(buffer_input_port, buffer_output_port);
+
+  Pin *buf_in_pin = network_->findPin(buffer, buffer_input_port);
+  load_pins.clear();
+  load_pins.push_back(buf_in_pin);
+  wire_length = 0;
+  pin_cap = buffer_input_port->capacitance();
+  fanout = portFanoutLoad(buffer_input_port);
+}
+
+bool
+Resizer::hasInputPort(const Net *net)
+{
+  bool has_top_level_port = false;
+  NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net);
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    if (network_->isTopLevelPort(pin)
+        && network_->direction(pin)->isAnyInput()) {
+      has_top_level_port = true;
+      break;
+    }
+  }
+  delete pin_iter;
+  return has_top_level_port;
+}
+
+bool
+Resizer::hasOutputPort(const Net *net)
+{
+  bool has_top_level_port = false;
+  NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net);
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    if (network_->isTopLevelPort(pin)
+        && network_->direction(pin)->isAnyOutput()) {
+      has_top_level_port = true;
+      break;
+    }
+  }
+  delete pin_iter;
+  return has_top_level_port;
+}
+
+bool
+Resizer::hasPort(const Net *net)
+{
+  bool has_top_level_port = false;
+  NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net);
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    if (network_->isTopLevelPort(pin)) {
+      has_top_level_port = true;
+      break;
+    }
+  }
+  delete pin_iter;
+  return has_top_level_port;
+}
+
+float
+Resizer::driveResistance(const Pin *drvr_pin)
+{
+  if (network_->isTopLevelPort(drvr_pin)) {
+    InputDrive *drive = sdc_->findInputDrive(network_->port(drvr_pin));
+    if (drive) {
+      float max_res = 0;
+      for (auto min_max : MinMax::range()) {
+        for (auto rf : RiseFall::range()) {
+          LibertyCell *cell;
+          LibertyPort *from_port;
+          float *from_slews;
+          LibertyPort *to_port;
+          drive->driveCell(rf, min_max, cell, from_port, from_slews, to_port);
+          if (to_port)
+            max_res = max(max_res, to_port->driveResistance());
+          else {
+            float res;
+            bool exists;
+            drive->driveResistance(rf, min_max, res, exists);
+            max_res = max(max_res, res);
+          }
+        }
+      }
+      return max_res;
+    }
+  }
+  else {
+    LibertyPort *drvr_port = network_->libertyPort(drvr_pin);
+    if (drvr_port)
+      return drvr_port->driveResistance();
+  }
+  return 0.0;
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::resizeToTargetSlew()
+{
+  resize_count_ = 0;
+  resized_multi_output_insts_.clear();
+  incrementalParasiticsBegin();
+  // Resize in reverse level order.
+  for (int i = level_drvr_vertices_.size() - 1; i >= 0; i--) {
+    Vertex *drvr = level_drvr_vertices_[i];
+    Pin *drvr_pin = drvr->pin();
+    Net *net = network_->net(drvr_pin);
+    if (net
+        && !drvr->isConstant()
+        && hasFanout(drvr)
+        // Hands off the clock nets.
+        && !sta_->isClock(drvr_pin)
+        // Hands off special nets.
+        && !db_network_->isSpecial(net)) {
+      resizeToTargetSlew(drvr_pin, true);
+      if (overMaxArea()) {
+        logger_->error(RSZ, 24, "Max utilization reached.");
+        break;
+      }
+    }
+  }
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (resize_count_ > 0)
+    logger_->info(RSZ, 29, "Resized {} instances.", resize_count_);
+}
+
+bool
+Resizer::hasFanout(Vertex *drvr)
+{
+  VertexOutEdgeIterator edge_iter(drvr, graph_);
+  return edge_iter.hasNext();
+}
+
+void
+Resizer::makeEquivCells()
+{
+  LibertyLibrarySeq libs;
+  LibertyLibraryIterator *lib_iter = network_->libertyLibraryIterator();
+  while (lib_iter->hasNext()) {
+    LibertyLibrary *lib = lib_iter->next();
+    // massive kludge until makeEquivCells is fixed to only incldue link cells
+    LibertyCellIterator cell_iter(lib);
+    if (cell_iter.hasNext()) {
+      LibertyCell *cell = cell_iter.next();
+      if (isLinkCell(cell))
+        libs.push_back(lib);
+    }
+  }
+  delete lib_iter;
+  sta_->makeEquivCells(&libs, nullptr);
+}
+
+static float
+targetLoadDist(float load_cap,
+               float target_load)
+{
+  return abs(load_cap - target_load);
+}
+
+bool
+Resizer::resizeToTargetSlew(const Pin *drvr_pin,
+                            bool update_count)
+{
+  Instance *inst = network_->instance(drvr_pin);
+  LibertyCell *cell = network_->libertyCell(inst);
+  if (cell) {
+    bool revisiting_inst = false;
+    if (hasMultipleOutputs(inst)) {
+      revisiting_inst = resized_multi_output_insts_.hasKey(inst);
+      debugPrint(logger_, RSZ, "resize", 2, "multiple outputs{}",
+                 revisiting_inst ? " - revisit" : "");
+      resized_multi_output_insts_.insert(inst);
+    }
+    ensureWireParasitic(drvr_pin);
+    // Includes net parasitic capacitance.
+    float load_cap = graph_delay_calc_->loadCap(drvr_pin, tgt_slew_dcalc_ap_);
+    // DINESH-A: delay cells resize disabled
+    if (load_cap > 0.00 && (strncmp(cell->name(),"sky130_fd_sc_hd__clkdlybuf4s15_2",26) != 0)) {
+      LibertyCell *target_cell = findTargetCell(cell, load_cap, revisiting_inst);
+      if (target_cell != cell) {
+        //printf("Dinesh-A: Resizing : %s => %s %s Load_cap: %f \n",sdc_network_->pathName(drvr_pin),cell->name(),target_cell->name(),load_cap);
+        debugPrint(logger_, RSZ, "resize", 2, "{} {} -> {}",
+                   sdc_network_->pathName(drvr_pin),
+                   cell->name(),
+                   target_cell->name());
+        if (replaceCell(inst, target_cell, true)
+            && !revisiting_inst
+            && update_count)
+          resize_count_++;
+      }
+    }
+  }
+  return false;
+}
+
+LibertyCell *
+Resizer::findTargetCell(LibertyCell *cell,
+                        float load_cap,
+                        bool revisiting_inst)
+{
+  LibertyCell *best_cell = cell;
+  LibertyCellSeq *equiv_cells = sta_->equivCells(cell);
+  if (equiv_cells) {
+    bool is_buf_inv = cell->isBuffer() || cell->isInverter();
+    float target_load = (*target_load_map_)[cell];
+    float best_load = target_load;
+    float best_dist = targetLoadDist(load_cap, target_load);
+    float best_delay = is_buf_inv
+      ? bufferDelay(cell, load_cap, tgt_slew_dcalc_ap_)
+      : 0.0;
+    debugPrint(logger_, RSZ, "resize", 3, "{} load cap {} dist={:.2e} delay={}",
+               cell->name(),
+               units_->capacitanceUnit()->asString(load_cap),
+               best_dist,
+               delayAsString(best_delay, sta_, 3));
+    for (LibertyCell *target_cell : *equiv_cells) {
+      if (!dontUse(target_cell)
+          && isLinkCell(target_cell)) {
+        float target_load = (*target_load_map_)[target_cell];
+        float delay = is_buf_inv
+          ? bufferDelay(target_cell, load_cap, tgt_slew_dcalc_ap_)
+          : 0.0;
+        float dist = targetLoadDist(load_cap, target_load);
+        debugPrint(logger_, RSZ, "resize", 3, " {} dist={:.2e} delay={}",
+                   target_cell->name(),
+                   dist,
+                   delayAsString(delay, sta_, 3));
+        if (is_buf_inv
+            // Library may have "delay" buffers/inverters that are
+            // functionally buffers/inverters but have additional
+            // intrinsic delay. Accept worse target load matching if
+            // delay is reduced to avoid using them.
+            ? ((delay < best_delay
+                && dist < best_dist * 1.1)
+               || (dist < best_dist
+                   && delay < best_delay * 1.1))
+            : dist < best_dist
+            // If the instance has multiple outputs (generally a register Q/QN)
+            // only allow upsizing after the first pin is visited.
+            && (!revisiting_inst
+                || target_load > best_load)) {
+          best_cell = target_cell;
+          best_dist = dist;
+          best_load = target_load;
+          best_delay = delay;
+        }
+      }
+    }
+  }
+  return best_cell;
+}
+
+// Replace LEF with LEF so ports stay aligned in instance.
+bool
+Resizer::replaceCell(Instance *inst,
+                     LibertyCell *replacement,
+                     bool journal)
+{
+  const char *replacement_name = replacement->name();
+  dbMaster *replacement_master = db_->findMaster(replacement_name);
+  if (replacement_master) {
+    dbInst *dinst = db_network_->staToDb(inst);
+    dbMaster *master = dinst->getMaster();
+    designAreaIncr(-area(master));
+    Cell *replacement_cell1 = db_network_->dbToSta(replacement_master);
+    if (journal)
+      journalInstReplaceCellBefore(inst);
+    sta_->replaceCell(inst, replacement_cell1);
+    designAreaIncr(area(replacement_master));
+
+    // Invalidate estimated parasitics on all instance pins.
+    // Input nets change pin cap, outputs change location (slightly).
+    if (haveEstimatedParasitics()) {
+      InstancePinIterator *pin_iter = network_->pinIterator(inst);
+      while (pin_iter->hasNext()) {
+        const Pin *pin = pin_iter->next();
+        const Net *net = network_->net(pin);
+        if (net)
+          parasiticsInvalid(net);
+      }
+      delete pin_iter;
+    }
+    return true;
+  }
+  return false;
+}
+
+bool
+Resizer::hasMultipleOutputs(const Instance *inst)
+{
+  int output_count = 0;
+  InstancePinIterator *pin_iter = network_->pinIterator(inst);
+  while (pin_iter->hasNext()) {
+    const Pin *pin = pin_iter->next();
+    if (network_->direction(pin)->isAnyOutput()
+        && network_->net(pin)) {
+      output_count++;
+      if (output_count > 1)
+        return true;
+    }
+  }
+  return false;
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::resizeSlackPreamble()
+{
+  resizePreamble();
+  // Save max_wire_length for multiple repairDesign calls.
+  max_wire_length_ = findMaxWireLength();
+  net_slack_map_.clear();
+}
+
+// Run repair design to find the slacks but save/restore all changes to the netlist.
+void
+Resizer::findResizeSlacks()
+{
+  journalBegin();
+  estimateWireParasitics();
+  int repair_count, slew_violations, cap_violations;
+  int fanout_violations, length_violations;
+  repairDesign(max_wire_length_, 0.0, 0.0,
+               repair_count, slew_violations, cap_violations,
+               fanout_violations, length_violations);
+  findResizeSlacks1();
+  journalRestore();
+}
+  
+void
+Resizer::findResizeSlacks1()
+{
+  // Use driver pin slacks rather than Sta::netSlack to save visiting
+  // the net pins and min'ing the slack.
+  NetSeq nets;
+  for (int i = level_drvr_vertices_.size() - 1; i >= 0; i--) {
+    Vertex *drvr = level_drvr_vertices_[i];
+    Pin *drvr_pin = drvr->pin();
+    Net *net = network_->isTopLevelPort(drvr_pin)
+      ? network_->net(network_->term(drvr_pin))
+      : network_->net(drvr_pin);
+    if (net
+        && !drvr->isConstant()
+        // Hands off special nets.
+        && !db_network_->isSpecial(net)
+        && !sta_->isClock(drvr_pin)) {
+      net_slack_map_[net] = sta_->vertexSlack(drvr, max_);
+      nets.push_back(net);
+    }
+  }
+
+  // Find the nets with the worst slack.
+  double worst_percent = .1;
+  //  sort(nets.begin(), nets.end(). [&](const Net *net1,
+  sort(nets, [this](const Net *net1,
+                 const Net *net2)
+             { return resizeNetSlack(net1) < resizeNetSlack(net2); });
+  worst_slack_nets_.clear();
+  for (int i = 0; i < nets.size() * worst_percent; i++)
+    worst_slack_nets_.push_back(nets[i]);
+}
+
+NetSeq &
+Resizer::resizeWorstSlackNets()
+{
+  return worst_slack_nets_;
+}
+
+vector<dbNet*>
+Resizer::resizeWorstSlackDbNets()
+{
+  vector<dbNet*> nets;
+  for (Net* net : worst_slack_nets_)
+    nets.push_back(db_network_->staToDb(net));
+  return nets;
+}
+
+Slack
+Resizer::resizeNetSlack(const Net *net)
+{
+  return net_slack_map_[net];
+}
+
+Slack
+Resizer::resizeNetSlack(const dbNet *db_net)
+{
+  const Net *net = db_network_->dbToSta(db_net);
+  return net_slack_map_[net];
+}
+
+////////////////////////////////////////////////////////////////
+
+double
+Resizer::area(Cell *cell)
+{
+  return area(db_network_->staToDb(cell));
+}
+
+double
+Resizer::area(dbMaster *master)
+{
+  if (!master->isCoreAutoPlaceable()) {
+    return 0;
+  }
+  return dbuToMeters(master->getWidth()) * dbuToMeters(master->getHeight());
+}
+
+double
+Resizer::dbuToMeters(int dist) const
+{
+  int dbu = db_->getTech()->getDbUnitsPerMicron();
+  return dist / (dbu * 1e+6);
+}
+
+int
+Resizer::metersToDbu(double dist) const
+{
+  int dbu = db_->getTech()->getDbUnitsPerMicron();
+  return dist * dbu * 1e+6;
+}
+
+void
+Resizer::setMaxUtilization(double max_utilization)
+{
+  max_area_ = coreArea() * max_utilization;
+}
+
+bool
+Resizer::overMaxArea()
+{
+  return max_area_
+    && fuzzyGreaterEqual(design_area_, max_area_);
+}
+
+void
+Resizer::setDontUse(LibertyCellSeq *dont_use)
+{
+  if (dont_use) {
+    for (LibertyCell *cell : *dont_use)
+      dont_use_.insert(cell);
+  }
+}
+
+bool
+Resizer::dontUse(LibertyCell *cell)
+{
+  return cell->dontUse()
+    || dont_use_.hasKey(cell);
+}
+
+////////////////////////////////////////////////////////////////
+
+// Find a target slew for the libraries and then
+// a target load for each cell that gives the target slew.
+void
+Resizer::findTargetLoads()
+{
+  // Find target slew across all buffers in the libraries.
+  findBufferTargetSlews();
+  if (target_load_map_ == nullptr)
+    target_load_map_ = new CellTargetLoadMap;
+  target_load_map_->clear();
+
+  // Find target loads at the tgt_slew_corner.
+  int lib_ap_index = tgt_slew_corner_->libertyIndex(max_);
+  LibertyLibraryIterator *lib_iter = network_->libertyLibraryIterator();
+  while (lib_iter->hasNext()) {
+    LibertyLibrary *lib = lib_iter->next();
+    LibertyCellIterator cell_iter(lib);
+    while (cell_iter.hasNext()) {
+      LibertyCell *cell = cell_iter.next();
+      if (isLinkCell(cell)) {
+        LibertyCell *corner_cell = cell->cornerCell(lib_ap_index);
+        float tgt_load;
+        bool exists;
+        target_load_map_->findKey(corner_cell, tgt_load, exists);
+        if (!exists) {
+          tgt_load = findTargetLoad(corner_cell);
+          (*target_load_map_)[corner_cell] = tgt_load;
+        }
+        // Map link cell to corner cell target load.
+        if (cell != corner_cell)
+          (*target_load_map_)[cell] = tgt_load;
+      }
+    }
+  }
+  delete lib_iter;
+}
+
+float
+Resizer::targetLoadCap(LibertyCell *cell)
+{
+  float load_cap = 0.0;
+  bool exists;
+  target_load_map_->findKey(cell, load_cap, exists);
+  if (!exists)
+    logger_->error(RSZ, 68, "missing target load cap.");
+  return load_cap;
+}
+
+float
+Resizer::findTargetLoad(LibertyCell *cell)
+{
+  LibertyCellTimingArcSetIterator arc_set_iter(cell);
+  float target_load_sum = 0.0;
+  int arc_count = 0;
+  while (arc_set_iter.hasNext()) {
+    TimingArcSet *arc_set = arc_set_iter.next();
+    TimingRole *role = arc_set->role();
+    if (!role->isTimingCheck()
+        && role != TimingRole::tristateDisable()
+        && role != TimingRole::tristateEnable()) {
+      TimingArcSetArcIterator arc_iter(arc_set);
+      while (arc_iter.hasNext()) {
+        TimingArc *arc = arc_iter.next();
+        int in_rf_index = arc->fromTrans()->asRiseFall()->index();
+        int out_rf_index = arc->toTrans()->asRiseFall()->index();
+        float arc_target_load = findTargetLoad(cell, arc, 
+                                               tgt_slews_[in_rf_index],
+                                               tgt_slews_[out_rf_index]);
+        debugPrint(logger_, RSZ, "target_load", 3, "{} {} -> {} {} target_load = {:.2e}",
+                   cell->name(),
+                   arc->from()->name(),
+                   arc->to()->name(),
+                   arc->toTrans()->asString(),
+                   arc_target_load);
+        target_load_sum += arc_target_load;
+        arc_count++;
+      }
+    }
+  }
+  float target_load = arc_count ? target_load_sum / arc_count : 0.0;
+  debugPrint(logger_, RSZ, "target_load", 2, "{} target_load = {:.2e}",
+             cell->name(),
+             target_load);
+  return target_load;
+}
+
+// Find the load capacitance that will cause the output slew
+// to be equal to out_slew.
+float
+Resizer::findTargetLoad(LibertyCell *cell,
+                        TimingArc *arc,
+                        Slew in_slew,
+                        Slew out_slew)
+{
+  GateTimingModel *model = dynamic_cast<GateTimingModel*>(arc->model());
+  if (model) {
+    // load_cap1 lower bound
+    // load_cap2 upper bound
+    double load_cap1 = 0.0;
+    double load_cap2 = 1.0e-12;  // 1pF
+    double tol = .01; // 1%
+    double diff1 = gateSlewDiff(cell, arc, model, in_slew, load_cap1, out_slew);
+    if (diff1 > 0.0)
+      // Zero load cap out_slew is higher than the target.
+      return 0.0;
+    double diff2 = gateSlewDiff(cell, arc, model, in_slew, load_cap2, out_slew);
+    // binary search for diff = 0.
+    while (abs(load_cap1 - load_cap2) > max(load_cap1, load_cap2) * tol) {
+      if (diff2 < 0.0) {
+        load_cap1 = load_cap2;
+        diff1 = diff2;
+        load_cap2 *= 2;
+        diff2 = gateSlewDiff(cell, arc, model, in_slew, load_cap2, out_slew);
+      }
+      else {
+        double load_cap3 = (load_cap1 + load_cap2) / 2.0;
+        double diff3 = gateSlewDiff(cell, arc, model, in_slew, load_cap3, out_slew);
+        if (diff3 < 0.0) {
+          load_cap1 = load_cap3;
+          diff1 = diff3;
+        }
+        else {
+          load_cap2 = load_cap3;
+          diff2 = diff3;
+        }
+      }
+    }
+    return load_cap1;
+  }
+  return 0.0;
+}
+
+// objective function
+Slew
+Resizer::gateSlewDiff(LibertyCell *cell,
+                      TimingArc *arc,
+                      GateTimingModel *model,
+                      Slew in_slew,
+                      float load_cap,
+                      Slew out_slew)
+
+{
+  const Pvt *pvt = tgt_slew_dcalc_ap_->operatingConditions();
+  ArcDelay arc_delay;
+  Slew arc_slew;
+  model->gateDelay(cell, pvt, in_slew, load_cap, 0.0, false,
+                   arc_delay, arc_slew);
+  return arc_slew - out_slew;
+}
+
+////////////////////////////////////////////////////////////////
+
+Slew
+Resizer::targetSlew(const RiseFall *rf)
+{
+  return tgt_slews_[rf->index()];
+}
+
+// Find target slew across all buffers in the libraries.
+void
+Resizer::findBufferTargetSlews()
+{
+  tgt_slews_ = {0.0};
+  tgt_slew_corner_ = nullptr;
+  
+  for (Corner *corner : *sta_->corners()) {
+    int lib_ap_index = corner->libertyIndex(max_);
+    const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(max_);
+    const Pvt *pvt = dcalc_ap->operatingConditions();
+    // Average slews across buffers at corner.
+    Slew slews[RiseFall::index_count]{0.0};
+    int counts[RiseFall::index_count]{0};
+    for (LibertyCell *buffer : buffer_cells_) {
+      LibertyCell *corner_buffer = buffer->cornerCell(lib_ap_index);
+      findBufferTargetSlews(corner_buffer, pvt, slews, counts);
+    }
+    Slew slew_rise = slews[RiseFall::riseIndex()] / counts[RiseFall::riseIndex()];
+    Slew slew_fall = slews[RiseFall::fallIndex()] / counts[RiseFall::fallIndex()];
+    // Use the target slews from the slowest corner,
+    // and resize using that corner.
+    if (slew_rise > tgt_slews_[RiseFall::riseIndex()]) {
+      tgt_slews_[RiseFall::riseIndex()] = slew_rise;
+      tgt_slews_[RiseFall::fallIndex()] = slew_fall;
+      tgt_slew_corner_ = corner;
+      tgt_slew_dcalc_ap_ = corner->findDcalcAnalysisPt(max_);
+    }
+  }
+
+  debugPrint(logger_, RSZ, "target_load", 1, "target slew corner {} = {}/{}",
+             tgt_slew_corner_->name(),
+             delayAsString(tgt_slews_[RiseFall::riseIndex()], sta_, 3),
+             delayAsString(tgt_slews_[RiseFall::fallIndex()], sta_, 3));
+}
+
+void
+Resizer::findBufferTargetSlews(LibertyCell *buffer,
+                               const Pvt *pvt,
+                               // Return values.
+                               Slew slews[],
+                               int counts[])
+{
+  LibertyPort *input, *output;
+  buffer->bufferPorts(input, output);
+  TimingArcSetSeq *arc_sets = buffer->timingArcSets(input, output);
+  if (arc_sets) {
+    for (TimingArcSet *arc_set : *arc_sets) {
+      TimingArcSetArcIterator arc_iter(arc_set);
+      while (arc_iter.hasNext()) {
+        TimingArc *arc = arc_iter.next();
+        GateTimingModel *model = dynamic_cast<GateTimingModel*>(arc->model());
+        RiseFall *in_rf = arc->fromTrans()->asRiseFall();
+        RiseFall *out_rf = arc->toTrans()->asRiseFall();
+        float in_cap = input->capacitance(in_rf, max_);
+        float load_cap = in_cap * tgt_slew_load_cap_factor;
+        ArcDelay arc_delay;
+        Slew arc_slew;
+        model->gateDelay(buffer, pvt, 0.0, load_cap, 0.0, false,
+                         arc_delay, arc_slew);
+        model->gateDelay(buffer, pvt, arc_slew, load_cap, 0.0, false,
+                         arc_delay, arc_slew);
+        slews[out_rf->index()] += arc_slew;
+        counts[out_rf->index()]++;
+      }
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+// Repair tie hi/low net driver fanout by duplicating the
+// tie hi/low instances for every pin connected to tie hi/low instances.
+void
+Resizer::repairTieFanout(LibertyPort *tie_port,
+                         double separation, // meters
+                         bool verbose)
+{
+  ensureBlock();
+  ensureDesignArea();
+  Instance *top_inst = network_->topInstance();
+  LibertyCell *tie_cell = tie_port->libertyCell();
+  InstanceSeq insts;
+  findCellInstances(tie_cell, insts);
+  int tie_count = 0;
+  int separation_dbu = metersToDbu(separation);
+  for (Instance *inst : insts) {
+    Pin *drvr_pin = network_->findPin(inst, tie_port);
+    if (drvr_pin) {
+      const char *inst_name = network_->name(inst);
+      Net *net = network_->net(drvr_pin);
+      if (net) {
+        NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(net);
+        while (pin_iter->hasNext()) {
+          Pin *load = pin_iter->next();
+          if (load != drvr_pin) {
+            // Make tie inst.
+            Point tie_loc = tieLocation(load, separation_dbu);
+            Instance *load_inst = network_->instance(load);
+            string tie_name = makeUniqueInstName(inst_name, true);
+            Instance *tie = makeInstance(tie_cell, tie_name.c_str(),
+                                         top_inst);
+            setLocation(tie, tie_loc);
+
+            // Make tie output net.
+            Net *load_net = makeUniqueNet();
+
+            // Connect tie inst output.
+            sta_->connectPin(tie, tie_port, load_net);
+
+            // Connect load to tie output net.
+            sta_->disconnectPin(load);
+            Port *load_port = network_->port(load);
+            sta_->connectPin(load_inst, load_port, load_net);
+
+            designAreaIncr(area(db_network_->cell(tie_cell)));
+            tie_count++;
+          }
+        }
+        delete pin_iter;
+
+        // Delete inst output net.
+        Pin *tie_pin = network_->findPin(inst, tie_port);
+        Net *tie_net = network_->net(tie_pin);
+        sta_->deleteNet(tie_net);
+        parasitics_invalid_.erase(tie_net);
+        // Delete the tie instance.
+        sta_->deleteInstance(inst);
+      }
+    }
+  }
+
+  if (tie_count > 0) {
+    logger_->info(RSZ, 42, "Inserted {} tie {} instances.",
+                  tie_count,
+                  tie_cell->name());
+    level_drvr_vertices_valid_ = false;
+  }
+}
+
+void
+Resizer::findCellInstances(LibertyCell *cell,
+                           // Return value.
+                           InstanceSeq &insts)
+{
+  LeafInstanceIterator *inst_iter = network_->leafInstanceIterator();
+  while (inst_iter->hasNext()) {
+    Instance *inst = inst_iter->next();
+    if (network_->libertyCell(inst) == cell)
+      insts.push_back(inst);
+  }
+  delete inst_iter;
+}
+
+// Place the tie instance on the side of the load pin.
+Point
+Resizer::tieLocation(Pin *load,
+                     int separation)
+{
+  Point load_loc = db_network_->location(load);
+  int load_x = load_loc.getX();
+  int load_y = load_loc.getY();
+  int tie_x = load_x;
+  int tie_y = load_y;
+  if (!network_->isTopLevelPort(load)) {
+    dbInst *db_inst = db_network_->staToDb(network_->instance(load));
+    dbBox *bbox = db_inst->getBBox();
+    int left_dist = abs(load_x - bbox->xMin());
+    int right_dist = abs(load_x - bbox->xMax());
+    int bot_dist = abs(load_y - bbox->yMin());
+    int top_dist = abs(load_y - bbox->yMax());
+    if (left_dist < right_dist
+        && left_dist < bot_dist
+        && left_dist < top_dist)
+      // left
+      tie_x -= separation;
+    if (right_dist < left_dist
+        && right_dist < bot_dist
+        && right_dist < top_dist)
+      // right
+      tie_x += separation;
+    if (bot_dist < left_dist
+        && bot_dist < right_dist
+        && bot_dist < top_dist)
+      // bot
+      tie_y -= separation;
+    if (top_dist < left_dist
+        && top_dist < right_dist
+        && top_dist < bot_dist)
+      // top
+      tie_y += separation;
+  }
+  return Point(tie_x, tie_y);
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::repairSetup(float slack_margin,
+                     int max_passes)
+{
+  inserted_buffer_count_ = 0;
+  resize_count_ = 0;
+  Slack worst_slack;
+  Vertex *worst_vertex;
+  sta_->worstSlack(max_, worst_slack, worst_vertex);
+  debugPrint(logger_, RSZ, "repair_setup", 1, "worst_slack = {}",
+             delayAsString(worst_slack, sta_, 3));
+  Slack prev_worst_slack = -INF;
+  int pass = 1;
+  int decreasing_slack_passes = 0;
+  incrementalParasiticsBegin();
+  while (fuzzyLess(worst_slack, slack_margin)
+         && pass <= max_passes) {
+    PathRef worst_path = sta_->vertexWorstSlackPath(worst_vertex, max_);
+    bool changed = repairSetup(worst_path, worst_slack);
+    updateParasitics();
+    sta_->findRequireds();
+    sta_->worstSlack(max_, worst_slack, worst_vertex);
+    bool decreasing_slack = fuzzyLessEqual(worst_slack, prev_worst_slack);
+    debugPrint(logger_, RSZ, "repair_setup", 1, "pass {} worst_slack = {} {}",
+               pass,
+               delayAsString(worst_slack, sta_, 3),
+               decreasing_slack ? "v" : "^");
+    if (decreasing_slack) {
+      // Allow slack to increase to get out of local minima.
+      // Do not update prev_worst_slack so it saves the high water mark.
+      decreasing_slack_passes++;
+      if (!changed
+          || decreasing_slack_passes > repair_setup_decreasing_slack_passes_allowed_) {
+        // Undo changes that reduced slack.
+        journalRestore();
+        debugPrint(logger_, RSZ, "repair_setup", 1,
+                   "decreasing slack for {} passes. Restoring best slack {}",
+                   decreasing_slack_passes,
+                   delayAsString(prev_worst_slack, sta_, 3));
+        break;
+      }
+    }
+    else {
+      prev_worst_slack = worst_slack;
+      decreasing_slack_passes = 0;
+      // Progress, start journal so we can back up to here.
+      journalBegin();
+    }
+    if (overMaxArea())
+      break;
+    pass++;
+  }
+  // Leave the parasitics up to date.
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (inserted_buffer_count_ > 0)
+    logger_->info(RSZ, 40, "Inserted {} buffers.", inserted_buffer_count_);
+  if (resize_count_ > 0)
+    logger_->info(RSZ, 41, "Resized {} instances.", resize_count_);
+  if (fuzzyLess(worst_slack, slack_margin))
+    logger_->warn(RSZ, 62, "Unable to repair all setup violations.");
+  if (overMaxArea())
+    logger_->error(RSZ, 25, "max utilization reached.");
+}
+
+// For testing.
+void
+Resizer::repairSetup(Pin *end_pin)
+{
+  inserted_buffer_count_ = 0;
+  resize_count_ = 0;
+  Vertex *vertex = graph_->pinLoadVertex(end_pin);
+  Slack slack = sta_->vertexSlack(vertex, max_);
+  PathRef path = sta_->vertexWorstSlackPath(vertex, max_);
+  incrementalParasiticsBegin();
+  repairSetup(path, slack);
+  // Leave the parasitices up to date.
+  updateParasitics();
+  incrementalParasiticsEnd();
+
+  if (inserted_buffer_count_ > 0)
+    logger_->info(RSZ, 30, "Inserted {} buffers.", inserted_buffer_count_);
+  if (resize_count_ > 0)
+    logger_->info(RSZ, 31, "Resized {} instances.", resize_count_);
+}
+
+bool
+Resizer::repairSetup(PathRef &path,
+                     Slack path_slack)
+{
+  PathExpanded expanded(&path, sta_);
+  bool changed = false;
+  if (expanded.size() > 1) {
+    int path_length = expanded.size();
+    vector<pair<int, Delay>> load_delays;
+    int start_index = expanded.startIndex();
+    const DcalcAnalysisPt *dcalc_ap = path.dcalcAnalysisPt(sta_);
+    int lib_ap = dcalc_ap->libertyIndex();
+    // Find load delay for each gate in the path.
+    for (int i = start_index; i < path_length; i++) {
+      PathRef *path = expanded.path(i);
+      Vertex *path_vertex = path->vertex(sta_);
+      const Pin *path_pin = path->pin(sta_);
+      if (network_->isDriver(path_pin)
+          && !network_->isTopLevelPort(path_pin)) {
+        TimingArc *prev_arc = expanded.prevArc(i);
+        TimingArc *corner_arc = prev_arc->cornerArc(lib_ap);
+        Edge *prev_edge = path->prevEdge(prev_arc, sta_);
+        Delay load_delay = graph_->arcDelay(prev_edge, prev_arc, dcalc_ap->index())
+          // Remove intrinsic delay to find load dependent delay.
+          - corner_arc->intrinsicDelay();
+        load_delays.push_back(pair(i, load_delay));
+        debugPrint(logger_, RSZ, "repair_setup", 3, "{} load_delay = {}",
+                   path_vertex->name(network_),
+                   delayAsString(load_delay, sta_, 3));
+      }
+    }
+
+    sort(load_delays.begin(), load_delays.end(),
+         [](pair<int, Delay> pair1,
+            pair<int, Delay> pair2) {
+           return pair1.second > pair2.second;
+         });
+    // Attack gates with largest load delays first.
+    for (auto index_delay : load_delays) {
+      int drvr_index = index_delay.first;
+      PathRef *drvr_path = expanded.path(drvr_index);
+      Vertex *drvr_vertex = drvr_path->vertex(sta_);
+      const Pin *drvr_pin = drvr_vertex->pin();
+      LibertyPort *drvr_port = network_->libertyPort(drvr_pin);
+      LibertyCell *drvr_cell = drvr_port ? drvr_port->libertyCell() : nullptr;
+      int fanout = this->fanout(drvr_vertex);
+      debugPrint(logger_, RSZ, "repair_setup", 2, "{} {} fanout = {}",
+                 network_->pathName(drvr_pin),
+                 drvr_cell ? drvr_cell->name() : "none",
+                 fanout);
+
+      if (upsizeDrvr(drvr_path, drvr_index, &expanded)) {
+        changed = true;
+        break;
+      }
+
+      // For tristate nets all we can do is resize the driver.
+      bool tristate_drvr = isTristateDriver(drvr_pin);
+      if (fanout > 1
+          // Rebuffer blows up on large fanout nets.
+          && fanout < rebuffer_max_fanout_
+          && !tristate_drvr) { 
+        int rebuffer_count = rebuffer(drvr_pin);
+        if (rebuffer_count > 0) {
+          debugPrint(logger_, RSZ, "repair_setup", 2, "rebuffer {} inserted {}",
+                     network_->pathName(drvr_pin),
+                     rebuffer_count);
+          changed = true;
+          break;
+        }
+      }
+
+      // Don't split loads on low fanout nets.
+      if (fanout > split_load_min_fanout_
+          && !tristate_drvr) {
+        splitLoads(drvr_path, drvr_index, path_slack, &expanded);
+        changed = true;
+        break;
+      }
+    }
+  }
+  return changed;
+}
+
+bool
+Resizer::upsizeDrvr(PathRef *drvr_path,
+                    int drvr_index,
+                    PathExpanded *expanded)
+{
+  Pin *drvr_pin = drvr_path->pin(this);
+  const DcalcAnalysisPt *dcalc_ap = drvr_path->dcalcAnalysisPt(sta_);
+  float load_cap = graph_delay_calc_->loadCap(drvr_pin, dcalc_ap);
+  int in_index = drvr_index - 1;
+  PathRef *in_path = expanded->path(in_index);
+  Pin *in_pin = in_path->pin(sta_);
+  LibertyPort *in_port = network_->libertyPort(in_pin);
+
+  float prev_drive;
+  if (drvr_index >= 2) {
+    int prev_drvr_index = drvr_index - 2;
+    PathRef *prev_drvr_path = expanded->path(prev_drvr_index);
+    Pin *prev_drvr_pin = prev_drvr_path->pin(sta_);
+    prev_drive = 0.0;
+    LibertyPort *prev_drvr_port = network_->libertyPort(prev_drvr_pin);
+    if (prev_drvr_port) {
+      prev_drive = prev_drvr_port->driveResistance();
+    }
+  }
+  else
+    prev_drive = 0.0;
+  LibertyPort *drvr_port = network_->libertyPort(drvr_pin);
+  LibertyCell *upsize = upsizeCell(in_port, drvr_port, load_cap,
+                                   prev_drive, dcalc_ap);
+  if (upsize) {
+    Instance *drvr = network_->instance(drvr_pin);
+    debugPrint(logger_, RSZ, "repair_setup", 2, "resize {} {} -> {}",
+               network_->pathName(drvr_pin),
+               drvr_port->libertyCell()->name(),
+               upsize->name());
+    if (replaceCell(drvr, upsize, true)) {
+      resize_count_++;
+      return true;
+    }
+  }
+  return false;
+}
+
+LibertyCell *
+Resizer::upsizeCell(LibertyPort *in_port,
+                    LibertyPort *drvr_port,
+                    float load_cap,
+                    float prev_drive,
+                    const DcalcAnalysisPt *dcalc_ap)
+{
+  int lib_ap = dcalc_ap->libertyIndex();
+  LibertyCell *cell = drvr_port->libertyCell();
+  LibertyCellSeq *equiv_cells = sta_->equivCells(cell);
+  if (equiv_cells) {
+    const char *in_port_name = in_port->name();
+    const char *drvr_port_name = drvr_port->name();
+    sort(equiv_cells,
+         [=] (const LibertyCell *cell1,
+              const LibertyCell *cell2) {
+           LibertyPort *port1=cell1->findLibertyPort(drvr_port_name)->cornerPort(lib_ap);
+           LibertyPort *port2=cell2->findLibertyPort(drvr_port_name)->cornerPort(lib_ap);
+           return port1->driveResistance() > port2->driveResistance();
+         });
+    float drive = drvr_port->cornerPort(lib_ap)->driveResistance();
+    float delay = gateDelay(drvr_port, load_cap, tgt_slew_dcalc_ap_)
+      + prev_drive * in_port->cornerPort(lib_ap)->capacitance();
+    for (LibertyCell *equiv : *equiv_cells) {
+      LibertyCell *equiv_corner = equiv->cornerCell(lib_ap);
+      LibertyPort *equiv_drvr = equiv_corner->findLibertyPort(drvr_port_name);
+      LibertyPort *equiv_input = equiv_corner->findLibertyPort(in_port_name);
+      float equiv_drive = equiv_drvr->driveResistance();
+      // Include delay of previous driver into equiv gate.
+      float equiv_delay = gateDelay(equiv_drvr, load_cap, dcalc_ap)
+        + prev_drive * equiv_input->capacitance();
+      if (!dontUse(equiv)
+          && equiv_drive < drive
+          && equiv_delay < delay)
+        return equiv;
+    }
+  }
+  return nullptr;
+}
+
+void
+Resizer::splitLoads(PathRef *drvr_path,
+                    int drvr_index,
+                    Slack drvr_slack,
+                    PathExpanded *expanded)
+{
+  Pin *drvr_pin = drvr_path->pin(this);
+  PathRef *load_path = expanded->path(drvr_index + 1);
+  Vertex *load_vertex = load_path->vertex(sta_);
+  Pin *load_pin = load_vertex->pin();
+  // Divide and conquer.
+  debugPrint(logger_, RSZ, "repair_setup", 2, "split loads {} -> {}",
+             network_->pathName(drvr_pin),
+             network_->pathName(load_pin));
+
+  Vertex *drvr_vertex = drvr_path->vertex(sta_);
+  const RiseFall *rf = drvr_path->transition(sta_);
+  // Sort fanouts of the drvr on the critical path by slack margin
+  // wrt the critical path slack.
+  vector<pair<Vertex*, Slack>> fanout_slacks;
+  VertexOutEdgeIterator edge_iter(drvr_vertex, graph_);
+  while (edge_iter.hasNext()) {
+    Edge *edge = edge_iter.next();
+    Vertex *fanout_vertex = edge->to(graph_);
+    Slack fanout_slack = sta_->vertexSlack(fanout_vertex, rf, max_);
+    Slack slack_margin = fanout_slack - drvr_slack;
+    debugPrint(logger_, RSZ, "repair_setup", 3, " fanin {} slack_margin = {}",
+               network_->pathName(fanout_vertex->pin()),
+               delayAsString(slack_margin, sta_, 3));
+    fanout_slacks.push_back(pair<Vertex*, Slack>(fanout_vertex, slack_margin));
+  }
+
+  sort(fanout_slacks.begin(), fanout_slacks.end(),
+       [](pair<Vertex*, Slack> pair1,
+          pair<Vertex*, Slack> pair2) {
+         return pair1.second > pair2.second;
+       });
+
+  Net *net = network_->net(drvr_pin);
+
+  string buffer_name = makeUniqueInstName("split");
+  Instance *parent = db_network_->topInstance();
+  LibertyCell *buffer_cell = buffer_lowest_drive_;
+  Instance *buffer = makeInstance(buffer_cell,
+                                  buffer_name.c_str(),
+                                  parent);
+  journalMakeBuffer(buffer);
+  inserted_buffer_count_++;
+  designAreaIncr(area(db_network_->cell(buffer_cell)));
+
+  Net *out_net = makeUniqueNet();
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  Point drvr_loc = db_network_->location(drvr_pin);
+  setLocation(buffer, drvr_loc);
+
+  // Split the loads with extra slack to an inserted buffer.
+  // before
+  // drvr_pin -> net -> load_pins
+  // after
+  // drvr_pin -> net -> load_pins with low slack
+  //                 -> buffer_in -> net -> rest of loads
+  sta_->connectPin(buffer, input, net);
+  parasiticsInvalid(net);
+  sta_->connectPin(buffer, output, out_net);
+  int split_index = fanout_slacks.size() / 2;
+  for (int i = 0; i < split_index; i++) {
+    pair<Vertex*, Slack> fanout_slack = fanout_slacks[i];
+    Vertex *load_vertex = fanout_slack.first;
+    Pin *load_pin = load_vertex->pin();
+    // Leave ports connected to original net so verilog port names are preserved.
+    if (!network_->isTopLevelPort(load_pin)) {
+      LibertyPort *load_port = network_->libertyPort(load_pin);
+      Instance *load = network_->instance(load_pin);
+
+      sta_->disconnectPin(load_pin);
+      sta_->connectPin(load, load_port, out_net);
+    }
+  }
+  Pin *buffer_out_pin = network_->findPin(buffer, output);
+  resizeToTargetSlew(buffer_out_pin, false);
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::repairHold(float slack_margin,
+                    bool allow_setup_violations,
+                    // Max buffer count as percent of design instance count.
+                    float max_buffer_percent)
+{
+  init();
+  LibertyCell *buffer_cell = findHoldBuffer();
+  sta_->findRequireds();
+  VertexSet *ends = sta_->search()->endpoints();
+  int max_buffer_count = max_buffer_percent * network_->instanceCount();
+  incrementalParasiticsBegin();
+  repairHold(ends, buffer_cell, slack_margin,
+             allow_setup_violations, max_buffer_count);
+
+  // Leave the parasitices up to date.
+  updateParasitics();
+  incrementalParasiticsEnd();
+}
+
+// For testing/debug.
+void
+Resizer::repairHold(Pin *end_pin,
+                    LibertyCell *buffer_cell,
+                    float slack_margin,
+                    bool allow_setup_violations,
+                    float max_buffer_percent)
+{
+  Vertex *end = graph_->pinLoadVertex(end_pin);
+  VertexSet ends;
+  ends.insert(end);
+
+  init();
+  sta_->findRequireds();
+  int max_buffer_count = max_buffer_percent * network_->instanceCount();
+  incrementalParasiticsBegin();
+  repairHold(&ends, buffer_cell, slack_margin, allow_setup_violations,
+             max_buffer_count);
+  // Leave the parasitices up to date.
+  updateParasitics();
+  incrementalParasiticsEnd();
+}
+
+// Find the buffer with the most delay in the fastest corner.
+LibertyCell *
+Resizer::findHoldBuffer()
+{
+  LibertyCell *max_buffer = nullptr;
+  float max_delay = 0.0;
+  for (LibertyCell *buffer : buffer_cells_) {
+    float buffer_min_delay = bufferHoldDelay(buffer);
+    if (max_buffer == nullptr
+        || buffer_min_delay > max_delay) {
+      max_buffer = buffer;
+      max_delay = buffer_min_delay;
+    }
+  }
+  return max_buffer;
+}
+
+float
+Resizer::bufferHoldDelay(LibertyCell *buffer)
+{
+  Delay delays[RiseFall::index_count];
+  bufferHoldDelays(buffer, delays);
+  return min(delays[RiseFall::riseIndex()],
+             delays[RiseFall::fallIndex()]);
+}
+
+// Min self delay across corners; buffer -> buffer
+void
+Resizer::bufferHoldDelays(LibertyCell *buffer,
+                          // Return values.
+                          Delay delays[RiseFall::index_count])
+{
+  LibertyPort *input, *output;
+  buffer->bufferPorts(input, output);
+
+  for (int rf_index : RiseFall::rangeIndex())
+    delays[rf_index] = MinMax::min()->initValue();
+  for (Corner *corner : *sta_->corners()) {
+    LibertyPort *corner_port = input->cornerPort(corner->libertyIndex(max_));
+    const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(max_);
+    float load_cap = corner_port->capacitance();
+    ArcDelay gate_delays[RiseFall::index_count];
+    Slew slews[RiseFall::index_count];
+    gateDelays(output, load_cap, dcalc_ap, gate_delays, slews);
+    for (int rf_index : RiseFall::rangeIndex())
+      delays[rf_index] = min(delays[rf_index], gate_delays[rf_index]);
+  }
+}
+
+void
+Resizer::repairHold(VertexSet *ends,
+                    LibertyCell *buffer_cell,
+                    float slack_margin,
+                    bool allow_setup_violations,
+                    int max_buffer_count)
+{
+  // Find endpoints with hold violation.
+  VertexSet hold_failures;
+  Slack worst_slack;
+  findHoldViolations(ends, slack_margin, worst_slack, hold_failures);
+  if (!hold_failures.empty()) {
+    logger_->info(RSZ, 46, "Found {} endpoints with hold violations.",
+                  hold_failures.size());
+    inserted_buffer_count_ = 0;
+    int repair_count = 1;
+    int pass = 1;
+    while (!hold_failures.empty()
+           // Make sure we are making progress.
+           && repair_count > 0
+           && !overMaxArea()
+           && inserted_buffer_count_ <= max_buffer_count) {
+      repair_count = repairHoldPass(hold_failures, buffer_cell, slack_margin,
+                                    allow_setup_violations, max_buffer_count);
+      debugPrint(logger_, RSZ, "repair_hold", 1,
+                 "pass {} worst slack {} failures {} inserted {}",
+                 pass,
+                 delayAsString(worst_slack, sta_, 3),
+                 hold_failures .size(),
+                 repair_count);
+      sta_->findRequireds();
+      findHoldViolations(ends, slack_margin, worst_slack, hold_failures);
+      pass++;
+    }
+    if (slack_margin == 0.0 && fuzzyLess(worst_slack, 0.0))
+      logger_->warn(RSZ, 66, "Unable to repair all hold violations.");
+    else if (fuzzyLess(worst_slack, slack_margin))
+      logger_->warn(RSZ, 64, "Unable to repair all hold checks within margin.");
+
+    if (inserted_buffer_count_ > 0) {
+      logger_->info(RSZ, 32, "Inserted {} hold buffers.", inserted_buffer_count_);
+      level_drvr_vertices_valid_ = false;
+    }
+    if (inserted_buffer_count_ > max_buffer_count)
+      logger_->error(RSZ, 60, "Max buffer count reached.");
+    if (overMaxArea())
+      logger_->error(RSZ, 50, "Max utilization reached.");
+  }
+  else
+    logger_->info(RSZ, 33, "No hold violations found.");
+}
+
+void
+Resizer::findHoldViolations(VertexSet *ends,
+                            float slack_margin,
+                            // Return values.
+                            Slack &worst_slack,
+                            VertexSet &hold_violations)
+{
+  worst_slack = INF;
+  hold_violations.clear();
+  debugPrint(logger_, RSZ, "repair_hold", 3, "Hold violations");
+  for (Vertex *end : *ends) {
+    Slack slack = sta_->vertexSlack(end, MinMax::min());
+    if (!sta_->isClock(end->pin())
+        && fuzzyLess(slack, slack_margin)) {
+      debugPrint(logger_, RSZ, "repair_hold", 3, " {}",
+                 end->name(sdc_network_));
+      if (slack < worst_slack)
+        worst_slack = slack;
+      hold_violations.insert(end);
+    }
+  }
+}
+
+int
+Resizer::repairHoldPass(VertexSet &hold_failures,
+                        LibertyCell *buffer_cell,
+                        float slack_margin,
+                        bool allow_setup_violations,
+                        int max_buffer_count)
+{
+  VertexSet fanins = findHoldFanins(hold_failures);
+  VertexSeq sorted_fanins = sortHoldFanins(fanins);
+  
+  int repair_count = 0;
+  int max_repair_count = max(static_cast<int>(hold_failures.size() * .2), 10);
+  for(int i = 0; i < sorted_fanins.size() && repair_count < max_repair_count ; i++) {
+    Vertex *vertex = sorted_fanins[i];
+    Pin *drvr_pin = vertex->pin();
+    Net *net = network_->isTopLevelPort(drvr_pin)
+      ? network_->net(network_->term(drvr_pin))
+      : network_->net(drvr_pin);
+    updateParasitics();
+    Slack drvr_slacks[RiseFall::index_count][MinMax::index_count];
+    sta_->vertexSlacks(vertex, drvr_slacks);
+    int min_index = MinMax::minIndex();
+    int max_index = MinMax::maxIndex();
+    const RiseFall *drvr_rf = (drvr_slacks[RiseFall::riseIndex()][min_index] <
+                               drvr_slacks[RiseFall::fallIndex()][min_index])
+      ? RiseFall::rise()
+      : RiseFall::fall();
+    Slack drvr_hold_slack = drvr_slacks[drvr_rf->index()][min_index] - slack_margin;
+    Slack drvr_setup_slack = drvr_slacks[drvr_rf->index()][max_index];
+    if (!vertex->isConstant()
+        && fuzzyLess(drvr_hold_slack, 0.0)
+        // Hands off special nets.
+        && !db_network_->isSpecial(net)
+        && !isTristateDriver(drvr_pin)
+        // Have to have enough setup slack to add delay to repair the hold violation.
+        && (allow_setup_violations
+            || fuzzyLess(drvr_hold_slack, drvr_setup_slack))) {
+      debugPrint(logger_, RSZ, "repair_hold", 2, "driver {}",
+                 vertex->name(sdc_network_));
+      // Only add delay to loads with hold violations.
+      PinSeq load_pins;
+      float load_cap = 0.0;
+      bool loads_have_out_port = false;
+      VertexOutEdgeIterator edge_iter(vertex, graph_);
+      while (edge_iter.hasNext()) {
+        Edge *edge = edge_iter.next();
+        Vertex *fanout = edge->to(graph_);
+        Slack fanout_slack = sta_->vertexSlack(fanout, MinMax::min());
+        if (fanout_slack < slack_margin) {
+          Pin *fanout_pin = fanout->pin();
+          load_pins.push_back(fanout_pin);
+          if (network_->direction(fanout_pin)->isAnyOutput()
+              && network_->isTopLevelPort(fanout_pin))
+            loads_have_out_port = true;
+          else {
+            LibertyPort *fanout_port = network_->libertyPort(fanout_pin);
+            if (fanout_port)
+              load_cap += fanout_port->capacitance();
+          }
+        }
+      }
+      if (!load_pins.empty()) {
+        // multi-corner support MIA
+        const DcalcAnalysisPt *dcalc_ap = sta_->cmdCorner()->findDcalcAnalysisPt(max_);
+        Delay buffer_delay1 = bufferDelay(buffer_cell, drvr_rf, load_cap, dcalc_ap);
+        // Need enough slack to at least insert the last buffer with loads.
+        if (allow_setup_violations
+            || (buffer_delay1 < drvr_slacks[RiseFall::riseIndex()][max_index]
+                && buffer_delay1 < drvr_slacks[RiseFall::fallIndex()][max_index])) {
+          Delay buffer_delay = bufferHoldDelay(buffer_cell);
+          Delay max_insert = min(drvr_slacks[RiseFall::riseIndex()][max_index],
+                                 drvr_slacks[RiseFall::fallIndex()][max_index]);
+          int max_insert_count = delayInf(max_insert)
+            ? 1
+            : (max_insert - buffer_delay1) / buffer_delay + 1;
+          int hold_buffer_count = (-drvr_hold_slack > buffer_delay1)
+            ? std::ceil((-drvr_hold_slack-buffer_delay1)/buffer_delay)+1
+            : 1;
+          int buffer_count = allow_setup_violations
+            ? hold_buffer_count
+            : min(max_insert_count, hold_buffer_count);
+          debugPrint(logger_, RSZ, "repair_hold", 2,
+                     " {} hold={} inserted {} for {}/{} loads",
+                     vertex->name(sdc_network_),
+                     delayAsString(drvr_hold_slack, this, 3),
+                     buffer_count,
+                     load_pins.size(),
+                     fanout(vertex));
+          makeHoldDelay(vertex, buffer_count, load_pins,
+                        loads_have_out_port, buffer_cell);
+          repair_count += buffer_count;
+          if (logger_->debugCheck(RSZ, "repair_hold", 4)) {
+            // Check that no setup violations are introduced.
+            updateParasitics();
+            Slack drvr_setup_slack1 = sta_->vertexSlack(vertex, max_);
+            if (drvr_setup_slack1 < 0
+                && drvr_setup_slack1 < drvr_setup_slack)
+              printf("%s %s -> %s\n", vertex->name(network_),
+                     delayAsString(drvr_setup_slack, sta_, 3),
+                     delayAsString(drvr_setup_slack1, sta_, 3));
+          }
+          if (inserted_buffer_count_ > max_buffer_count
+              || overMaxArea())
+            return repair_count;
+        }
+      }
+    }
+  }
+  return repair_count;
+}
+
+VertexSet
+Resizer::findHoldFanins(VertexSet &ends)
+{
+  SearchPredNonReg2 pred(sta_);
+  BfsBkwdIterator iter(BfsIndex::other, &pred, this);
+  for (Vertex *vertex : ends)
+    iter.enqueueAdjacentVertices(vertex);
+
+  VertexSet fanins;
+  while (iter.hasNext()) {
+    Vertex *fanin = iter.next();
+    if (!sta_->isClock(fanin->pin())) {
+      if (fanin->isDriver(network_))
+        fanins.insert(fanin);
+      iter.enqueueAdjacentVertices(fanin);
+    }
+  }
+  return fanins;
+}
+
+VertexSeq
+Resizer::sortHoldFanins(VertexSet &fanins)
+{
+  VertexSeq sorted_fanins;
+  for(Vertex *vertex : fanins)
+    sorted_fanins.push_back(vertex);
+
+  sort(sorted_fanins, [&](Vertex *v1, Vertex *v2)
+                      { float s1 = sta_->vertexSlack(v1, MinMax::min());
+                        float s2 = sta_->vertexSlack(v2, MinMax::min());
+                        if (fuzzyEqual(s1, s2)) {
+                          float gap1 = slackGap(v1);
+                          float gap2 = slackGap(v2);
+                          // Break ties based on the hold/setup gap.
+                          if (fuzzyEqual(gap1, gap2))
+                            return v1->level() > v2->level();
+                          else
+                            return gap1 > gap2;
+                        }
+                        else
+                          return s1 < s2;});
+  if (logger_->debugCheck(RSZ, "repair_hold", 4)) {
+    printf("Sorted fanins");
+    printf("     hold_slack  slack_gap  level");
+    for(Vertex *vertex : sorted_fanins)
+      printf("%s %s %s %d",
+             vertex->name(network_),
+             delayAsString(sta_->vertexSlack(vertex, MinMax::min()), sta_, 3),
+             delayAsString(slackGap(vertex), sta_, 3),
+             vertex->level());
+  }
+  return sorted_fanins;
+}
+
+void
+Resizer::makeHoldDelay(Vertex *drvr,
+                       int buffer_count,
+                       PinSeq &load_pins,
+                       bool loads_have_out_port,
+                       LibertyCell *buffer_cell)
+{
+  Pin *drvr_pin = drvr->pin();
+  Instance *parent = db_network_->topInstance();
+  Net *drvr_net = network_->isTopLevelPort(drvr_pin)
+    ? db_network_->net(db_network_->term(drvr_pin))
+    : db_network_->net(drvr_pin);
+  Net *in_net, *out_net;
+  if (loads_have_out_port) {
+    // Verilog uses nets as ports, so the net connected to an output port has
+    // to be preserved.
+    // Move the driver pin over to gensym'd net.
+    in_net = makeUniqueNet();
+    Port *drvr_port = network_->port(drvr_pin);
+    Instance *drvr_inst = network_->instance(drvr_pin);
+    sta_->disconnectPin(drvr_pin);
+    sta_->connectPin(drvr_inst, drvr_port, in_net);
+    out_net = drvr_net;
+  }
+  else {
+    in_net = drvr_net;
+    out_net = makeUniqueNet();
+  }
+
+  parasiticsInvalid(in_net);
+  // Spread buffers between driver and load center.
+  Point drvr_loc = db_network_->location(drvr_pin);
+  Point load_center = findCenter(load_pins);
+  int dx = (load_center.x() - drvr_loc.x()) / (buffer_count + 1);
+  int dy = (load_center.y() - drvr_loc.y()) / (buffer_count + 1);
+
+  Net *buf_in_net = in_net;
+  Instance *buffer = nullptr;
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  // drvr_pin->in_net->hold_buffer1->net2->hold_buffer2->out_net...->load_pins
+  for (int i = 0; i < buffer_count; i++) {
+    Net *buf_out_net = (i == buffer_count - 1) ? out_net : makeUniqueNet();
+    // drvr_pin->drvr_net->hold_buffer->net2->load_pins
+    string buffer_name = makeUniqueInstName("hold");
+    buffer = makeInstance(buffer_cell, buffer_name.c_str(),
+                          parent);
+    journalMakeBuffer(buffer);
+    inserted_buffer_count_++;
+    designAreaIncr(area(db_network_->cell(buffer_cell)));
+
+    sta_->connectPin(buffer, input, buf_in_net);
+    sta_->connectPin(buffer, output, buf_out_net);
+    Point buffer_loc(drvr_loc.x() + dx * i,
+                     drvr_loc.y() + dy * i);
+    setLocation(buffer, buffer_loc);
+    buf_in_net = buf_out_net;
+    parasiticsInvalid(buf_out_net);
+  }
+
+  for (Pin *load_pin : load_pins) {
+    Net *load_net = network_->isTopLevelPort(load_pin)
+      ? network_->net(network_->term(load_pin))
+      : network_->net(load_pin);
+    if (load_net != out_net) {
+      Instance *load = db_network_->instance(load_pin);
+      Port *load_port = db_network_->port(load_pin);
+      sta_->disconnectPin(load_pin);
+      sta_->connectPin(load, load_port, out_net);
+    }
+  }
+  Pin *buffer_out_pin = network_->findPin(buffer, output);
+  resizeToTargetSlew(buffer_out_pin, false);
+}
+
+Point
+Resizer::findCenter(PinSeq &pins)
+{
+  long sum_x = 0;
+  long sum_y = 0;
+  for (Pin *pin : pins) {
+    Point loc = db_network_->location(pin);
+    sum_x += loc.x();
+    sum_y += loc.y();
+  }
+  return Point(sum_x / pins.size(), sum_y / pins.size());
+}
+
+// Gap between min setup and hold slacks.
+// This says how much head room there is for adding delay to fix a
+// hold violation before violating a setup check.
+Slack
+Resizer::slackGap(Slacks &slacks)
+{
+  return min(slacks[RiseFall::riseIndex()][MinMax::maxIndex()]
+             - slacks[RiseFall::riseIndex()][MinMax::minIndex()],
+             slacks[RiseFall::fallIndex()][MinMax::maxIndex()]
+             - slacks[RiseFall::fallIndex()][MinMax::minIndex()]);
+}
+
+Slack
+Resizer::slackGap(Vertex *vertex)
+{
+  Slacks slacks;
+  sta_->vertexSlacks(vertex, slacks);
+  return slackGap(slacks);
+}
+
+int
+Resizer::fanout(Vertex *vertex)
+{
+  int fanout = 0;
+  VertexOutEdgeIterator edge_iter(vertex, graph_);
+  while (edge_iter.hasNext()) {
+    edge_iter.next();
+    fanout++;
+  }
+  return fanout;
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::reportLongWires(int count,
+                         int digits)
+{
+  graph_ = sta_->ensureGraph();
+  sta_->ensureClkNetwork();
+  VertexSeq drvrs;
+  findLongWires(drvrs);
+  report_->reportLine("Driver    length delay");
+  const Corner *corner = sta_->cmdCorner();
+  double wire_res = wireSignalResistance(corner);
+  double wire_cap = wireSignalCapacitance(corner);
+  int i = 0;
+  for (Vertex *drvr : drvrs) {
+    Pin *drvr_pin = drvr->pin();
+    double wire_length = dbuToMeters(maxLoadManhattenDistance(drvr));
+    double steiner_length = dbuToMeters(findMaxSteinerDist(drvr));
+    double delay = (wire_length * wire_res) * (wire_length * wire_cap) * 0.5;
+    report_->reportLine("%s manhtn %s steiner %s %s",
+                        sdc_network_->pathName(drvr_pin),
+                        units_->distanceUnit()->asString(wire_length, 1),
+                        units_->distanceUnit()->asString(steiner_length, 1),
+                        delayAsString(delay, sta_, digits));
+    if (i == count)
+      break;
+    i++;
+  }
+}
+
+typedef std::pair<Vertex*, int> DrvrDist;
+
+void
+Resizer::findLongWires(VertexSeq &drvrs)
+{
+  Vector<DrvrDist> drvr_dists;
+  VertexIterator vertex_iter(graph_);
+  while (vertex_iter.hasNext()) {
+    Vertex *vertex = vertex_iter.next();
+    if (vertex->isDriver(network_)) {
+      Pin *pin = vertex->pin();
+      // Hands off the clock nets.
+      if (!sta_->isClock(pin)
+          && !vertex->isConstant()
+          && !vertex->isDisabledConstraint())
+        drvr_dists.push_back(DrvrDist(vertex, maxLoadManhattenDistance(vertex)));
+    }
+  }
+  sort(drvr_dists, [](const DrvrDist &drvr_dist1,
+                          const DrvrDist &drvr_dist2) {
+                    return drvr_dist1.second > drvr_dist2.second;
+                  });
+  drvrs.reserve(drvr_dists.size());
+  for (DrvrDist &drvr_dist : drvr_dists)
+    drvrs.push_back(drvr_dist.first);
+}
+
+void
+Resizer::findLongWiresSteiner(VertexSeq &drvrs)
+{
+  Vector<DrvrDist> drvr_dists;
+  VertexIterator vertex_iter(graph_);
+  while (vertex_iter.hasNext()) {
+    Vertex *vertex = vertex_iter.next();
+    if (vertex->isDriver(network_)) {
+      Pin *pin = vertex->pin();
+      // Hands off the clock nets.
+      if (!sta_->isClock(pin)
+          && !vertex->isConstant())
+        drvr_dists.push_back(DrvrDist(vertex, findMaxSteinerDist(vertex)));
+    }
+  }
+  sort(drvr_dists, [](const DrvrDist &drvr_dist1,
+                          const DrvrDist &drvr_dist2) {
+                     return drvr_dist1.second > drvr_dist2.second;
+                   });
+  drvrs.reserve(drvr_dists.size());
+  for (DrvrDist &drvr_dist : drvr_dists)
+    drvrs.push_back(drvr_dist.first);
+}
+
+// Find the maximum distance along steiner tree branches from
+// the driver to loads (in dbu).
+int
+Resizer::findMaxSteinerDist(Vertex *drvr)
+{
+  Pin *drvr_pin = drvr->pin();
+  SteinerTree *tree = makeSteinerTree(drvr_pin, true, max_steiner_pin_count_,
+                                      stt_builder_, db_network_, logger_);
+  if (tree) {
+    int dist = findMaxSteinerDist(tree);
+    delete tree;
+    return dist;
+  }
+  return 0;
+}
+
+int
+Resizer::findMaxSteinerDist(SteinerTree *tree)
+{
+  SteinerPt drvr_pt = tree->drvrPt(network_);
+  if (drvr_pt == SteinerTree::null_pt)
+    return 0;
+  else
+    return findMaxSteinerDist(tree, drvr_pt, 0);
+}
+
+// DFS of steiner tree.
+int
+Resizer::findMaxSteinerDist(SteinerTree *tree,
+                            SteinerPt pt,
+                            int dist_from_drvr)
+{
+  const PinSeq *pins = tree->pins(pt);
+  if (pins) {
+    for (const Pin *pin : *pins) {
+      if (db_network_->isLoad(pin))
+        return dist_from_drvr;
+    }
+  }
+  Point loc = tree->location(pt);
+  SteinerPt left = tree->left(pt);
+  int left_max = 0;
+  if (left != SteinerTree::null_pt) {
+    int left_dist = Point::manhattanDistance(loc, tree->location(left));
+    left_max = findMaxSteinerDist(tree, left, dist_from_drvr + left_dist);
+  }
+  SteinerPt right = tree->right(pt);
+  int right_max = 0;
+  if (right != SteinerTree::null_pt) {
+    int right_dist = Point::manhattanDistance(loc, tree->location(right));
+    right_max = findMaxSteinerDist(tree, right, dist_from_drvr + right_dist);
+  }
+  return max(left_max, right_max);
+}
+
+double
+Resizer::maxLoadManhattenDistance(const Net *net)
+{
+  NetPinIterator *pin_iter = network_->pinIterator(net);
+  int max_dist = 0;
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    if (network_->isDriver(pin)) {
+      Vertex *drvr = graph_->pinDrvrVertex(pin);
+      if (drvr) {
+        int dist = maxLoadManhattenDistance(drvr);
+        max_dist = max(max_dist, dist);
+      }
+    }
+  }
+  delete pin_iter;
+  return dbuToMeters(max_dist);
+}
+
+int
+Resizer::maxLoadManhattenDistance(Vertex *drvr)
+{
+  int max_dist = 0;
+  Point drvr_loc = db_network_->location(drvr->pin());
+  VertexOutEdgeIterator edge_iter(drvr, graph_);
+  while (edge_iter.hasNext()) {
+    Edge *edge = edge_iter.next();
+    Vertex *load = edge->to(graph_);
+    Point load_loc = db_network_->location(load->pin());
+    int dist = Point::manhattanDistance(drvr_loc, load_loc);
+    max_dist = max(max_dist, dist);
+  }
+  return max_dist;
+}
+
+////////////////////////////////////////////////////////////////
+
+NetSeq *
+Resizer::findFloatingNets()
+{
+  NetSeq *floating_nets = new NetSeq;
+  NetIterator *net_iter = network_->netIterator(network_->topInstance());
+  while (net_iter->hasNext()) {
+    Net *net = net_iter->next();
+    PinSeq loads;
+    PinSeq drvrs;
+    PinSet visited_drvrs;
+    FindNetDrvrLoads visitor(nullptr, visited_drvrs, loads, drvrs, network_);
+    network_->visitConnectedPins(net, visitor);
+    if (drvrs.size() == 0 && loads.size() > 0)
+      floating_nets->push_back(net);
+  }
+  delete net_iter;
+  sort(floating_nets, sta::NetPathNameLess(network_));
+  return floating_nets;
+}
+
+////////////////////////////////////////////////////////////////
+
+string
+Resizer::makeUniqueNetName()
+{
+  string node_name;
+  Instance *top_inst = network_->topInstance();
+  do 
+    stringPrint(node_name, "net%d", unique_net_index_++);
+  while (network_->findNet(top_inst, node_name.c_str()));
+  return node_name;
+}
+
+Net *
+Resizer::makeUniqueNet()
+{
+  string net_name = makeUniqueNetName();
+  Instance *parent = db_network_->topInstance();
+  return db_network_->makeNet(net_name.c_str(), parent);
+}
+
+string
+Resizer::makeUniqueInstName(const char *base_name)
+{
+  return makeUniqueInstName(base_name, false);
+}
+
+string
+Resizer::makeUniqueInstName(const char *base_name,
+                            bool underscore)
+{
+  string inst_name;
+  do 
+    stringPrint(inst_name, underscore ? "%s_%d" : "%s%d",
+                base_name, unique_inst_index_++);
+  while (network_->findInstance(inst_name.c_str()));
+  return inst_name;
+}
+
+float
+Resizer::portFanoutLoad(LibertyPort *port)
+{
+  float fanout_load;
+  bool exists;
+  port->fanoutLoad(fanout_load, exists);
+  if (!exists) {
+    LibertyLibrary *lib = port->libertyLibrary();
+    lib->defaultFanoutLoad(fanout_load, exists);
+  }
+  if (exists)
+    return fanout_load;
+  else
+    return 0.0;
+}
+
+float
+Resizer::bufferDelay(LibertyCell *buffer_cell,
+                     const RiseFall *rf,
+                     float load_cap,
+                     const DcalcAnalysisPt *dcalc_ap)
+{
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  ArcDelay gate_delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  gateDelays(output, load_cap, dcalc_ap, gate_delays, slews);
+  return gate_delays[rf->index()];
+}
+
+float
+Resizer::bufferDelay(LibertyCell *buffer_cell,
+                     float load_cap,
+                     const DcalcAnalysisPt *dcalc_ap)
+{
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  ArcDelay gate_delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  gateDelays(output, load_cap, dcalc_ap, gate_delays, slews);
+  return max(gate_delays[RiseFall::riseIndex()],
+             gate_delays[RiseFall::fallIndex()]);
+}
+
+// Self delay; buffer -> buffer
+float
+Resizer::bufferSelfDelay(LibertyCell *buffer_cell)
+{
+  const DcalcAnalysisPt *dcalc_ap = sta_->cmdCorner()->findDcalcAnalysisPt(max_);
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  ArcDelay gate_delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  float load_cap = input->capacitance();
+  gateDelays(output, load_cap, dcalc_ap, gate_delays, slews);
+  return max(gate_delays[RiseFall::riseIndex()],
+             gate_delays[RiseFall::fallIndex()]);
+}
+
+float
+Resizer::bufferSelfDelay(LibertyCell *buffer_cell,
+                         const RiseFall *rf)
+{
+  const DcalcAnalysisPt *dcalc_ap = sta_->cmdCorner()->findDcalcAnalysisPt(max_);
+  LibertyPort *input, *output;
+  buffer_cell->bufferPorts(input, output);
+  ArcDelay gate_delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  float load_cap = input->capacitance();
+  gateDelays(output, load_cap, dcalc_ap, gate_delays, slews);
+  return gate_delays[rf->index()];
+}
+
+// Rise/fall delays across all timing arcs into drvr_port.
+// Uses target slew for input slew.
+void
+Resizer::gateDelays(LibertyPort *drvr_port,
+                    float load_cap,
+                    const DcalcAnalysisPt *dcalc_ap,
+                    // Return values.
+                    ArcDelay delays[RiseFall::index_count],
+                    Slew slews[RiseFall::index_count])
+{
+  for (int rf_index : RiseFall::rangeIndex()) {
+    delays[rf_index] = -INF;
+    slews[rf_index] = -INF;
+  }
+  const Pvt *pvt = dcalc_ap->operatingConditions();
+  LibertyCell *cell = drvr_port->libertyCell();
+  LibertyCellTimingArcSetIterator set_iter(cell);
+  while (set_iter.hasNext()) {
+    TimingArcSet *arc_set = set_iter.next();
+    if (arc_set->to() == drvr_port
+        && !arc_set->role()->isTimingCheck()) {
+      TimingArcSetArcIterator arc_iter(arc_set);
+      while (arc_iter.hasNext()) {
+        TimingArc *arc = arc_iter.next();
+        RiseFall *in_rf = arc->fromTrans()->asRiseFall();
+        int out_rf_index = arc->toTrans()->asRiseFall()->index();
+        float in_slew = tgt_slews_[in_rf->index()];
+        ArcDelay gate_delay;
+        Slew drvr_slew;
+        arc_delay_calc_->gateDelay(cell, arc, in_slew, load_cap,
+                                   nullptr, 0.0, pvt, dcalc_ap,
+                                   gate_delay,
+                                   drvr_slew);
+        delays[out_rf_index] = max(delays[out_rf_index], gate_delay);
+        slews[out_rf_index] = max(slews[out_rf_index], drvr_slew);
+      }
+    }
+  }
+}
+
+ArcDelay
+Resizer::gateDelay(LibertyPort *drvr_port,
+                   const RiseFall *rf,
+                   float load_cap,
+                   const DcalcAnalysisPt *dcalc_ap)
+{
+  ArcDelay delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  gateDelays(drvr_port, load_cap, dcalc_ap, delays, slews);
+  return delays[rf->index()];
+}
+
+ArcDelay
+Resizer::gateDelay(LibertyPort *drvr_port,
+                   float load_cap,
+                   const DcalcAnalysisPt *dcalc_ap)
+{
+  ArcDelay delays[RiseFall::index_count];
+  Slew slews[RiseFall::index_count];
+  gateDelays(drvr_port, load_cap, dcalc_ap, delays, slews);
+  return max(delays[RiseFall::riseIndex()], delays[RiseFall::fallIndex()]);
+}
+
+////////////////////////////////////////////////////////////////
+
+double
+Resizer::findMaxWireLength()
+{
+  double max_length = INF;
+  for (const Corner *corner : *sta_->corners()) {
+    if (wireSignalResistance(corner) > 0.0) {
+      for (LibertyCell *buffer_cell : buffer_cells_) {
+        double buffer_length = findMaxWireLength(buffer_cell, corner);
+        max_length = min(max_length, buffer_length);
+      }
+    }
+  }
+  return max_length;
+}
+
+// Find the max wire length before it is faster to split the wire
+// in half with a buffer (in meters).
+double
+Resizer::findMaxWireLength(LibertyCell *buffer_cell,
+                           const Corner *corner)
+{
+  ensureBlock();
+  LibertyPort *load_port, *drvr_port;
+  buffer_cell->bufferPorts(load_port, drvr_port);
+  return findMaxWireLength(drvr_port, corner);
+}
+
+double
+Resizer::findMaxWireLength(LibertyPort *drvr_port,
+                           const Corner *corner)
+{
+  LibertyCell *cell = drvr_port->libertyCell();
+  if (db_network_->staToDb(cell) == nullptr)
+    logger_->error(RSZ, 70, "no LEF cell for {}.", cell->name());
+  double drvr_r = drvr_port->driveResistance();
+  // wire_length1 lower bound
+  // wire_length2 upper bound
+  double wire_length1 = 0.0;
+  // Initial guess with wire resistance same as driver resistance.
+  double wire_length2 = drvr_r / wireSignalResistance(corner);
+  double tol = .01; // 1%
+  double diff1 = splitWireDelayDiff(wire_length2, cell);
+  // binary search for diff = 0.
+  while (abs(wire_length1 - wire_length2) > max(wire_length1, wire_length2) * tol) {
+    if (diff1 < 0.0) {
+      wire_length1 = wire_length2;
+      wire_length2 *= 2;
+      diff1 = splitWireDelayDiff(wire_length2, cell);
+    }
+    else {
+      double wire_length3 = (wire_length1 + wire_length2) / 2.0;
+      double diff2 = splitWireDelayDiff(wire_length3, cell);
+      if (diff2 < 0.0) {
+        wire_length1 = wire_length3;
+      }
+      else {
+        wire_length2 = wire_length3;
+        diff1 = diff2;
+      }
+    }
+  }
+  return wire_length1;
+}
+
+// objective function
+double
+Resizer::splitWireDelayDiff(double wire_length,
+                            LibertyCell *buffer_cell)
+{
+  Delay delay1, delay2;
+  Slew slew1, slew2;
+  bufferWireDelay(buffer_cell, wire_length, delay1, slew1);
+  bufferWireDelay(buffer_cell, wire_length / 2, delay2, slew2);
+  return delay1 - delay2 * 2;
+}
+
+void
+Resizer::bufferWireDelay(LibertyCell *buffer_cell,
+                         double wire_length, // meters
+                         // Return values.
+                         Delay &delay,
+                         Slew &slew)
+{
+  LibertyPort *load_port, *drvr_port;
+  buffer_cell->bufferPorts(load_port, drvr_port);
+  return cellWireDelay(drvr_port, load_port, wire_length, delay, slew);
+}
+
+// Cell delay plus wire delay.
+// Use target slew for input slew.
+// drvr_port and load_port do not have to be the same liberty cell.
+void
+Resizer::cellWireDelay(LibertyPort *drvr_port,
+                       LibertyPort *load_port,
+                       double wire_length, // meters
+                       // Return values.
+                       Delay &delay,
+                       Slew &slew)
+{
+  // Make a (hierarchical) block to use as a scratchpad.
+  dbBlock *block = dbBlock::create(block_, "wire_delay", '/');
+  dbSta *sta = makeBlockSta(openroad_, block);
+  Parasitics *parasitics = sta->parasitics();
+  Network *network = sta->network();
+  ArcDelayCalc *arc_delay_calc = sta->arcDelayCalc();
+  Corners *corners = sta->corners();
+  corners->copy(sta_->corners());
+
+  Instance *top_inst = network->topInstance();
+  // Tmp net for parasitics to live on.
+  Net *net = sta->makeNet("wire", top_inst);
+  LibertyCell *drvr_cell = drvr_port->libertyCell();
+  LibertyCell *load_cell = load_port->libertyCell();
+  Instance *drvr = sta->makeInstance("drvr", drvr_cell, top_inst);
+  Instance *load = sta->makeInstance("load", load_cell, top_inst);
+  sta->connectPin(drvr, drvr_port, net);
+  sta->connectPin(load, load_port, net);
+  Pin *drvr_pin = network->findPin(drvr, drvr_port);
+  Pin *load_pin = network->findPin(load, load_port);
+
+  // Max rise/fall delays.
+  delay = -INF;
+  slew = -INF;
+
+  for (Corner *corner : *corners) {
+    const DcalcAnalysisPt *dcalc_ap = corner->findDcalcAnalysisPt(max_);
+    const Pvt *pvt = dcalc_ap->operatingConditions();
+
+    makeWireParasitic(net, drvr_pin, load_pin, wire_length, corner, parasitics);
+    // Let delay calc reduce parasitic network as it sees fit.
+    Parasitic *drvr_parasitic = arc_delay_calc->findParasitic(drvr_pin,
+                                                              RiseFall::rise(),
+                                                              dcalc_ap);
+    LibertyCellTimingArcSetIterator set_iter(drvr_cell);
+    while (set_iter.hasNext()) {
+      TimingArcSet *arc_set = set_iter.next();
+      if (arc_set->to() == drvr_port) {
+        TimingArcSetArcIterator arc_iter(arc_set);
+        while (arc_iter.hasNext()) {
+          TimingArc *arc = arc_iter.next();
+          RiseFall *in_rf = arc->fromTrans()->asRiseFall();
+          double in_slew = tgt_slews_[in_rf->index()];
+          ArcDelay gate_delay;
+          Slew drvr_slew;
+          arc_delay_calc->gateDelay(drvr_cell, arc, in_slew, 0.0,
+                                    drvr_parasitic, 0.0, pvt, dcalc_ap,
+                                    gate_delay,
+                                    drvr_slew);
+          ArcDelay wire_delay;
+          Slew load_slew;
+          arc_delay_calc->loadDelay(load_pin, wire_delay, load_slew);
+          delay = max(delay, gate_delay + wire_delay);
+          slew = max(slew, load_slew);
+        }
+      }
+    }
+    arc_delay_calc->finishDrvrPin();
+    parasitics->deleteParasitics(net, dcalc_ap->parasiticAnalysisPt());
+  }
+
+  // Cleanup the turds.
+  sta->deleteInstance(drvr);
+  sta->deleteInstance(load);
+  sta->deleteNet(net);
+  delete sta;
+  dbBlock::destroy(block);
+}
+
+void
+Resizer::makeWireParasitic(Net *net,
+                           Pin *drvr_pin,
+                           Pin *load_pin,
+                           double wire_length, // meters
+                           const Corner *corner,
+                           Parasitics *parasitics)
+{
+  const ParasiticAnalysisPt *parasitics_ap =
+    corner->findParasiticAnalysisPt(max_);
+  Parasitic *parasitic = parasitics->makeParasiticNetwork(net, false,
+                                                          parasitics_ap);
+  ParasiticNode *n1 = parasitics->ensureParasiticNode(parasitic, drvr_pin);
+  ParasiticNode *n2 = parasitics->ensureParasiticNode(parasitic, load_pin);
+  double wire_cap = wire_length * wireSignalCapacitance(corner);
+  double wire_res = wire_length * wireSignalResistance(corner);
+  parasitics->incrCap(n1, wire_cap / 2.0, parasitics_ap);
+  parasitics->makeResistor(nullptr, n1, n2, wire_res, parasitics_ap);
+  parasitics->incrCap(n2, wire_cap / 2.0, parasitics_ap);
+}
+
+////////////////////////////////////////////////////////////////
+
+double
+Resizer::findMaxSlewWireLength(LibertyPort *drvr_port,
+                               LibertyPort *load_port,
+                               double max_slew,
+                               const Corner *corner)
+{
+  ensureBlock();
+  // wire_length1 lower bound
+  // wire_length2 upper bound
+  double wire_length1 = 0.0;
+  double wire_length2 = std::sqrt(max_slew /(wireSignalResistance(corner)
+                                             * wireSignalCapacitance(corner)));
+  double tol = .01; // 1%
+  double diff1 = maxSlewWireDiff(drvr_port, load_port, wire_length2, max_slew);
+  // binary search for diff = 0.
+  while (abs(wire_length1 - wire_length2) > max(wire_length1, wire_length2) * tol) {
+    if (diff1 < 0.0) {
+      wire_length1 = wire_length2;
+      wire_length2 *= 2;
+      diff1 = maxSlewWireDiff(drvr_port, load_port, wire_length2, max_slew);
+    }
+    else {
+      double wire_length3 = (wire_length1 + wire_length2) / 2.0;
+      double diff2 = maxSlewWireDiff(drvr_port, load_port, wire_length3, max_slew);
+      if (diff2 < 0.0) {
+        wire_length1 = wire_length3;
+      }
+      else {
+        wire_length2 = wire_length3;
+        diff1 = diff2;
+      }
+    }
+  }
+  return wire_length1;
+}
+
+// objective function
+double
+Resizer::maxSlewWireDiff(LibertyPort *drvr_port,
+                         LibertyPort *load_port,
+                         double wire_length,
+                         double max_slew)
+{
+  Delay delay;
+  Slew slew;
+  cellWireDelay(drvr_port, load_port, wire_length, delay, slew);
+  return slew - max_slew;
+}
+
+////////////////////////////////////////////////////////////////
+
+double
+Resizer::designArea()
+{
+  ensureBlock();
+  ensureDesignArea();
+  return design_area_;
+}
+
+void
+Resizer::designAreaIncr(float delta)
+{
+  design_area_ += delta;
+}
+
+void
+Resizer::ensureDesignArea()
+{
+  if (block_) {
+    design_area_ = 0.0;
+    for (dbInst *inst : block_->getInsts()) {
+      dbMaster *master = inst->getMaster();
+      // Don't count fillers otherwise you'll always get 100% utilization
+      if (!master->isFiller()) {
+        design_area_ += area(master);
+      }
+    }
+  }
+}
+
+int
+Resizer::fanout(Pin *drvr_pin)
+{
+  int fanout = 0;
+  NetConnectedPinIterator *pin_iter = network_->connectedPinIterator(drvr_pin);
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    if (pin != drvr_pin)
+      fanout++;
+  }
+  delete pin_iter;
+  return fanout;
+}
+
+bool
+Resizer::isFuncOneZero(const Pin *drvr_pin)
+{
+  LibertyPort *port = network_->libertyPort(drvr_pin);
+  if (port) {
+    FuncExpr *func = port->function();
+    return func && (func->op() == FuncExpr::op_zero
+                    || func->op() == FuncExpr::op_one);
+  }
+  return false;
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+Resizer::repairClkInverters()
+{
+  // Abbreviated copyState
+  db_network_ = sta_->getDbNetwork();
+  sta_->ensureLevelized();
+  graph_ = sta_->graph();
+  ensureBlock();
+  ensureDesignArea();
+  for (Instance *inv : findClkInverters())
+    cloneClkInverter(inv);
+}
+
+InstanceSeq
+Resizer::findClkInverters()
+{
+  InstanceSeq clk_inverters;
+  ClkArrivalSearchPred srch_pred(this);
+  BfsFwdIterator bfs(BfsIndex::other, &srch_pred, this);
+  for (Clock *clk : sdc_->clks()) {
+    for (Pin *pin : clk->leafPins()) {
+      Vertex *vertex = graph_->pinDrvrVertex(pin);
+      bfs.enqueue(vertex);
+    }
+  }
+  while (bfs.hasNext()) {
+    Vertex *vertex = bfs.next();
+    const Pin *pin = vertex->pin();
+    Instance *inst = network_->instance(pin);
+    LibertyCell *lib_cell = network_->libertyCell(inst);
+    if (vertex->isDriver(network_)
+        && lib_cell
+        && lib_cell->isInverter()) {
+      clk_inverters.push_back(inst);
+      debugPrint(logger_, RSZ, "repair_clk_inverters", 2, "inverter {}",
+                 network_->pathName(inst));
+    }
+    if (!vertex->isRegClk())
+      bfs.enqueueAdjacentVertices(vertex);
+  }
+  return clk_inverters;
+}
+
+void
+Resizer::cloneClkInverter(Instance *inv)
+{
+  LibertyCell *inv_cell = network_->libertyCell(inv);
+  LibertyPort *in_port, *out_port;
+  inv_cell->bufferPorts(in_port, out_port);
+  Pin *in_pin = network_->findPin(inv, in_port);
+  Pin *out_pin = network_->findPin(inv, out_port);
+  Net *in_net = network_->net(in_pin);
+  dbNet *in_net_db = db_network_->staToDb(in_net);
+  Net *out_net = network_->isTopLevelPort(out_pin)
+    ? network_->net(network_->term(out_pin))
+    : network_->net(out_pin);
+  if (out_net) {
+    const char *inv_name = network_->name(inv);
+    Instance *top_inst = network_->topInstance();
+    NetConnectedPinIterator *load_iter = network_->pinIterator(out_net);
+    while (load_iter->hasNext()) {
+      Pin *load_pin = load_iter->next();
+      if (load_pin != out_pin) {
+        string clone_name = makeUniqueInstName(inv_name, true);
+        Instance *clone = makeInstance(inv_cell, clone_name.c_str(),
+                                       top_inst);
+        Point clone_loc = db_network_->location(load_pin);
+        journalMakeBuffer(clone);
+        setLocation(clone, clone_loc);
+
+        Net *clone_out_net = makeUniqueNet();
+        dbNet *clone_out_net_db = db_network_->staToDb(clone_out_net);
+        clone_out_net_db->setSigType(in_net_db->getSigType());
+
+        Instance *load = network_->instance(load_pin);
+        sta_->connectPin(clone, in_port, in_net);
+        sta_->connectPin(clone, out_port, clone_out_net);
+
+        // Connect load to clone
+        sta_->disconnectPin(load_pin);
+        Port *load_port = network_->port(load_pin);
+        sta_->connectPin(load, load_port, clone_out_net);
+      }
+    }
+    delete load_iter;
+
+    // Delete inv
+    sta_->disconnectPin(in_pin);
+    sta_->disconnectPin(out_pin);
+    sta_->deleteNet(out_net);
+    parasitics_invalid_.erase(out_net);
+    sta_->deleteInstance(inv);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+// Journal to roll back changes (OpenDB not up to the task).
+void
+Resizer::journalBegin()
+{
+  debugPrint(logger_, RSZ, "journal", 1, "journal begin");
+  resized_inst_map_.clear();
+  inserted_buffers_.clear();
+}
+
+void
+Resizer::journalInstReplaceCellBefore(Instance *inst)
+{
+  LibertyCell *lib_cell = network_->libertyCell(inst);
+  debugPrint(logger_, RSZ, "journal", 1, "journal replace {} ({})",
+             network_->pathName(inst),
+             lib_cell->name());
+  // Do not clobber an existing checkpoint cell.
+  if (!resized_inst_map_.hasKey(inst))
+    resized_inst_map_[inst] = lib_cell;
+}
+
+void
+Resizer::journalMakeBuffer(Instance *buffer)
+{
+  debugPrint(logger_, RSZ, "journal", 1, "journal make_buffer {}",
+             network_->pathName(buffer));
+  inserted_buffers_.insert(buffer);
+}
+
+void
+Resizer::journalRestore()
+{
+  for (auto inst_cell : resized_inst_map_) {
+    Instance *inst = inst_cell.first;
+    if (!inserted_buffers_.hasKey(inst)) {
+      LibertyCell *lib_cell = inst_cell.second;
+      debugPrint(logger_, RSZ, "journal", 1, "journal restore {} ({})",
+                 network_->pathName(inst),
+                 lib_cell->name());
+      replaceCell(inst, lib_cell, false);
+      resize_count_--;
+    }
+  }
+  for (Instance *buffer : inserted_buffers_) {
+    debugPrint(logger_, RSZ, "journal", 1, "journal remove {}",
+               network_->pathName(buffer));
+    removeBuffer(buffer);
+    inserted_buffer_count_--;
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+class SteinerRenderer : public gui::Renderer
+{
+public:
+  SteinerRenderer();
+  void highlight(SteinerTree *tree);
+  virtual void drawObjects(gui::Painter& /* painter */) override;
+
+private:
+  SteinerTree *tree_;
+};
+
+void
+Resizer::highlightSteiner(const Pin *drvr)
+{
+  if (gui::Gui::enabled()) {
+    if (steiner_renderer_ == nullptr) {
+      steiner_renderer_ = new SteinerRenderer();
+      gui_->registerRenderer(steiner_renderer_);
+    }
+    SteinerTree *tree = nullptr;
+    if (drvr)
+      tree = makeSteinerTree(drvr, false, max_steiner_pin_count_,
+                             stt_builder_, db_network_, logger_);
+    steiner_renderer_->highlight(tree);
+  }
+}
+
+SteinerRenderer::SteinerRenderer() :
+  tree_(nullptr)
+{
+}
+
+void
+SteinerRenderer::highlight(SteinerTree *tree)
+{
+  tree_ = tree;
+}
+
+void
+SteinerRenderer::drawObjects(gui::Painter &painter)
+{
+  if (tree_) {
+    painter.setPen(gui::Painter::red, true);
+    for (int i = 0 ; i < tree_->branchCount(); ++i) {
+      Point pt1, pt2;
+      int steiner_pt1, steiner_pt2;
+      int wire_length;
+      tree_->branch(i, pt1, steiner_pt1, pt2, steiner_pt2, wire_length);
+      painter.drawLine(pt1, pt2);
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+PinSet
+Resizer::findFaninFanouts(PinSet *end_pins)
+{
+  // Abbreviated copyState
+  db_network_ = sta_->getDbNetwork();
+  sta_->ensureLevelized();
+  graph_ = sta_->graph();
+
+  VertexSet ends;
+  for (Pin *pin : *end_pins) {
+    Vertex *end = graph_->pinLoadVertex(pin);
+    ends.insert(end);
+  }
+  PinSet fanin_fanout_pins;
+  VertexSet fanin_fanouts = findFaninFanouts(ends);
+  for (Vertex *vertex : fanin_fanouts)
+    fanin_fanout_pins.insert(vertex->pin());
+  return fanin_fanout_pins;
+}
+
+VertexSet
+Resizer::findFaninFanouts(VertexSet &ends)
+{
+  // Search backwards from ends to fanin register outputs and input ports.
+  VertexSet fanin_roots = findFaninRoots(ends);
+  // Search forward from register outputs.
+  VertexSet fanouts = findFanouts(fanin_roots);
+  return fanouts;
+}
+
+// Find source pins for logic fanin of ends.
+PinSet
+Resizer::findFanins(PinSet *end_pins)
+{
+  // Abbreviated copyState
+  db_network_ = sta_->getDbNetwork();
+  sta_->ensureLevelized();
+  graph_ = sta_->graph();
+
+  VertexSet ends;
+  for (Pin *pin : *end_pins) {
+    Vertex *end = graph_->pinLoadVertex(pin);
+    ends.insert(end);
+  }
+
+  SearchPredNonReg2 pred(sta_);
+  BfsBkwdIterator iter(BfsIndex::other, &pred, this);
+  for (Vertex *vertex : ends)
+    iter.enqueueAdjacentVertices(vertex);
+
+  PinSet fanins;
+  while (iter.hasNext()) {
+    Vertex *vertex = iter.next();
+    if (isRegOutput(vertex)
+        || network_->isTopLevelPort(vertex->pin()))
+      continue;
+    else {
+      iter.enqueueAdjacentVertices(vertex);
+      fanins.insert(vertex->pin());
+    }
+  }
+  return fanins;
+}
+
+// Find roots for logic fanin of ends.
+VertexSet
+Resizer::findFaninRoots(VertexSet &ends)
+{
+  SearchPredNonReg2 pred(sta_);
+  BfsBkwdIterator iter(BfsIndex::other, &pred, this);
+  for (Vertex *vertex : ends)
+    iter.enqueueAdjacentVertices(vertex);
+
+  VertexSet roots;
+  while (iter.hasNext()) {
+    Vertex *vertex = iter.next();
+    if (isRegOutput(vertex)
+        || network_->isTopLevelPort(vertex->pin()))
+      roots.insert(vertex);
+    else
+      iter.enqueueAdjacentVertices(vertex);
+  }
+  return roots;
+}
+
+bool
+Resizer::isRegOutput(Vertex *vertex)
+{
+  LibertyPort *port = network_->libertyPort(vertex->pin());
+  if (port) {
+    LibertyCell *cell = port->libertyCell();
+    LibertyCellTimingArcSetIterator arc_set_iter(cell, nullptr, port);
+    while (arc_set_iter.hasNext()) {
+      TimingArcSet *arc_set = arc_set_iter.next();
+      if (arc_set->role()->genericRole() == TimingRole::regClkToQ())
+        return true;
+    }
+  }
+  return false;
+}
+
+VertexSet
+Resizer::findFanouts(VertexSet &reg_outs)
+{
+  VertexSet fanouts;
+  sta::SearchPredNonLatch2 pred(sta_);
+  BfsFwdIterator iter(BfsIndex::other, &pred, this);
+  for (Vertex *reg_out : reg_outs)
+    iter.enqueueAdjacentVertices(reg_out);
+
+  while (iter.hasNext()) {
+    Vertex *vertex = iter.next();
+    if (!isRegister(vertex)) {
+      fanouts.insert(vertex);
+      iter.enqueueAdjacentVertices(vertex);
+    }
+  }
+  return fanouts;
+}
+
+bool
+Resizer::isRegister(Vertex *vertex)
+{
+  LibertyPort *port = network_->libertyPort(vertex->pin());
+  if (port) {
+    LibertyCell *cell = port->libertyCell();
+    return cell && cell->hasSequentials();
+  }
+  return false;
+}
+
+Instance *Resizer::makeInstance(LibertyCell *cell,
+                                const char *name,
+                                Instance *parent)
+{
+  debugPrint(logger_, RSZ, "make_instance", 1, "make instance {}", name);
+  Instance *inst = db_network_->makeInstance(cell, name, parent);
+  dbInst *db_inst = db_network_->staToDb(inst);
+  db_inst->setSourceType(odb::dbSourceType::TIMING);
+  return inst;
+}
+
+} // namespace
diff --git a/hacks/src/OpenSTA/network/ConcreteNetwork.cc b/hacks/src/OpenSTA/network/ConcreteNetwork.cc
new file mode 100644
index 0000000..e0ee69b
--- /dev/null
+++ b/hacks/src/OpenSTA/network/ConcreteNetwork.cc
@@ -0,0 +1,2000 @@
+// OpenSTA, Static Timing Analyzer
+// Copyright (c) 2022, Parallax Software, Inc.
+// 
+// This program is free software: 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 3 of the License, or
+// (at your option) any later version.
+// 
+// This program 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 program. If not, see <https://www.gnu.org/licenses/>.
+
+#include "ConcreteNetwork.hh"
+
+#include "DisallowCopyAssign.hh"
+#include "PatternMatch.hh"
+#include "Report.hh"
+#include "Liberty.hh"
+#include "PortDirection.hh"
+#include "ConcreteLibrary.hh"
+#include "Network.hh"
+
+namespace sta {
+
+static void
+makeChildNetwork(Instance *proto,
+		 Instance *parent,
+		 ConcreteBindingTbl *parent_bindings,
+		 NetworkReader *network);
+static void
+makeClonePins(Instance *proto,
+	      Instance *clone,
+	      Instance *clone_view,
+	      ConcreteBindingTbl *bindings,
+	      Instance *parent,
+	      ConcreteBindingTbl *parent_bindings,
+	      NetworkReader *network);
+
+NetworkReader *
+makeConcreteNetwork()
+{
+  return new ConcreteNetwork;
+}
+
+class ConcreteInstanceChildIterator : public InstanceChildIterator
+{
+public:
+  explicit ConcreteInstanceChildIterator(ConcreteInstanceChildMap *map);
+  bool hasNext();
+  Instance *next();
+
+private:
+  ConcreteInstanceChildMap::ConstIterator iter_;
+};
+
+ConcreteInstanceChildIterator::
+ConcreteInstanceChildIterator(ConcreteInstanceChildMap *map) :
+  iter_(map)
+{
+}
+
+bool
+ConcreteInstanceChildIterator::hasNext()
+{
+  return iter_.hasNext();
+}
+
+Instance *
+ConcreteInstanceChildIterator::next()
+{
+  return reinterpret_cast<Instance*>(iter_.next());
+}
+
+class ConcreteInstanceNetIterator : public InstanceNetIterator
+{
+public:
+  explicit ConcreteInstanceNetIterator(ConcreteInstanceNetMap *nets);
+  bool hasNext();
+  Net *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteInstanceNetIterator);
+  void findNext();
+
+  ConcreteInstanceNetMap::Iterator iter_;
+  ConcreteNet *next_;
+};
+
+ConcreteInstanceNetIterator::
+ConcreteInstanceNetIterator(ConcreteInstanceNetMap *nets):
+  iter_(nets),
+  next_(nullptr)
+{
+  findNext();
+}
+
+bool
+ConcreteInstanceNetIterator::hasNext()
+{
+  return next_ != nullptr;
+}
+
+// Skip nets that have been merged.
+void
+ConcreteInstanceNetIterator::findNext()
+{
+  while (iter_.hasNext()) {
+    next_ = iter_.next();
+    if (next_->mergedInto() == nullptr)
+      return;
+  }
+  next_ = nullptr;
+}
+
+Net *
+ConcreteInstanceNetIterator::next()
+{
+  ConcreteNet *next = next_;
+  findNext();
+  return reinterpret_cast<Net*>(next);
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteInstancePinIterator : public InstancePinIterator
+{
+public:
+  ConcreteInstancePinIterator(const ConcreteInstance *inst,
+			      int pin_count);
+  bool hasNext();
+  Pin *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteInstancePinIterator);
+  void findNext();
+
+  ConcretePin **pins_;
+  int pin_count_;
+  int pin_index_;
+  ConcretePin *next_;
+};
+
+ConcreteInstancePinIterator::
+ConcreteInstancePinIterator(const ConcreteInstance *inst,
+			    int pin_count) :
+  pins_(inst->pins_),
+  pin_count_(pin_count),
+  pin_index_(0)
+{
+  findNext();
+}
+
+bool
+ConcreteInstancePinIterator::hasNext()
+{
+  return next_ != nullptr;
+}
+
+Pin *
+ConcreteInstancePinIterator::next()
+{
+  ConcretePin *next = next_;
+  findNext();
+  return reinterpret_cast<Pin*>(next);
+}
+
+// Skip over missing pins.
+void
+ConcreteInstancePinIterator::findNext()
+{
+  while (pin_index_ < pin_count_) {
+    next_ = pins_[pin_index_++];
+    if (next_)
+      return;
+  }
+  next_ = nullptr;
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteNetPinIterator : public NetPinIterator
+{
+public:
+  explicit ConcreteNetPinIterator(const ConcreteNet *net);
+  bool hasNext();
+  Pin *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteNetPinIterator);
+
+  ConcretePin *next_;
+};
+
+ConcreteNetPinIterator::ConcreteNetPinIterator(const ConcreteNet *net) :
+  next_(net->pins_)
+{
+}
+
+bool
+ConcreteNetPinIterator::hasNext()
+{
+  return next_ != nullptr;
+}
+
+Pin *
+ConcreteNetPinIterator::next()
+{
+  ConcretePin *next = next_;
+  next_ = next_->net_next_;
+  return reinterpret_cast<Pin*>(next);
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteNetTermIterator : public NetTermIterator
+{
+public:
+  explicit ConcreteNetTermIterator(const ConcreteNet *net);
+  bool hasNext();
+  Term *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteNetTermIterator);
+
+  ConcreteTerm *next_;
+};
+
+ConcreteNetTermIterator::ConcreteNetTermIterator(const ConcreteNet *net) :
+  next_(net->terms_)
+{
+}
+
+bool
+ConcreteNetTermIterator::hasNext()
+{
+  return next_ != nullptr;
+}
+
+Term *
+ConcreteNetTermIterator::next()
+{
+  ConcreteTerm *next = next_;
+  next_ = next_->net_next_;
+  return reinterpret_cast<Term*>(next);
+}
+
+////////////////////////////////////////////////////////////////
+
+ConcreteNetwork::ConcreteNetwork() :
+  NetworkReader(),
+  top_instance_(nullptr),
+  link_func_(nullptr)
+{
+}
+
+ConcreteNetwork::~ConcreteNetwork()
+{
+  clear();
+}
+
+void
+ConcreteNetwork::clear()
+{
+  deleteTopInstance();
+  deleteCellNetworkViews();
+  library_seq_.deleteContentsClear();
+  library_map_.clear();
+  Network::clear();
+}
+
+void
+ConcreteNetwork::deleteTopInstance()
+{
+  if (top_instance_) {
+    deleteInstance(top_instance_);
+    top_instance_ = nullptr;
+  }
+}
+
+void
+ConcreteNetwork::deleteCellNetworkViews()
+{
+  CellNetworkViewMap::Iterator view_iter(cell_network_view_map_);
+  while (view_iter.hasNext()) {
+    Instance *view = view_iter.next();
+    if (view)
+      deleteInstance(view);
+  }
+  cell_network_view_map_.clear();
+}
+
+Instance *
+ConcreteNetwork::topInstance() const
+{
+  return top_instance_;
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteLibraryIterator1 : public Iterator<Library*>
+{
+public:
+  explicit ConcreteLibraryIterator1(const ConcreteLibrarySeq &lib_seq_);
+  virtual bool hasNext();
+  virtual Library *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteLibraryIterator1);
+
+  ConcreteLibraryIterator iter_;
+};
+
+ConcreteLibraryIterator1::ConcreteLibraryIterator1(const ConcreteLibrarySeq &lib_seq_):
+  iter_(lib_seq_)
+{
+}
+
+bool
+ConcreteLibraryIterator1::hasNext()
+{
+  return iter_.hasNext();
+}
+
+Library *
+ConcreteLibraryIterator1::next()
+{
+  return reinterpret_cast<Library*>(iter_.next());
+}
+
+LibraryIterator *
+ConcreteNetwork::libraryIterator() const
+{
+  return new ConcreteLibraryIterator1(library_seq_);
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteLibertyLibraryIterator : public Iterator<LibertyLibrary*>
+{
+public:
+  explicit ConcreteLibertyLibraryIterator(const ConcreteNetwork *network);
+  virtual ~ConcreteLibertyLibraryIterator();
+  virtual bool hasNext();
+  virtual LibertyLibrary *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteLibertyLibraryIterator);
+  void findNext();
+
+  ConcreteLibrarySeq::ConstIterator iter_;
+  LibertyLibrary *next_;
+};
+
+ConcreteLibertyLibraryIterator::
+ConcreteLibertyLibraryIterator(const ConcreteNetwork *network):
+  iter_(network->library_seq_),
+  next_(nullptr)
+{
+  findNext();
+}
+
+ConcreteLibertyLibraryIterator::~ConcreteLibertyLibraryIterator()
+{
+}
+
+bool
+ConcreteLibertyLibraryIterator::hasNext()
+{
+  return next_ != nullptr;
+}
+
+LibertyLibrary *
+ConcreteLibertyLibraryIterator::next()
+{
+  LibertyLibrary *next = next_;
+  findNext();
+  return next;
+}
+
+void
+ConcreteLibertyLibraryIterator::findNext()
+{
+  next_ = nullptr;
+  while (iter_.hasNext()) {
+    ConcreteLibrary *lib = iter_.next();
+    if (lib->isLiberty()) {
+      LibertyLibrary *liberty = static_cast<LibertyLibrary*>(lib);
+      if (liberty) {
+	next_ = liberty;
+	break;
+      }
+    }
+  }
+}
+
+LibertyLibraryIterator *
+ConcreteNetwork::libertyLibraryIterator() const
+{
+  return new ConcreteLibertyLibraryIterator(this);
+}
+
+////////////////////////////////////////////////////////////////
+
+Library *
+ConcreteNetwork::makeLibrary(const char *name,
+			     const char *filename)
+{
+  ConcreteLibrary *library = new ConcreteLibrary(name, filename, false);
+  addLibrary(library);
+  return reinterpret_cast<Library*>(library);
+}
+
+LibertyLibrary *
+ConcreteNetwork::makeLibertyLibrary(const char *name,
+				    const char *filename)
+{
+  LibertyLibrary *library = new LibertyLibrary(name, filename);
+  addLibrary(library);
+  return library;
+}
+
+void
+ConcreteNetwork::addLibrary(ConcreteLibrary *library)
+{
+  library_seq_.push_back(library);
+  library_map_[library->name()] = library;
+}
+
+Library *
+ConcreteNetwork::findLibrary(const char *name)
+{
+  return reinterpret_cast<Library*>(library_map_.findKey(name));
+}
+
+void
+ConcreteNetwork::deleteLibrary(Library *library)
+{
+  ConcreteLibrary *clib = reinterpret_cast<ConcreteLibrary*>(library);
+  library_map_.erase(clib->name());
+  library_seq_.eraseObject(clib);
+  delete clib;
+}
+
+const char *
+ConcreteNetwork::name(const Library *library) const
+{
+  const ConcreteLibrary *clib =
+    reinterpret_cast<const ConcreteLibrary*>(library);
+  return clib->name();
+}
+
+LibertyLibrary *
+ConcreteNetwork::findLiberty(const char *name)
+{
+  ConcreteLibrary *lib =  library_map_.findKey(name);
+  if (lib) {
+    if (lib->isLiberty())
+      return static_cast<LibertyLibrary*>(lib);
+    // Potential name conflict
+    else {
+      for (ConcreteLibrary *lib : library_seq_) {
+	if (stringEq(lib->name(), name)
+	    && lib->isLiberty())
+	  return static_cast<LibertyLibrary*>(lib);
+      }
+    }
+  }
+  return nullptr;
+}
+
+LibertyLibrary *
+ConcreteNetwork::libertyLibrary(Library *library) const
+{
+  ConcreteLibrary *lib = reinterpret_cast<ConcreteLibrary*>(library);
+  return static_cast<LibertyLibrary*>(lib);
+}
+
+Cell *
+ConcreteNetwork::makeCell(Library *library,
+			  const char *name,
+			  bool is_leaf,
+			  const char *filename)
+{
+  ConcreteLibrary *clib = reinterpret_cast<ConcreteLibrary*>(library);
+  return reinterpret_cast<Cell*>(clib->makeCell(name, is_leaf, filename));
+}
+
+Cell *
+ConcreteNetwork::findCell(const Library *library,
+			  const char *name) const
+{
+  const ConcreteLibrary *clib =
+    reinterpret_cast<const ConcreteLibrary*>(library);
+  return reinterpret_cast<Cell*>(clib->findCell(name));
+}
+
+Cell *
+ConcreteNetwork::findAnyCell(const char *name)
+{
+  ConcreteLibrarySeq::Iterator lib_iter(library_seq_);
+  while (lib_iter.hasNext()) {
+    ConcreteLibrary *lib = lib_iter.next();
+    ConcreteCell *cell = lib->findCell(name);
+    if (cell)
+      return reinterpret_cast<Cell*>(cell);
+  }
+  return nullptr;
+}
+
+void
+ConcreteNetwork::findCellsMatching(const Library *library,
+				   const PatternMatch *pattern,
+				   CellSeq *cells) const
+{
+  const ConcreteLibrary *clib =
+    reinterpret_cast<const ConcreteLibrary*>(library);
+  clib->findCellsMatching(pattern, cells);
+}
+
+void
+ConcreteNetwork::deleteCell(Cell *cell)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ConcreteLibrary *clib = ccell->library();
+  clib->deleteCell(ccell);
+}
+
+////////////////////////////////////////////////////////////////
+
+const char *
+ConcreteNetwork::name(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return ccell->name();
+}
+
+void
+ConcreteNetwork::setName(Cell *cell,
+			 const char *name)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ccell->setName(name);
+}
+
+void
+ConcreteNetwork::setIsLeaf(Cell *cell,
+			   bool is_leaf)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ccell->setIsLeaf(is_leaf);
+}
+
+Library *
+ConcreteNetwork::library(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return reinterpret_cast<Library*>(ccell->library());
+}
+
+LibertyCell *
+ConcreteNetwork::libertyCell(Cell *cell) const
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  return ccell->libertyCell();
+}
+
+const LibertyCell *
+ConcreteNetwork::libertyCell(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return ccell->libertyCell();
+}
+
+Cell *
+ConcreteNetwork::cell(LibertyCell *cell) const
+{
+  return reinterpret_cast<Cell*>(cell);
+}
+
+const Cell *
+ConcreteNetwork::cell(const LibertyCell *cell) const
+{
+  return reinterpret_cast<const Cell*>(cell);
+}
+
+const char *
+ConcreteNetwork::filename(const Cell *cell)
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return ccell->filename();
+}
+
+Port *
+ConcreteNetwork::findPort(const Cell *cell,
+			  const char *name) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return reinterpret_cast<Port*>(ccell->findPort(name));
+}
+
+void
+ConcreteNetwork::findPortsMatching(const Cell *cell,
+				   const PatternMatch *pattern,
+				   PortSeq *ports) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  ccell->findPortsMatching(pattern, ports);
+}
+
+bool
+ConcreteNetwork::isLeaf(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return ccell->isLeaf();
+}
+
+Port *
+ConcreteNetwork::makePort(Cell *cell,
+			  const char *name)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ConcretePort *port = ccell->makePort(name);
+  return reinterpret_cast<Port*>(port);
+}
+
+Port *
+ConcreteNetwork::makeBusPort(Cell *cell,
+			     const char *name,
+			     int from_index,
+			     int to_index)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ConcretePort *port = ccell->makeBusPort(name, from_index, to_index);
+  return reinterpret_cast<Port*>(port);
+}
+
+void
+ConcreteNetwork::groupBusPorts(Cell *cell,
+                               std::function<bool(const char*)> port_msb_first)
+{
+  Library *lib = library(cell);
+  ConcreteLibrary *clib = reinterpret_cast<ConcreteLibrary*>(lib);
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ccell->groupBusPorts(clib->busBrktLeft(), clib->busBrktRight(), port_msb_first);
+}
+
+Port *
+ConcreteNetwork::makeBundlePort(Cell *cell,
+				const char *name,
+				PortSeq *members)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  ConcretePortSeq *cmembers = reinterpret_cast<ConcretePortSeq*>(members);
+  ConcretePort *port = ccell->makeBundlePort(name, cmembers);
+  return reinterpret_cast<Port*>(port);
+}
+
+void
+ConcreteNetwork::setDirection(Port *port,
+			      PortDirection *dir)
+{
+  ConcretePort *cport = reinterpret_cast<ConcretePort*>(port);
+  cport->setDirection(dir);
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteCellPortIterator1 : public CellPortIterator
+{
+public:
+  explicit ConcreteCellPortIterator1(const ConcreteCell *cell);
+  ~ConcreteCellPortIterator1();
+  virtual bool hasNext() { return iter_->hasNext(); }
+  virtual Port *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteCellPortIterator1);
+
+  ConcreteCellPortIterator *iter_;
+};
+
+ConcreteCellPortIterator1::ConcreteCellPortIterator1(const ConcreteCell *cell):
+  iter_(cell->portIterator())
+{
+}
+
+ConcreteCellPortIterator1::~ConcreteCellPortIterator1()
+{
+  delete iter_;
+}
+
+Port *
+ConcreteCellPortIterator1::next()
+{
+  return reinterpret_cast<Port*>(iter_->next());
+}
+
+CellPortIterator *
+ConcreteNetwork::portIterator(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return new ConcreteCellPortIterator1(ccell);
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcreteCellPortBitIterator1 : public CellPortIterator
+{
+public:
+  explicit ConcreteCellPortBitIterator1(const ConcreteCell *cell);
+  ~ConcreteCellPortBitIterator1();
+  virtual bool hasNext() { return iter_->hasNext(); }
+  virtual Port *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteCellPortBitIterator1);
+
+  ConcreteCellPortBitIterator *iter_;
+};
+
+ConcreteCellPortBitIterator1::ConcreteCellPortBitIterator1(const ConcreteCell *cell):
+  iter_(cell->portBitIterator())
+{
+}
+
+ConcreteCellPortBitIterator1::~ConcreteCellPortBitIterator1()
+{
+  delete iter_;
+}
+
+Port *
+ConcreteCellPortBitIterator1::next()
+{
+  return reinterpret_cast<Port*>(iter_->next());
+}
+
+CellPortBitIterator *
+ConcreteNetwork::portBitIterator(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return new ConcreteCellPortBitIterator1(ccell);
+}
+
+int
+ConcreteNetwork::portBitCount(const Cell *cell) const
+{
+  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
+  return ccell->portBitCount();
+}
+
+////////////////////////////////////////////////////////////////
+
+const char *
+ConcreteNetwork::name(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->name();
+}
+
+Cell *
+ConcreteNetwork::cell(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->cell();
+}
+
+LibertyPort *
+ConcreteNetwork::libertyPort(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->libertyPort();
+}
+
+PortDirection *
+ConcreteNetwork::direction(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->direction();
+}
+
+bool
+ConcreteNetwork::isBundle(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->isBundle();
+}
+
+bool
+ConcreteNetwork::isBus(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->isBus();
+}
+
+const char *
+ConcreteNetwork::busName(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->busName();
+}
+
+int
+ConcreteNetwork::size(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->size();
+}
+
+int
+ConcreteNetwork::fromIndex(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->fromIndex();
+}
+
+int
+ConcreteNetwork::toIndex(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->toIndex();
+}
+
+Port *
+ConcreteNetwork::findBusBit(const Port *port,
+			    int index) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return reinterpret_cast<Port*>(cport->findBusBit(index));
+}
+
+Port *
+ConcreteNetwork::findMember(const Port *port,
+			    int index) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return reinterpret_cast<Port*>(cport->findMember(index));
+}
+
+bool
+ConcreteNetwork::hasMembers(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return cport->hasMembers();
+}
+
+////////////////////////////////////////////////////////////////
+
+class ConcretePortMemberIterator1 : public PortMemberIterator
+{
+public:
+  explicit ConcretePortMemberIterator1(const ConcretePort *port);
+  ~ConcretePortMemberIterator1();
+  virtual bool hasNext() { return iter_->hasNext(); }
+  virtual Port *next();
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcretePortMemberIterator1);
+
+  ConcretePortMemberIterator *iter_;
+};
+
+ConcretePortMemberIterator1::ConcretePortMemberIterator1(const ConcretePort *
+							 port) :
+  iter_(port->memberIterator())
+{
+}
+
+ConcretePortMemberIterator1::~ConcretePortMemberIterator1()
+{
+  delete iter_;
+}
+
+Port *
+ConcretePortMemberIterator1::next()
+{
+  return reinterpret_cast<Port*>(iter_->next());
+}
+
+PortMemberIterator *
+ConcreteNetwork::memberIterator(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return new ConcretePortMemberIterator1(cport);
+}
+
+////////////////////////////////////////////////////////////////
+
+const char *
+ConcreteNetwork::name(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return inst->name();
+}
+
+Cell *
+ConcreteNetwork::cell(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return inst->cell();
+}
+
+Instance *
+ConcreteNetwork::parent(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return reinterpret_cast<Instance*>(inst->parent());
+}
+
+bool
+ConcreteNetwork::isLeaf(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(inst->cell());
+  return ccell->isLeaf();
+}
+
+Instance *
+ConcreteNetwork::findChild(const Instance *parent,
+			   const char *name) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(parent);
+  return inst->findChild(name);
+}
+
+Pin *
+ConcreteNetwork::findPin(const Instance *instance,
+			 const char *port_name) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return reinterpret_cast<Pin*>(inst->findPin(port_name));
+}
+
+Pin *
+ConcreteNetwork::findPin(const Instance *instance,
+			 const Port *port) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return reinterpret_cast<Pin*>(inst->findPin(port));
+}
+
+Net *
+ConcreteNetwork::findNet(const Instance *instance,
+			 const char *net_name) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return reinterpret_cast<Net*>(inst->findNet(net_name));
+}
+
+void
+ConcreteNetwork::findInstNetsMatching(const Instance *instance,
+				      const PatternMatch *pattern,
+				      NetSeq *nets) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  inst->findNetsMatching(pattern, nets);
+}
+
+////////////////////////////////////////////////////////////////
+
+InstanceChildIterator *
+ConcreteNetwork::childIterator(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return inst->childIterator();
+}
+
+InstancePinIterator *
+ConcreteNetwork::pinIterator(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  ConcreteCell *cell = reinterpret_cast<ConcreteCell*>(inst->cell());
+  int pin_count = cell->portBitCount();
+  return new ConcreteInstancePinIterator(inst, pin_count);
+}
+
+InstanceNetIterator *
+ConcreteNetwork::netIterator(const Instance *instance) const
+{
+  const ConcreteInstance *inst =
+    reinterpret_cast<const ConcreteInstance*>(instance);
+  return inst->netIterator();
+}
+
+////////////////////////////////////////////////////////////////
+
+Instance *
+ConcreteNetwork::instance(const Pin *pin) const
+{
+  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
+  return reinterpret_cast<Instance*>(cpin->instance());
+}
+
+Net *
+ConcreteNetwork::net(const Pin *pin) const
+{
+  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
+  return reinterpret_cast<Net*>(cpin->net());
+}
+
+Term *
+ConcreteNetwork::term(const Pin *pin) const
+{
+  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
+  return reinterpret_cast<Term*>(cpin->term());
+}
+
+Port *
+ConcreteNetwork::port(const Pin *pin) const
+{
+  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
+  return reinterpret_cast<Port*>(cpin->port());
+}
+
+PortDirection *
+ConcreteNetwork::direction(const Pin *pin) const
+{
+  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
+  const ConcretePort *cport = cpin->port();
+  return cport->direction();
+}
+
+VertexId
+ConcreteNetwork::vertexId(const Pin *pin) const
+{
+  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
+  return cpin->vertexId();
+}
+
+void
+ConcreteNetwork::setVertexId(Pin *pin,
+			     VertexId id)
+{
+  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
+  cpin->setVertexId(id);
+}
+
+////////////////////////////////////////////////////////////////
+
+Net *
+ConcreteNetwork::net(const Term *term) const
+{
+  const ConcreteTerm *cterm = reinterpret_cast<const ConcreteTerm*>(term);
+  return reinterpret_cast<Net*>(cterm->net());
+}
+
+Pin *
+ConcreteNetwork::pin(const Term *term) const
+{
+  const ConcreteTerm *cterm = reinterpret_cast<const ConcreteTerm*>(term);
+  return reinterpret_cast<Pin*>(cterm->pin());
+}
+
+////////////////////////////////////////////////////////////////
+
+const char *
+ConcreteNetwork::name(const Net *net) const
+{
+  const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
+  return cnet->name();
+}
+
+Instance *
+ConcreteNetwork::instance(const Net *net) const
+{
+  const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
+  return reinterpret_cast<Instance*>(cnet->instance());
+}
+
+bool
+ConcreteNetwork::isPower(const Net *net) const
+{
+  return constant_nets_[int(LogicValue::one)].hasKey(const_cast<Net*>(net));
+}
+
+bool
+ConcreteNetwork::isGround(const Net *net) const
+{
+  return constant_nets_[int(LogicValue::zero)].hasKey(const_cast<Net*>(net));
+}
+
+NetPinIterator *
+ConcreteNetwork::pinIterator(const Net *net) const
+{
+  const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
+  return new ConcreteNetPinIterator(cnet);
+}
+
+NetTermIterator *
+ConcreteNetwork::termIterator(const Net *net) const
+{
+  const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
+  return new ConcreteNetTermIterator(cnet);
+}
+
+void
+ConcreteNetwork::mergeInto(Net *net,
+			   Net *into_net)
+{
+  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
+  ConcreteNet *cinto_net = reinterpret_cast<ConcreteNet*>(into_net);
+  cnet->mergeInto(cinto_net);
+  clearNetDrvrPinMap();
+}
+
+Net *
+ConcreteNetwork::mergedInto(Net *net)
+{
+  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
+  return reinterpret_cast<Net*>(cnet->mergedInto());
+}
+
+////////////////////////////////////////////////////////////////
+
+Cell *
+ConcreteInstance::cell() const
+{
+  return reinterpret_cast<Cell*>(cell_);
+}
+
+Instance *
+ConcreteNetwork::makeInstance(Cell *cell,
+			      const char *name,
+			      Instance *parent)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  return makeConcreteInstance(ccell, name, parent);
+}
+
+Instance *
+ConcreteNetwork::makeInstance(LibertyCell *cell,
+			      const char *name,
+			      Instance *parent)
+{
+  return makeConcreteInstance(cell, name, parent);
+}
+
+Instance *
+ConcreteNetwork::makeConcreteInstance(ConcreteCell *cell,
+				      const char *name,
+				      Instance *parent)
+{
+  ConcreteInstance *cparent =
+    reinterpret_cast<ConcreteInstance*>(parent);
+  ConcreteInstance *inst = new ConcreteInstance(cell, name, cparent);
+  if (parent)
+    cparent->addChild(inst);
+  return reinterpret_cast<Instance*>(inst);
+}
+
+void
+ConcreteNetwork::makePins(Instance *inst)
+{
+  CellPortBitIterator *port_iterator = portBitIterator(cell(inst));
+  while (port_iterator->hasNext()) {
+    Port *port = port_iterator->next();
+    makePin(inst, port, nullptr);
+  }
+  delete port_iterator;
+}
+
+void
+ConcreteNetwork::replaceCell(Instance *inst,
+			     Cell *cell)
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
+  int port_count = ccell->portBitCount();
+  ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
+  // Port count picked from Instance instead of Target cells-Dinesh A
+  ConcreteCell *instcell = reinterpret_cast<ConcreteCell*>(cinst->cell());
+  int inst_port_count = instcell->portBitCount();
+  ConcretePin **pins = cinst->pins_;
+  ConcretePin **rpins = new ConcretePin*[port_count];
+  for (int i = 0; i < port_count; i++) 
+    rpins[i] = pins[inst_port_count-1];
+  for (int i = 0; i < inst_port_count; i++) {
+    ConcretePin *cpin = pins[i];
+    if (cpin) {
+      ConcretePort *pin_cport = reinterpret_cast<ConcretePort*>(cpin->port());
+      ConcretePort *cport = ccell->findPort(pin_cport->name());
+      if (cport) {
+        rpins[cport->pinIndex()] = cpin;
+        cpin->port_ = cport;
+      }
+    }
+  }
+  delete [] pins;
+  cinst->pins_ = rpins;
+  cinst->setCell(ccell);
+}
+
+void
+ConcreteNetwork::deleteInstance(Instance *inst)
+{
+  ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
+
+  // Delete nets first (so children pin deletes are not required).
+  ConcreteInstanceNetMap::Iterator net_iter(cinst->nets_);
+  while (net_iter.hasNext()) {
+    ConcreteNet *cnet = net_iter.next();
+    Net *net = reinterpret_cast<Net*>(cnet);
+    // Delete terminals connected to net.
+    NetTermIterator *term_iter = termIterator(net);
+    while (term_iter->hasNext()) {
+      ConcreteTerm *term = reinterpret_cast<ConcreteTerm*>(term_iter->next());
+      delete term;
+    }
+    delete term_iter;
+    deleteNet(net);
+  }
+
+  // Delete children.
+  InstanceChildIterator *child_iter = childIterator(inst);
+  while (child_iter->hasNext()) {
+    Instance *child = child_iter->next();
+    deleteInstance(child);
+  }
+  delete child_iter;
+
+  InstancePinIterator *pin_iter = pinIterator(inst);
+  while (pin_iter->hasNext()) {
+    Pin *pin = pin_iter->next();
+    deletePin(pin);
+  }
+  delete pin_iter;
+
+  Instance *parent_inst = parent(inst);
+  if (parent_inst) {
+    ConcreteInstance *cparent =
+      reinterpret_cast<ConcreteInstance*>(parent_inst);
+    cparent->deleteChild(cinst);
+  }
+  delete cinst;
+}
+
+Pin *
+ConcreteNetwork::makePin(Instance *inst,
+			 Port *port,
+			 Net *net)
+{
+  ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
+  ConcretePort *cport = reinterpret_cast<ConcretePort*>(port);
+  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
+  ConcretePin *cpin = new ConcretePin(cinst, cport, cnet);
+  cinst->addPin(cpin);
+  if (cnet)
+    connectNetPin(cnet, cpin);
+  return reinterpret_cast<Pin*>(cpin);
+}
+
+Term *
+ConcreteNetwork::makeTerm(Pin *pin,
+			  Net *net)
+{
+  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
+  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
+  ConcreteTerm *cterm = new ConcreteTerm(cpin, cnet);
+  if (cnet)
+    cnet->addTerm(cterm);
+  cpin->term_ = cterm;
+  return reinterpret_cast<Term*>(cterm);
+}
+
+Pin *
+ConcreteNetwork::connect(Instance *inst,
+			 LibertyPort *port,
+			 Net *net)
+{
+  return connect(inst, reinterpret_cast<Port*>(port), net);
+}
+
+Pin *
+ConcreteNetwork::connect(Instance *inst,
+			 Port *port,
+			 Net *net)
+{
+  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
+  ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
+  ConcretePort *cport = reinterpret_cast<ConcretePort*>(port);
+  ConcretePin *cpin = cinst->findPin(port);
+  if (cpin) {
+    ConcreteNet *prev_net = cpin->net_;
+    if (prev_net)
+      disconnectNetPin(prev_net, cpin);
+  }
+  else {
+    cpin = new ConcretePin(cinst, cport, cnet);
+    cinst->addPin(cpin);
+  }
+  if (inst == top_instance_) {
+    // makeTerm
+    ConcreteTerm *cterm = new ConcreteTerm(cpin, cnet);
+    cnet->addTerm(cterm);
+    cpin->term_ = cterm;
+    cpin->net_ = nullptr;
+  }
+  else {
+    cpin->net_ = cnet;
+    connectNetPin(cnet, cpin);
+  }
+  return reinterpret_cast<Pin*>(cpin);
+}
+
+void
+ConcreteNetwork::connectNetPin(ConcreteNet *cnet,
+			       ConcretePin *cpin)
+{
+  cnet->addPin(cpin);
+
+  // If there are no terminals the net does not span hierarchy levels
+  // and it is safe to incrementally update the drivers.
+  Pin *pin = reinterpret_cast<Pin*>(cpin);
+  if (isDriver(pin)) {
+    if (cnet->terms_ == nullptr) {
+      Net *net = reinterpret_cast<Net*>(cnet);
+      PinSet *drvrs = net_drvr_pin_map_.findKey(net);
+      if (drvrs)
+	drvrs->insert(pin);
+    }
+    else
+      clearNetDrvrPinMap();
+  }
+}
+
+void
+ConcreteNetwork::disconnectPin(Pin *pin)
+{
+  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
+  if (reinterpret_cast<Instance*>(cpin->instance()) == top_instance_) {
+    ConcreteTerm *cterm = cpin->term_;
+    if (cterm) {
+      ConcreteNet *cnet = cterm->net_;
+      if (cnet) {
+	cnet->deleteTerm(cterm);
+	clearNetDrvrPinMap();
+      }
+      cpin->term_ = nullptr;
+      delete cterm;
+    }
+  }
+  else {
+    ConcreteNet *cnet = cpin->net();
+    if (cnet)
+      disconnectNetPin(cnet, cpin);
+    cpin->net_ = nullptr;
+  }
+}
+
+void
+ConcreteNetwork::disconnectNetPin(ConcreteNet *cnet,
+				  ConcretePin *cpin)
+{
+  cnet->deletePin(cpin);
+
+  Pin *pin = reinterpret_cast<Pin*>(cpin);
+  if (isDriver(pin)) {
+    ConcreteNet *cnet = cpin->net();
+    // If there are no terminals the net does not span hierarchy levels
+    // and it is safe to incrementally update the drivers.
+    if (cnet->terms_ == nullptr) {
+      Net *net = reinterpret_cast<Net*>(cnet);
+      PinSet *drvrs = net_drvr_pin_map_.findKey(net);
+      if (drvrs)
+	drvrs->erase(pin);
+    }
+    else
+      clearNetDrvrPinMap();
+  }
+}
+
+void
+ConcreteNetwork::deletePin(Pin *pin)
+{
+  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
+  ConcreteNet *cnet = cpin->net();
+  if (cnet)
+    disconnectNetPin(cnet, cpin);
+  ConcreteInstance *cinst =
+    reinterpret_cast<ConcreteInstance*>(cpin->instance());
+  if (cinst)
+    cinst->deletePin(cpin);
+  delete cpin;
+}
+
+Net *
+ConcreteNetwork::makeNet(const char *name,
+			 Instance *parent)
+{
+  ConcreteInstance *cparent = reinterpret_cast<ConcreteInstance*>(parent);
+  ConcreteNet *net = new ConcreteNet(name, cparent);
+  cparent->addNet(net);
+  return reinterpret_cast<Net*>(net);
+}
+
+void
+ConcreteNetwork::deleteNet(Net *net)
+{
+  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
+  ConcreteNetPinIterator pin_iter(cnet);
+  while (pin_iter.hasNext()) {
+    ConcretePin *pin = reinterpret_cast<ConcretePin*>(pin_iter.next());
+    // Do NOT use net->disconnectPin because it would be N^2
+    // to delete all of the pins from the net.
+    pin->net_ = nullptr;
+  }
+
+  constant_nets_[int(LogicValue::zero)].erase(net);
+  constant_nets_[int(LogicValue::one)].erase(net);
+  PinSet *drvrs = net_drvr_pin_map_.findKey(net);
+  if (drvrs) {
+    delete drvrs;
+    net_drvr_pin_map_.erase(net);
+  }
+
+  ConcreteInstance *cinst =
+    reinterpret_cast<ConcreteInstance*>(cnet->instance());
+  cinst->deleteNet(cnet);
+  delete cnet;
+}
+
+void
+ConcreteNetwork::clearConstantNets()
+{
+  constant_nets_[int(LogicValue::zero)].clear();
+  constant_nets_[int(LogicValue::one)].clear();
+}
+
+void
+ConcreteNetwork::addConstantNet(Net *net,
+				LogicValue value)
+{
+  if (value == LogicValue::zero
+      || value == LogicValue::one)
+    constant_nets_[int(value)].insert(net);
+}
+
+ConstantPinIterator *
+ConcreteNetwork::constantPinIterator()
+{
+  return new NetworkConstantPinIterator(this,
+					constant_nets_[int(LogicValue::zero)],
+					constant_nets_[int(LogicValue::one)]);
+}
+
+////////////////////////////////////////////////////////////////
+
+// Optimized version of Network::visitConnectedPins.
+void
+ConcreteNetwork::visitConnectedPins(const Net *net,
+				    PinVisitor &visitor,
+				    ConstNetSet &visited_nets) const
+{
+  if (!visited_nets.hasKey(net)) {
+    visited_nets.insert(net);
+    // Search up from net terminals.
+    const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
+    for (ConcreteTerm *term = cnet->terms_; term; term = term->net_next_) {
+      ConcretePin *above_pin = term->pin_;
+      if (above_pin) {
+	ConcreteNet *above_net = above_pin->net_;
+	if (above_net)
+	  visitConnectedPins(reinterpret_cast<Net*>(above_net),
+			     visitor, visited_nets);
+	else
+	  visitor(reinterpret_cast<Pin*>(above_pin));
+      }
+    }
+
+    // Search down from net pins.
+    for (ConcretePin *pin = cnet->pins_; pin; pin = pin->net_next_) {
+      visitor(reinterpret_cast<Pin*>(pin));
+      ConcreteTerm *below_term = pin->term_;
+      if (below_term) {
+	ConcreteNet *below_net = below_term->net_;
+	if (below_net)
+	  visitConnectedPins(reinterpret_cast<Net*>(below_net),
+			     visitor, visited_nets);
+      }
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+ConcreteInstance::ConcreteInstance(ConcreteCell *cell,
+				   const char *name,
+				   ConcreteInstance *parent) :
+  cell_(cell),
+  name_(stringCopy(name)),
+  parent_(parent),
+  children_(nullptr),
+  nets_(nullptr)
+{
+  initPins();
+}
+
+void
+ConcreteInstance::initPins()
+{
+  int pin_count = reinterpret_cast<ConcreteCell*>(cell_)->portBitCount();
+  if (pin_count) {
+    pins_ = new ConcretePin*[pin_count];
+    for (int i = 0; i < pin_count; i++)
+      pins_[i] = nullptr;
+  }
+  else
+    pins_ = nullptr;
+}
+
+ConcreteInstance::~ConcreteInstance()
+{
+  stringDelete(name_);
+  delete [] pins_;
+  delete children_;
+  delete nets_;
+}
+
+Instance *
+ConcreteInstance::findChild(const char *name) const
+{
+  if (children_)
+    return reinterpret_cast<Instance*>(children_->findKey(name));
+  else
+    return nullptr;
+}
+
+ConcretePin *
+ConcreteInstance::findPin(const char *port_name) const
+{
+  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell_);
+  const ConcretePort *cport =
+    reinterpret_cast<const ConcretePort*>(ccell->findPort(port_name));
+  if (cport
+      && !cport->isBus())
+    return pins_[cport->pinIndex()];
+  else
+    return nullptr;
+}
+
+ConcretePin *
+ConcreteInstance::findPin(const Port *port) const
+{
+  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
+  return pins_[cport->pinIndex()];
+}
+
+ConcreteNet *
+ConcreteInstance::findNet(const char *net_name) const
+{
+  ConcreteNet *net = nullptr;
+  if (nets_) {
+    net = nets_->findKey(net_name);
+    // Follow merge pointer to surviving net.
+    if (net) {
+      while (net->mergedInto())
+	net = net->mergedInto();
+    }
+  }
+  return net;
+}
+
+void
+ConcreteInstance::findNetsMatching(const PatternMatch *pattern,
+				   NetSeq *nets) const
+{
+  if (pattern->hasWildcards()) {
+    ConcreteInstanceNetMap::Iterator net_iter(nets_);
+    while (net_iter.hasNext()) {
+      const char *net_name;
+      ConcreteNet *cnet;
+      net_iter.next(net_name, cnet);
+      if (pattern->match(net_name))
+	nets->push_back(reinterpret_cast<Net*>(cnet));
+    }
+  }
+  else {
+    ConcreteNet *cnet = findNet(pattern->pattern());
+    if (cnet)
+      nets->push_back(reinterpret_cast<Net*>(cnet));
+  }
+}
+
+InstanceNetIterator *
+ConcreteInstance::netIterator() const
+{
+  return reinterpret_cast<InstanceNetIterator*>
+    (new ConcreteInstanceNetIterator(nets_));
+}
+
+InstanceChildIterator *
+ConcreteInstance::childIterator() const
+{
+  return new ConcreteInstanceChildIterator(children_);
+}
+
+void
+ConcreteInstance::addChild(ConcreteInstance *child)
+{
+  if (children_ == nullptr)
+    children_ = new ConcreteInstanceChildMap;
+  (*children_)[child->name()] = child;
+}
+
+void
+ConcreteInstance::deleteChild(ConcreteInstance *child)
+{
+  children_->erase(child->name());
+}
+
+void
+ConcreteInstance::addPin(ConcretePin *pin)
+{
+  ConcretePort *cport = reinterpret_cast<ConcretePort *>(pin->port());
+  pins_[cport->pinIndex()] = pin;
+}
+
+void
+ConcreteInstance::deletePin(ConcretePin *pin)
+{
+  ConcretePort *cport = reinterpret_cast<ConcretePort *>(pin->port());
+  pins_[cport->pinIndex()] = nullptr;
+}
+
+void
+ConcreteInstance::addNet(ConcreteNet *net)
+{
+  if (nets_ == nullptr)
+    nets_ = new ConcreteInstanceNetMap;
+  (*nets_)[net->name()] = net;
+}
+
+void
+ConcreteInstance::addNet(const char *name,
+			 ConcreteNet *net)
+{
+  if (nets_ == nullptr)
+    nets_ = new ConcreteInstanceNetMap;
+  (*nets_)[name] = net;
+}
+
+void
+ConcreteInstance::deleteNet(ConcreteNet *net)
+{
+  nets_->erase(net->name());
+}
+
+void
+ConcreteInstance::setCell(ConcreteCell *cell)
+{
+  cell_ = cell;
+}
+
+////////////////////////////////////////////////////////////////
+
+ConcretePin::ConcretePin(ConcreteInstance *instance,
+			 ConcretePort *port,
+			 ConcreteNet *net) :
+  instance_(instance),
+  port_(port),
+  net_(net),
+  term_(nullptr),
+  net_next_(nullptr),
+  net_prev_(nullptr),
+  vertex_id_(vertex_id_null)
+{
+}
+
+const char *
+ConcretePin::name() const
+{
+  return port_->name();
+}
+
+void
+ConcretePin::setVertexId(VertexId id)
+{
+  vertex_id_ = id;
+}
+
+////////////////////////////////////////////////////////////////
+
+const char *
+ConcreteTerm::name() const
+{
+  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin_);
+  const ConcretePort *cport =
+    reinterpret_cast<const ConcretePort*>(cpin->port());
+  return cport->name();
+}
+
+ConcreteTerm::ConcreteTerm(ConcretePin *pin,
+			   ConcreteNet *net) :
+  pin_(pin),
+  net_(net),
+  net_next_(nullptr)
+{
+}
+
+////////////////////////////////////////////////////////////////
+
+ConcreteNet::ConcreteNet(const char *name,
+			 ConcreteInstance *instance) :
+  name_(stringCopy(name)),
+  instance_(instance),
+  pins_(nullptr),
+  terms_(nullptr),
+  merged_into_(nullptr)
+{
+}
+
+ConcreteNet::~ConcreteNet()
+{
+  stringDelete(name_);
+}
+
+// Merged nets are kept around to serve as name aliases.
+// Only Instance::findNet and InstanceNetIterator need to know
+// the net has been merged.
+void
+ConcreteNet::mergeInto(ConcreteNet *net)
+{
+  ConcreteNetPinIterator pin_iter(this);
+  while (pin_iter.hasNext()) {
+    Pin *pin = pin_iter.next();
+    ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
+    net->addPin(cpin);
+    cpin->net_ = net;
+  }
+  pins_ = nullptr;
+  ConcreteNetTermIterator term_iter(this);
+  while (term_iter.hasNext()) {
+    Term *term = term_iter.next();
+    ConcreteTerm *cterm = reinterpret_cast<ConcreteTerm*>(term);
+    net->addTerm(cterm);
+    cterm->net_ = net;
+  }
+  terms_ = nullptr;
+  // Leave name map pointing to merged net because otherwise a top
+  // level merged net has no pointer to it and it is leaked.
+  merged_into_ = net;
+}
+
+void
+ConcreteNet::addPin(ConcretePin *pin)
+{
+  if (pins_)
+    pins_->net_prev_ = pin;
+  pin->net_next_ = pins_;
+  pin->net_prev_ = nullptr;
+  pins_ = pin;
+}
+
+void
+ConcreteNet::deletePin(ConcretePin *pin)
+{
+  ConcretePin *prev = pin->net_prev_;
+  ConcretePin *next = pin->net_next_;
+  if (prev)
+    prev->net_next_ = next;
+  if (next)
+    next->net_prev_ = prev;
+  if (pins_ == pin)
+    pins_ = next;
+}
+
+void
+ConcreteNet::addTerm(ConcreteTerm *term)
+{
+  ConcreteTerm *next = terms_;
+  terms_ = term;
+  term->net_next_ = next;
+}
+
+void
+ConcreteNet::deleteTerm(ConcreteTerm *term)
+{
+  ConcreteTerm *net_prev_term = nullptr;
+  for (ConcreteTerm *net_term=terms_;net_term;net_term=net_term->net_next_) {
+    if (net_term == term) {
+      if (net_prev_term)
+	net_prev_term->net_next_ = term->net_next_;
+      else
+	terms_ = term->net_next_;
+      break;
+    }
+    net_prev_term = net_term;
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+typedef Map<Net*, Net*> BindingMap;
+
+// Binding table used for linking/expanding network.
+class ConcreteBindingTbl
+{
+public:
+  explicit ConcreteBindingTbl(NetworkEdit *network);
+  Net *ensureBinding(Net *proto_net,
+		     Instance *parent);
+  Net *find(Net *net);
+  void bind(Net *proto_net,
+	    Net *clone_net);
+
+private:
+  DISALLOW_COPY_AND_ASSIGN(ConcreteBindingTbl);
+
+  BindingMap map_;
+  NetworkEdit *network_;
+};
+
+void
+ConcreteNetwork::setCellNetworkView(Cell *cell,
+				    Instance *inst)
+{
+  cell_network_view_map_[cell] = inst;
+}
+
+Instance *
+ConcreteNetwork::cellNetworkView(Cell *cell)
+{
+  return cell_network_view_map_.findKey(cell);
+}
+
+void
+ConcreteNetwork::readNetlistBefore()
+{
+  clearConstantNets();
+  deleteTopInstance();
+  clearNetDrvrPinMap();
+}
+
+void
+ConcreteNetwork::setTopInstance(Instance *top_inst)
+{
+  if (top_instance_) {
+    deleteInstance(top_instance_);
+    clearConstantNets();
+    clearNetDrvrPinMap();
+  }
+  top_instance_ = top_inst;
+}
+
+void
+ConcreteNetwork::setLinkFunc(LinkNetworkFunc *link)
+{
+  link_func_ = link;
+}
+
+bool
+ConcreteNetwork::linkNetwork(const char *top_cell_name,
+			     bool make_black_boxes,
+			     Report *report)
+{
+  if (link_func_) {
+    clearConstantNets();
+    deleteTopInstance();
+    top_instance_ = link_func_(top_cell_name, make_black_boxes, report, this);
+    return top_instance_ != nullptr;
+  }
+  else {
+    report->error(8, "cell type %s can not be linked.", top_cell_name);
+    return false;
+  }
+}
+
+Instance *
+linkReaderNetwork(Cell *top_cell,
+		  bool, Report *,
+		  NetworkReader *network)
+{
+  Instance *view = network->cellNetworkView(top_cell);
+  if (view) {
+    // Seed the recursion for expansion with the top level instance.
+    Instance *top_instance = network->makeInstance(top_cell, "", nullptr);
+    ConcreteBindingTbl bindings(network);
+    makeClonePins(view, top_instance, view, &bindings, nullptr, nullptr, network);
+    InstanceChildIterator *child_iter = network->childIterator(view);
+    while (child_iter->hasNext()) {
+      Instance *child = child_iter->next();
+      makeChildNetwork(child, top_instance, &bindings, network);
+    }
+    delete child_iter;
+    network->deleteCellNetworkViews();
+    return top_instance;
+  }
+  return nullptr;
+}
+
+static void
+makeChildNetwork(Instance *proto,
+		 Instance *parent,
+		 ConcreteBindingTbl *parent_bindings,
+		 NetworkReader *network)
+{
+  Cell *proto_cell = network->cell(proto);
+  Instance *clone = network->makeInstance(proto_cell, network->name(proto),
+					  parent);
+  if (network->isLeaf(proto_cell))
+    makeClonePins(proto, clone, nullptr, nullptr, parent, parent_bindings, network);
+  else {
+    // Recurse if this isn't a leaf cell.
+    ConcreteBindingTbl bindings(network);
+    Instance *clone_view = network->cellNetworkView(proto_cell);
+    makeClonePins(proto, clone, clone_view, &bindings, parent,
+		  parent_bindings, network);
+    if (clone_view) {
+      InstanceChildIterator *child_iter = network->childIterator(clone_view);
+      while (child_iter->hasNext()) {
+	Instance *child = child_iter->next();
+	makeChildNetwork(child, clone, &bindings, network);
+      }
+      delete child_iter;
+    }
+  }
+}
+
+static void
+makeClonePins(Instance *proto,
+	      Instance *clone,
+	      Instance *clone_view,
+	      ConcreteBindingTbl *bindings,
+	      Instance *parent,
+	      ConcreteBindingTbl *parent_bindings,
+	      NetworkReader *network)
+{
+  InstancePinIterator *proto_pin_iter = network->pinIterator(proto);
+  while (proto_pin_iter->hasNext()) {
+    Pin *proto_pin = proto_pin_iter->next();
+    Net *proto_net = network->net(proto_pin);
+    Port *proto_port = network->port(proto_pin);
+    Net *clone_net = nullptr;
+    if (proto_net && parent_bindings)
+      clone_net = parent_bindings->ensureBinding(proto_net, parent);
+    Pin *clone_pin = network->connect(clone, proto_port, clone_net);
+    if (clone_view) {
+      Pin *clone_proto_pin = network->findPin(clone_view, proto_port);
+      Net *clone_proto_net = network->net(clone_proto_pin);
+      Net *clone_child_net = nullptr;
+      if (clone_proto_net)
+	clone_child_net = bindings->ensureBinding(clone_proto_net, clone);
+      network->makeTerm(clone_pin, clone_child_net);
+    }
+  }
+  delete proto_pin_iter;
+}
+
+////////////////////////////////////////////////////////////////
+
+ConcreteBindingTbl::ConcreteBindingTbl(NetworkEdit *network) :
+  network_(network)
+{
+}
+
+// Follow the merged_into pointers rather than update the
+// binding tables up the call tree when nodes are merged
+// because the name changes up the hierarchy.
+Net *
+ConcreteBindingTbl::find(Net *proto_net)
+{
+  ConcreteNet *net = reinterpret_cast<ConcreteNet*>(map_.findKey(proto_net));
+  while (net && net->mergedInto())
+    net = net->mergedInto();
+  return reinterpret_cast<Net*>(net);
+}
+
+void
+ConcreteBindingTbl::bind(Net *proto_net,
+			 Net *net)
+{
+  map_[proto_net] = net;
+}
+
+Net *
+ConcreteBindingTbl::ensureBinding(Net *proto_net,
+				  Instance *parent)
+{
+  Net *net = find(proto_net);
+  if (net == nullptr) {
+    net = network_->makeNet(network_->name(proto_net), parent);
+    map_[proto_net] = net;
+  }
+  return net;
+}
+
+} // namespace
diff --git a/hacks/src/OpenSTA/tcl/NetworkEdit.tcl b/hacks/src/OpenSTA/tcl/NetworkEdit.tcl
new file mode 100644
index 0000000..9df729d
--- /dev/null
+++ b/hacks/src/OpenSTA/tcl/NetworkEdit.tcl
@@ -0,0 +1,262 @@
+# OpenSTA, Static Timing Analyzer
+# Copyright (c) 2022, Parallax Software, Inc.
+# 
+# This program is free software: 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 3 of the License, or
+# (at your option) any later version.
+# 
+# This program 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 program. If not, see <https://www.gnu.org/licenses/>.
+
+# Network editing commands.
+
+namespace eval sta {
+
+proc connect_pin { net pin } {
+  set insts_port [parse_connect_pin $pin]
+  if { $insts_port == 0 } {
+    return 0
+  }
+  set net [get_net_warn "net" $net]
+  if { $net == "NULL" } {
+    return 0
+  }
+  lassign $insts_port inst port
+  connect_pin_cmd $inst $port $net
+  return 1
+}
+
+proc parse_connect_pin { arg } {
+  set path_regexp [path_regexp]
+  set insts_port {}
+  if { [is_object $arg] } {
+    set object_type [object_type $arg]
+    if { $object_type == "Pin" } {
+      set pin $arg
+      set inst [$pin instance]
+      set port [$pin port]
+    } elseif { $object_type == "Port" } {
+      # Explicit port arg - convert to pin.
+      set pin [find_pin [get_name $arg]]
+      set inst [$pin instance]
+      set port [$pin port]
+    } else {
+      sta_error 586 "unsupported object type $object_type."
+    }
+  } else {
+    if {[regexp $path_regexp $arg ignore path_name port_name]} {
+      set inst [find_instance $path_name]
+      if { $inst == "NULL" } {
+	return 0
+      }
+    } else {
+      set inst [top_instance]
+      set port_name $arg
+    }
+    set cell [$inst cell]
+    set port [$cell find_port $port_name]
+    if { $port == "NULL" } {
+      return 0
+    }
+    set pin [$inst find_pin $port_name]
+  }
+  
+  # Make sure the pin is not currently connected to a net.
+  if { $pin != "NULL" \
+	 && ![$pin is_hierarchical] \
+	 && [$pin net] != "NULL" } {
+    return 0
+  }
+  return [list $inst $port]
+}
+
+proc connect_pins { net pins } {
+  sta_warn 372 "connect_pins is deprecated.  Use connect_pin."
+  # Visit the pins to make sure command will succeed.
+  set insts_ports [parse_connect_pins $pins]
+  if { $insts_ports == 0 } {
+    return 0
+  }
+  set net [get_net_warn "net" $net]
+  if { $net == "NULL" } {
+    return 0
+  }
+  foreach {inst port} $insts_ports {
+    connect_pin_cmd $inst $port $net
+  }
+  return 1
+}
+
+proc parse_connect_pins { arg } {
+  set path_regexp [path_regexp]
+  set inst_ports {}
+  # Copy backslashes that will be removed by foreach.
+  set arg [string map {\\ \\\\} $arg]
+  foreach obj $arg {
+    set inst_port [parse_connect_pin $obj]
+    if { $inst_port == 0 } {
+      return 0
+    }
+    set inst_ports [concat $inst_ports $inst_port]
+  }
+  return $inst_ports
+}
+
+################################################################
+
+proc delete_instance { instance } {
+  if { [is_object $instance] } {
+    set object_type [object_type $instance]
+    if { $object_type == "Instance" } {
+      set inst $obj
+    } else {
+      sta_error 587 "unsupported object type $object_type."
+    }
+  } else {
+    set inst [find_instance $instance]
+  }
+  if { $inst != "NULL" } {
+    delete_instance_cmd $inst
+  }
+}
+
+################################################################
+
+proc delete_net { net } {
+  if { [is_object $net] } {
+    set object_type [object_type $net]
+    if { $object_type != "Net" } {
+      sta_error 588 "unsupported object type $object_type."
+    }
+  } else {
+    set net [find_net $net]
+  }
+  if { $net != "NULL" } {
+    delete_net_cmd $net
+  }
+}
+
+################################################################
+
+proc disconnect_pin { net pin } {
+  set net [get_net_warn "net" $net]
+  if { $net == "NULL" } {
+    return 0
+  }
+  if { $pin == "-all" } {
+    set iter [$net connected_pin_iterator]
+    while {[$iter has_next]} {
+      set pin [$iter next]
+      disconnect_pin_cmd $pin
+    }
+    $iter finish
+    return 1
+  } else {
+    set pin1 [get_port_pin_warn "pin" $pin]
+    if { $pin1 == "NULL" } {
+      return 0
+    } else {
+      disconnect_pin_cmd $pin1
+      return 1
+    }
+  }
+}
+
+proc disconnect_pins { net pins } {
+  sta_warn 603 "disconnect_pins is deprecated.  Use disconnect_pin."
+  foreach pin $pins {
+    disconnect_pin $net $pins
+  }
+}
+
+################################################################
+
+proc make_instance { inst_path lib_cell } {
+  set lib_cell [get_lib_cell_warn "lib_cell" $lib_cell]
+  if { $lib_cell != "NULL" } {
+    set path_regexp [path_regexp]
+    if {[regexp $path_regexp $inst_path ignore path_name inst_name]} {
+      set parent [find_instance $path_name]
+      if { $parent == "NULL" } {
+	# Parent instance not found.  This could be a typo, but since
+	# SDC does not escape hierarchy dividers it can also be
+	# an escaped name.
+	set inst_name $inst_path
+	set parent [top_instance]
+      }
+    } else {
+      set inst_name $inst_path
+      set parent [top_instance]
+    }
+    return [make_instance_cmd $inst_name $lib_cell $parent]
+  } else {
+    return 0
+  }
+}
+
+################################################################
+
+proc make_net { net_path } {
+  # Copy backslashes that will be removed by foreach.
+  set net_path [string map {\\ \\\\} $net_path]
+  set path_regexp [path_regexp]
+  if {[regexp $path_regexp $net_path ignore path_name net_name]} {
+    set parent [find_instance $path_name]
+    if { $parent == "NULL" } {
+      return 0
+    }
+  } else {
+    set parent [top_instance]
+    set net_name $net_path
+  }
+  return [make_net_cmd $net_name $parent]
+}
+
+################################################################
+
+proc replace_cell { instance lib_cell } {
+  set cell [get_lib_cell_warn "lib_cell" $lib_cell]
+  if { $cell != "NULL" } {
+    set inst [get_instance_error "instance" $instance]
+    set inst_cell [$inst liberty_cell]
+    if { $inst_cell == "NULL" \
+	   || ![equiv_cell_ports $inst_cell $cell] } {
+      return 0
+    }
+    replace_cell_cmd $inst $cell
+    return 1
+  } else {
+    return 0
+  }
+}
+
+proc replace_to_scan_cell { instance } {
+  set inst [get_instance_error "instance" $instance]
+  set inst_cell [get_full_name [$inst liberty_cell]]
+  #Target scan cell __d to __sd
+  #example sky130_fd_sc_hd__dfrtp_2 to sky130_fd_sc_hd__sdfrtp_2
+  set inst_scell [regsub -all "__d" $inst_cell "__sd"]
+  puts "Info: Scan Swapping => Instance:$instance From:$inst_cell to:$inst_scell";
+  if { $inst_cell == "NULL"} {
+    return 0
+  }
+  set scell [get_lib_cell_warn "lib_cell" $inst_scell]
+  replace_cell_cmd $inst $scell
+  return 1
+}
+
+proc path_regexp {} {
+  global hierarchy_separator
+  set id_regexp "\[^${hierarchy_separator}\]+"
+  set prefix_regexp "${id_regexp}(?:${hierarchy_separator}${id_regexp})*"
+  return "^(${prefix_regexp})${hierarchy_separator}(${id_regexp})$"
+}
+
+# sta namespace end.
+}
diff --git a/hacks/src/OpenSTA/tcl/Sta.tcl b/hacks/src/OpenSTA/tcl/Sta.tcl
new file mode 100644
index 0000000..64f5a08
--- /dev/null
+++ b/hacks/src/OpenSTA/tcl/Sta.tcl
@@ -0,0 +1,1557 @@
+# OpenSTA, Static Timing Analyzer
+# Copyright (c) 2022, Parallax Software, Inc.
+# 
+# This program is free software: 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 3 of the License, or
+# (at your option) any later version.
+# 
+# This program 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 program. If not, see <https://www.gnu.org/licenses/>.
+
+namespace eval sta {
+
+################################################################
+#
+# Non-SDC commands
+#
+################################################################
+
+define_cmd_args "delete_clock" {[-all] clocks}
+
+proc delete_clock { args } {
+  parse_key_args "delete_clock" args keys {} flags {-all}
+  if { [info exists flags(-all)] } {
+    check_argc_eq0 "delete_clock" $args
+    set clks [all_clocks]
+  } else {
+    check_argc_eq1 "delete_clock" $args
+    set clks [get_clocks_warn "clocks" [lindex $args 0]]
+  }
+  foreach clk $clks {
+    remove_clock_cmd $clk
+  }
+}
+
+################################################################
+
+define_cmd_args "delete_generated_clock" {[-all] clocks}
+
+proc delete_generated_clock { args } {
+  remove_gclk_cmd "delete_generated_clock" $args
+}
+
+################################################################
+
+define_cmd_args "set_disable_inferred_clock_gating" { objects }
+
+proc set_disable_inferred_clock_gating { objects } {
+  set_disable_inferred_clock_gating_cmd $objects
+}
+
+proc set_disable_inferred_clock_gating_cmd { objects } {
+  parse_inst_port_pin_arg $objects insts pins
+  foreach inst $insts {
+    disable_clock_gating_check_inst $inst
+  }
+  foreach pin $pins {
+    disable_clock_gating_check_pin $pin
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_case_analysis" {pins}
+
+proc unset_case_analysis { pins } {
+  set pins1 [get_port_pins_error "pins" $pins]
+  foreach pin $pins1 {
+    unset_case_analysis_cmd $pin
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_clock_groups" \
+  {[-logically_exclusive] [-physically_exclusive]\
+     [-asynchronous] [-name names] [-all]}
+				
+proc unset_clock_groups { args } {
+  unset_clk_groups_cmd "unset_clock_groups" $args
+}
+
+proc unset_clk_groups_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args \
+    keys {-name} \
+    flags {-logically_exclusive -physically_exclusive -asynchronous -all}
+
+  set all [info exists flags(-all)]
+  set names {}
+  if {[info exists keys(-name)]} {
+    set names $keys(-name)
+  }
+
+  if { $all && $names != {} } {
+    sta_error 454 "the -all and -name options are mutually exclusive."
+  }
+  if { !$all && $names == {} } {
+    sta_error 455 "either -all or -name options must be specified."
+  }
+
+  set logically_exclusive [info exists flags(-logically_exclusive)]
+  set physically_exclusive [info exists flags(-physically_exclusive)]
+  set asynchronous [info exists flags(-asynchronous)]
+
+  if { ($logically_exclusive+$physically_exclusive+$asynchronous) == 0 } {
+    sta_error 456 "one of -logically_exclusive, -physically_exclusive or -asynchronous is required."
+  }
+  if { ($logically_exclusive+$physically_exclusive+$asynchronous) > 1 } {
+    sta_error 457 "the keywords -logically_exclusive, -physically_exclusive and -asynchronous are mutually exclusive."
+  }
+
+  if { $all } {
+    if { $logically_exclusive } {
+      unset_clock_groups_logically_exclusive "NULL"
+    } elseif { $physically_exclusive } {
+      unset_clock_groups_physically_exclusive "NULL"
+    } elseif { $asynchronous } {
+      unset_clock_groups_asynchronous "NULL"
+    }
+  } else {
+    foreach name $names {
+      if { $logically_exclusive } {
+	unset_clock_groups_logically_exclusive $name
+      } elseif { $physically_exclusive } {
+	unset_clock_groups_physically_exclusive $name
+      } elseif { $asynchronous } {
+	unset_clock_groups_asynchronous $name
+      }
+    }
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_clock_latency" {[-source] [-clock clock] objects}
+
+proc unset_clock_latency { args } {
+  unset_clk_latency_cmd "unset_clock_latency" $args
+}
+
+proc unset_clk_latency_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args keys {-clock} flags {-source}
+  check_argc_eq1 $cmd $cmd_args
+  set objects [lindex $cmd_args 0]
+  parse_clk_port_pin_arg $objects clks pins
+  set pin_clk "NULL"
+  if { [info exists keys(-clock)] } {
+    set pin_clk [get_clock_warn "clock" $keys(-clock)]
+    if { $clks != {} } {
+      sta_warn 303 "-clock ignored for clock objects."
+    }
+  }
+
+  if {[info exists flags(-source)]} {
+    # Source latency.
+    foreach clk $clks {
+      unset_clock_insertion_cmd $clk "NULL"
+    }
+    foreach pin $pins {
+      # Source only allowed on clocks and clock pins.
+      if { ![is_clock_pin $pin] } {
+	sta_error 458 "-source '[$pin path_name]' is not a clock pin."
+      }
+      unset_clock_insertion_cmd $pin_clk $pin
+    }
+  } else {
+    # Latency.
+    foreach clk $clks {
+      unset_clock_latency_cmd $clk "NULL"
+    }
+    foreach pin $pins {
+      unset_clock_latency_cmd $pin_clk $pin
+    }
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_clock_transition" {clocks}
+
+proc unset_clock_transition { args } {
+  check_argc_eq1 "unset_clock_transition" $args
+  set clks [get_clocks_warn "clocks" [lindex $args 0]]
+  foreach clk $clks {
+    unset_clock_slew_cmd $clk
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_clock_uncertainty" \
+  {[-from|-rise_from|-fall_from from_clock]\
+     [-to|-rise_to|-fall_to to_clock] [-rise] [-fall]\
+     [-setup] [-hold] [objects]}
+
+proc unset_clock_uncertainty { args } {
+  unset_clk_uncertainty_cmd "unset_clock_uncertainty" $args
+}
+
+proc unset_clk_uncertainty_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args \
+    keys {-from -rise_from -fall_from -to -rise_to -fall_to} \
+    flags {-rise -fall -setup -hold}
+
+  set min_max "min_max"
+  if { [info exists flags(-setup)] && ![info exists flags(-hold)] } {
+    set min_max "max"
+  }
+  if { [info exists flags(-hold)] && ![info exists flags(-setup)] } {
+    set min_max "min"
+  }
+
+  if { [info exists keys(-from)] } {
+    set from_key "-from"
+    set from_rf "rise_fall"
+  } elseif { [info exists keys(-rise_from)] } {
+    set from_key "-rise_from"
+    set from_rf "rise"
+  } elseif { [info exists keys(-fall_from)] } {
+    set from_key "-fall_from"
+    set from_rf "fall"
+  } else {
+    set from_key "none"
+  }
+
+  if { [info exists keys(-to)] } {
+    set to_key "-to"
+    set to_rf "rise_fall"
+  } elseif { [info exists keys(-rise_to)] } {
+    set to_key "-rise_to"
+    set to_rf "rise"
+  } elseif { [info exists keys(-fall_to)] } {
+    set to_key "-fall_to"
+    set to_rf "fall"
+  } else {
+    set to_key "none"
+  }
+
+  if { $from_key != "none" && $to_key == "none" \
+	 || $from_key == "none" && $to_key != "none" } {
+    sta_error 459 "-from/-to must be used together."
+  } elseif { $from_key != "none" && $to_key != "none" } {
+    # Inter-clock uncertainty.
+    check_argc_eq0 "unset_clock_uncertainty" $cmd_args
+
+    # -from/-to can be lists.
+    set from_clks [get_clocks_warn "from_clocks" $keys($from_key)]
+    set to_clks [get_clocks_warn "to_clocks" $keys($to_key)]
+
+    foreach from_clk $from_clks {
+      foreach to_clk $to_clks {
+	unset_inter_clock_uncertainty $from_clk $from_rf \
+	  $to_clk $to_rf $min_max
+      }
+    }
+  } else {
+    # Single clock uncertainty.
+    check_argc_eq1 $cmd $cmd_args
+    if { [info exists keys(-rise)] \
+	   || [info exists keys(-fall)] } {
+      sta_error 460 "-rise, -fall options not allowed for single clock uncertainty."
+    }
+    set objects [lindex $cmd_args 0]
+    parse_clk_port_pin_arg $objects clks pins
+
+    foreach clk $clks {
+      unset_clock_uncertainty_clk $clk $min_max
+    }
+    foreach pin $pins {
+      unset_clock_uncertainty_pin $pin $min_max
+    }
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_data_check" \
+  {[-from from_pin] [-rise_from from_pin] [-fall_from from_pin]\
+     [-to to_pin] [-rise_to to_pin] [-fall_to to_pin]\
+     [-setup | -hold] [-clock clock]}
+
+proc unset_data_check { args } {
+  unset_data_checks_cmd "unset_data_check" $args
+}
+
+proc unset_data_checks_cmd { cmd cmd_args } {
+  parse_key_args cmd cmd_args \
+    keys {-from -rise_from -fall_from -to -rise_to -fall_to -clock} \
+    flags {-setup -hold}
+  check_argc_eq0 $cmd $cmd_args
+
+  set from_rf "rise_fall"
+  set to_rf "rise_fall"
+  set clk "NULL"
+  set setup_hold "max"
+  if [info exists keys(-from)] {
+    set from [get_port_pin_error "from_pin" $keys(-from)]
+  } elseif [info exists keys(-rise_from)] {
+    set from [get_port_pin_error "from_pin" $keys(-rise_from)]
+    set from_rf "rise"
+  } elseif [info exists keys(-fall_from)] {
+    set from [get_port_pin_error "from_pin" $keys(-fall_from)]
+    set from_rf "fall"
+  } else {
+    sta_error 461 "missing -from, -rise_from or -fall_from argument."
+  }
+
+  if [info exists keys(-to)] {
+    set to [get_port_pin_error "to_pin" $keys(-to)]
+  } elseif [info exists keys(-rise_to)] {
+    set to [get_port_pin_error "to_pin" $keys(-rise_to)]
+    set to_rf "rise"
+  } elseif [info exists keys(-fall_to)] {
+    set to [get_port_pin_error "to_pin" $keys(-fall_to)]
+    set to_rf "fall"
+  } else {
+    sta_error 462 "missing -to, -rise_to or -fall_to argument."
+  }
+
+  if [info exists keys(-clock)] {
+    set clk [get_clock_warn "clock" $keys(-clock)]
+  }
+
+  if { [info exists flags(-setup)] && ![info exists flags(-hold)] } {
+    set setup_hold "setup"
+  } elseif { [info exists flags(-hold)] && ![info exists flags(-setup)] } {
+    set setup_hold "hold"
+  } else {
+    set setup_hold "setup_hold"
+  }
+
+  unset_data_check_cmd $from $from_rf $to $to_rf $clk $setup_hold
+}
+
+################################################################
+
+define_cmd_args "unset_disable_inferred_clock_gating" { objects }
+
+proc unset_disable_inferred_clock_gating { objects } {
+  unset_disable_inferred_clock_gating_cmd $objects
+}
+
+proc unset_disable_inferred_clock_gating_cmd { objects } {
+  parse_inst_port_pin_arg $objects insts pins
+  foreach inst $insts {
+    unset_disable_clock_gating_check_inst $inst
+  }
+  foreach pin $pins {
+    unset_disable_clock_gating_check_pin $pin
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_disable_timing" \
+  {[-from from_port] [-to to_port] objects}
+
+proc unset_disable_timing { args } {
+  unset_disable_cmd "unset_disable_timing" $args
+}
+
+proc unset_disable_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args keys {-from -to} flags {}
+  check_argc_eq1 $cmd $cmd_args
+
+  set from ""
+  if { [info exists keys(-from)] } {
+    set from $keys(-from)
+  }
+  set to ""
+  if { [info exists keys(-to)] } {
+    set to $keys(-to)
+  }
+  parse_libcell_libport_inst_port_pin_edge_timing_arc_set_arg $cmd_args \
+    libcells libports insts ports pins edges timing_arc_sets
+
+  if { ([info exists keys(-from)] || [info exists keys(-to)]) \
+	 && ($libports != {} || $pins != {} || $ports != {}) } {
+    sta_warn 304 "-from/-to keywords ignored for lib_pin, port and pin arguments."
+  }
+
+  foreach libcell $libcells {
+    unset_disable_timing_cell $libcell $from $to
+  }
+  foreach libport $libports {
+    unset_disable_lib_port $libport
+  }
+  foreach inst $insts {
+    unset_disable_timing_instance $inst $from $to
+  }
+  foreach pin $pins {
+    unset_disable_pin $pin
+  }
+  foreach port $ports {
+    unset_disable_port $port
+  }
+  foreach edge $edges {
+    unset_disable_edge $edge
+  }
+  foreach timing_arc_set $timing_arc_sets {
+    unset_disable_timing_arc_set $timing_arc_set
+  }
+}
+
+proc unset_disable_timing_cell { cell from to } {
+  set from_ports [parse_disable_cell_ports $cell $from]
+  set to_ports [parse_disable_cell_ports $cell $to]
+  if { $from_ports == "NULL" && $to_ports == "NULL" } {
+    unset_disable_cell $cell "NULL" "NULL"
+  } elseif { $from_ports == "NULL" } {
+    foreach to_port $to_ports {
+      unset_disable_cell $cell "NULL" $to_port
+    }
+  } elseif { $to_ports == "NULL" } {
+    foreach from_port $from_ports {
+      unset_disable_cell $cell $from_port "NULL"
+    }
+  } else {
+    foreach from_port $from_ports {
+      foreach to_port $to_ports {
+	unset_disable_cell $cell $from_port $to_port
+      }
+    }
+  }
+}
+
+proc unset_disable_timing_instance { inst from to } {
+  set from_ports [parse_disable_inst_ports $inst $from]
+  set to_ports [parse_disable_inst_ports $inst $to]
+  if { ![$inst is_leaf] } {
+    sta_error 463 "-from/-to hierarchical instance not supported."
+  }
+  if { $from_ports == "NULL" && $to_ports == "NULL" } {
+    unset_disable_instance $inst "NULL" "NULL"
+  } elseif { $from_ports == "NULL" } {
+    foreach to_port $to_ports {
+      unset_disable_instance $inst "NULL" $to_port
+    }
+  } elseif { $to_ports == "NULL" } {
+    foreach from_port $from_ports {
+      unset_disable_instance $inst $from_port "NULL"
+    }
+  } else {
+    foreach from_port $from_ports {
+      foreach to_port $to_ports {
+	unset_disable_instance $inst $from_port $to_port
+      }
+    }
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_generated_clock" {[-all] clocks}
+
+proc unset_generated_clock { args } {
+  unset_gclk_cmd "unset_generated_clock" $args
+}
+
+proc remove_gclk_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args keys {} flags {-all}
+  if { [info exists flags(-all)] } {
+    check_argc_eq0 $cmd $cmd_args
+    set clks [all_clocks]
+  } else {
+    check_argc_eq1 $cmd $cmd_args
+    set clks [get_clocks_warn "clocks" [lindex $cmd_args 0]]
+  }
+  foreach clk $clks {
+    if { [$clk is_generated] } {
+      remove_clock_cmd $clk
+    }
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_input_delay" \
+  {[-rise] [-fall] [-max] [-min]\
+     [-clock clock] [-clock_fall]\
+     port_pin_list}
+
+proc unset_input_delay { args } {
+  unset_port_delay "unset_input_delay" "unset_input_delay_cmd" $args
+}
+
+################################################################
+
+define_cmd_args "unset_output_delay" \
+  {[-rise] [-fall] [-max] [-min]\
+     [-clock clock] [-clock_fall]\
+     port_pin_list}
+
+proc unset_output_delay { args } {
+  unset_port_delay "unset_output_delay" "unset_output_delay_cmd" $args
+}
+
+proc unset_port_delay { cmd swig_cmd cmd_args } {
+  parse_key_args $cmd cmd_args \
+    keys {-clock -reference_pin} \
+    flags {-rise -fall -max -min -clock_fall }
+  check_argc_eq1 $cmd $cmd_args
+  
+  set pins [get_port_pins_error "pins" [lindex $cmd_args 0]]
+  
+  set clk "NULL"
+  if [info exists keys(-clock)] {
+    set clk [get_clock_warn "clock" $keys(-clock)]
+  }
+  
+  if [info exists flags(-clock_fall)] {
+    set clk_rf "fall"
+  } else {
+    set clk_rf "rise"
+  }
+  
+  set tr [parse_rise_fall_flags flags]
+  set min_max [parse_min_max_all_flags flags]
+
+  foreach pin $pins {
+    $swig_cmd $pin $tr $clk $clk_rf $min_max
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_path_exceptions" \
+  {[-setup] [-hold] [-rise] [-fall] [-from from_list]\
+     [-rise_from from_list] [-fall_from from_list]\
+     [-through through_list] [-rise_through through_list]\
+     [-fall_through through_list] [-to to_list] [-rise_to to_list]\
+     [-fall_to to_list]}
+
+proc unset_path_exceptions { args } {
+  unset_path_exceptions_cmd "unset_path_exceptions" $args
+}
+
+proc unset_path_exceptions_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args \
+    keys {-from -rise_from -fall_from -to -rise_to -fall_to} \
+    flags {-setup -hold -rise -fall} 0
+
+  set min_max "min_max"
+  if { [info exists flags(-setup)] && ![info exists flags(-hold)] } {
+    set min_max "max"
+  }
+  if { [info exists flags(-hold)] && ![info exists flags(-setup)] } {
+    set min_max "min"
+  }
+
+  set arg_error 0
+  set from [parse_from_arg keys arg_error]
+  set thrus [parse_thrus_arg cmd_args arg_error]
+  set to [parse_to_arg keys flags arg_error]
+  if { $arg_error } {
+    delete_from_thrus_to $from $thrus $to
+    sta_error 464 "$cmd command failed."
+    return 0
+  }
+
+  check_for_key_args $cmd cmd_args
+  if { $cmd_args != {} } {
+    delete_from_thrus_to $from $thrus $to
+    sta_error 465 "positional arguments not supported."
+  }
+  if { ($from == "NULL" && $thrus == "" && $to == "NULL") } {
+    delete_from_thrus_to $from $thrus $to
+    sta_error 466 "-from, -through or -to required."
+  }
+
+  reset_path_cmd $from $thrus $to $min_max
+  delete_from_thrus_to $from $thrus $to
+}
+
+################################################################
+
+define_cmd_args "unset_propagated_clock" {objects}
+
+proc unset_propagated_clock { objects } {
+  parse_clk_port_pin_arg $objects clks pins
+  foreach clk $clks {
+    unset_propagated_clock_cmd $clk
+  }
+  foreach pin $pins {
+    unset_propagated_clock_pin_cmd $pin
+  }
+}
+
+################################################################
+
+define_cmd_args "unset_timing_derate" {}
+
+proc unset_timing_derate { args } {
+  check_argc_eq0 "unset_timing_derate" $args
+  reset_timing_derate_cmd
+}
+
+################################################################
+#
+# Network editing commands
+#  
+################################################################
+
+define_cmd_args "connect_pin" {net pin}
+# deprecated 2.0.16 05/02/2019
+define_cmd_args "connect_pins" {net pins}
+
+define_cmd_args "delete_instance" {inst}
+
+define_cmd_args "delete_net" {net}
+
+define_cmd_args "disconnect_pin" {net -all|pin}
+# deprecated 2.0.16 05/02/2019
+define_cmd_args "disconnect_pins" {net -all|pins}
+
+define_cmd_args "make_instance" {inst_path lib_cell}
+
+define_cmd_args "make_net" {}
+
+define_cmd_args "replace_cell" {instance lib_cell}
+define_cmd_args "replace_to_scan_cell" {instance}
+
+define_cmd_args "insert_buffer" {buffer_name buffer_cell net load_pins\
+				       buffer_out_net_name}
+
+################################################################
+#
+# Delay calculation commands
+#  
+################################################################
+
+define_cmd_args "set_assigned_delay" \
+  {-cell|-net [-rise] [-fall] [-corner corner_name] [-min] [-max]\
+     [-from from_pins] [-to to_pins] delay}
+
+# Change the delay for timing arcs between from_pins and to_pins matching
+# on cell (instance) or net.
+proc set_assigned_delay { args } {
+  set_assigned_delay_cmd "set_assigned_delay" $args
+}
+
+proc set_assigned_delay_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args keys {-corner -from -to} \
+    flags {-cell -net -rise -fall -max -min}
+  check_argc_eq1 $cmd $cmd_args
+  set corner [parse_corner keys]
+  set min_max [parse_min_max_all_check_flags flags]
+  set to_rf [parse_rise_fall_flags flags]
+
+  if [info exists keys(-from)] {
+    set from_pins [get_port_pins_error "from_pins" $keys(-from)]
+  } else {
+    sta_error 442 "$cmd missing -from argument."
+  }
+  if [info exists keys(-to)] {
+    set to_pins [get_port_pins_error "to_pins" $keys(-to)]
+  } else {
+    sta_error 443 "$cmd missing -to argument."
+  }
+
+  set delay [lindex $cmd_args 0]
+  if {![string is double $delay]} {
+    sta_error 444 "$cmd delay is not a float."
+  }
+  set delay [time_ui_sta $delay]
+
+  if {[info exists flags(-cell)] && [info exists flags(-net)]} {
+    sta_error 445 "set_annotated_delay -cell and -net options are mutually excluive."
+  } elseif {[info exists flags(-cell)]} {
+    if { $from_pins != {} } {
+      set inst [[lindex $from_pins 0] instance]
+      foreach pin $from_pins {
+	if {[$pin instance] != $inst} {
+	  sta_error 446 "$cmd pin [get_full_name $pin] is not attached to instance [get_full_name $inst]."
+	}
+      }
+      foreach pin $to_pins {
+	if {[$pin instance] != $inst} {
+	  sta_error 447 "$cmd pin [get_full_name $pin] is not attached to instance [get_full_name $inst]"
+	}
+      }
+    }
+  } elseif {![info exists flags(-net)]} {
+    sta_error 448 "$cmd -cell or -net required."
+  }
+  foreach from_pin $from_pins {
+    set from_vertices [$from_pin vertices]
+    set_assigned_delay1 [lindex $from_vertices 0] \
+      $to_pins $to_rf $corner $min_max $delay
+    if { [llength $from_vertices] == 2 } {
+      set_assigned_delay1 [lindex $from_vertices 1] \
+	$to_pins $to_rf $corner $min_max $delay
+    }
+  }
+}
+
+proc set_assigned_delay1 { from_vertex to_pins to_rf corner min_max delay } {
+  foreach to_pin $to_pins {
+    set to_vertices [$to_pin vertices]
+    set_assigned_delay2 $from_vertex [lindex $to_vertices 0] \
+      $to_rf $corner $min_max $delay
+    if { [llength $to_vertices] == 2 } {
+      # Bidirect driver.
+      set_assigned_delay2 $from_vertex [lindex $to_vertices 1] \
+	$to_rf $corner $min_max $delay
+    }
+  }
+}
+
+proc set_assigned_delay2 {from_vertex to_vertex to_rf corner min_max delay} {
+  set edge_iter [$from_vertex out_edge_iterator]
+  while {[$edge_iter has_next]} {
+    set edge [$edge_iter next]
+    if { [$edge to] == $to_vertex \
+	   && ![timing_role_is_check [$edge role]] } {
+      set arc_iter [$edge timing_arc_iterator]
+      while {[$arc_iter has_next]} {
+	set arc [$arc_iter next]
+	if { $to_rf == "rise_fall" \
+	       || $to_rf eq [$arc to_trans_name] } {
+	  set_arc_delay $edge $arc $corner $min_max $delay
+	}
+      }
+      $arc_iter finish
+    }
+  }
+  $edge_iter finish
+}
+
+################################################################
+
+define_cmd_args "set_assigned_check" \
+  {-setup|-hold|-recovery|-removal [-rise] [-fall]\
+     [-corner corner_name] [-min] [-max]\
+     [-from from_pins] [-to to_pins] [-clock rise|fall]\
+     [-cond sdf_cond] [-worst] check_value}
+
+# -worst is ignored.
+proc set_assigned_check { args } {
+  set_assigned_check_cmd "set_assigned_check" $args
+}
+
+# -worst is ignored.
+proc set_assigned_check_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args \
+    keys {-from -to -corner -clock -cond} \
+    flags {-setup -hold -recovery -removal -rise -fall -max -min -worst}
+  check_argc_eq1 $cmd $cmd_args
+
+  if { [info exists keys(-from)] } {
+    set from_pins [get_port_pins_error "from_pins" $keys(-from)]
+  } else {
+    sta_error 449 "$cmd missing -from argument."
+  }
+  set from_rf "rise_fall"
+  if { [info exists keys(-clock)] } {
+    set clk_arg $keys(-clock)
+    if { $clk_arg eq "rise" \
+	   || $clk_arg eq "fall" } {
+      set from_rf $clk_arg
+    } else {
+      sta_error 450 "$cmd -clock must be rise or fall."
+    }
+  }
+
+  if { [info exists keys(-to)] } {
+    set to_pins [get_port_pins_error "to_pins" $keys(-to)]
+  } else {
+    sta_error 451 "$cmd missing -to argument."
+  }
+  set to_rf [parse_rise_fall_flags flags]
+  set corner [parse_corner keys]
+  set min_max [parse_min_max_all_check_flags flags]
+
+  if { [info exists flags(-setup)] } {
+    set role "setup"
+  } elseif { [info exists flags(-hold)] } {
+    set role "hold"
+  } elseif { [info exists flags(-recovery)] } {
+    set role "recovery"
+  } elseif { [info exists flags(-removal)] } {
+    set role "removal"
+  } else {
+    sta_error 452 "$cmd missing -setup|-hold|-recovery|-removal check type.."
+  }
+  set cond ""
+  if { [info exists key(-cond)] } {
+    set cond $key(-cond)
+  }
+  set check_value [lindex $cmd_args 0]
+  if { ![string is double $check_value] } {
+    sta_error 453 "$cmd check_value is not a float."
+  }
+  set check_value [time_ui_sta $check_value]
+
+  foreach from_pin $from_pins {
+    set from_vertices [$from_pin vertices]
+    set_assigned_check1 [lindex $from_vertices 0] $from_rf \
+      $to_pins $to_rf $role $corner $min_max $cond $check_value
+    if { [llength $from_vertices] == 2 } {
+      set_assigned_check1 [lindex $from_vertices 1] $from_rf \
+	$to_pins $to_rf $role $corner $min_max $cond $check_value
+    }
+  }
+}
+
+proc set_assigned_check1 { from_vertex from_rf to_pins to_rf \
+			     role corner min_max cond check_value } {
+  foreach to_pin $to_pins {
+    set to_vertices [$to_pin vertices]
+    set_assigned_check2 $from_vertex $from_rf [lindex $to_vertices 0] \
+      $to_rf $role $corner $min_max $cond $check_value
+    if { [llength $to_vertices] == 2 } {
+      # Bidirect driver.
+      set_assigned_check2 $from_vertex $from_rf \
+	[lindex $to_vertices 1] $to_rf $role $corner $min_max \
+	$cond $check_value
+    }
+  }
+}
+
+proc set_assigned_check2 { from_vertex from_rf to_vertex to_rf \
+			     role corner min_max cond check_value } {
+  set edge_iter [$from_vertex out_edge_iterator]
+  while {[$edge_iter has_next]} {
+    set edge [$edge_iter next]
+    if { [$edge to] == $to_vertex } {
+      set arc_iter [$edge timing_arc_iterator]
+      while {[$arc_iter has_next]} {
+	set arc [$arc_iter next]
+	if { ($from_rf eq "rise_fall" \
+		|| $from_rf eq [$arc from_trans_name]) \
+	       && ($to_rf eq "rise_fall" \
+		     || $to_rf eq [$arc to_trans_name]) \
+	       && [$arc role] eq $role \
+	       && ($cond eq "" || [$arc sdf_cond] eq $cond) } {
+	  set_arc_delay $edge $arc $corner $min_max $check_value
+	}
+      }
+      $arc_iter finish
+    }
+  }
+  $edge_iter finish
+}
+
+################################################################a
+
+define_cmd_args "set_assigned_transition" \
+  {[-rise] [-fall] [-corner corner_name] [-min] [-max] slew pins}
+
+# Change the slew on a list of ports.
+proc set_assigned_transition { args } {
+  parse_key_args "set_assigned_transition" args keys {-corner} \
+    flags {-rise -fall -max -min}
+
+  set corner [parse_corner keys]
+  set min_max [parse_min_max_all_check_flags flags]
+  set tr [parse_rise_fall_flags flags]
+  check_argc_eq2 "set_assigned_transition" $args
+
+  set slew [lindex $args 0]
+  if {![string is double $slew]} {
+    sta_error 428 "set_assigned_transition transition is not a float."
+  }
+  set slew [time_ui_sta $slew]
+  set pins [get_port_pins_error "pins" [lindex $args 1]]
+  foreach pin $pins {
+    set vertices [$pin vertices]
+    set vertex [lindex $vertices 0]
+    set_annotated_slew $vertex $corner $min_max $tr $slew
+    if { [llength $vertices] == 2 } {
+      # Bidirect driver.
+      set vertex [lindex $vertices 1]
+      set_annotated_slew $vertex $min_max $tr $slew
+    }
+  }
+}
+
+################################################################a
+
+# compatibility
+define_cmd_args "read_parasitics" \
+  {[-min]\
+     [-max]\
+     [-elmore]\
+     [-path path]\
+     [-increment]\
+     [-pin_cap_included]\
+     [-keep_capacitive_coupling]\
+     [-coupling_reduction_factor factor]\
+     [-reduce_to pi_elmore|pi_pole_residue2]\
+     [-delete_after_reduce]\
+     [-quiet]\
+     [-save]\
+     filename}
+
+################################################################
+#  
+# Utility commands
+#
+################################################################
+
+define_cmd_args "delete_from_list" {list objs}
+
+proc delete_from_list { list objects } {
+  delete_objects_from_list_cmd $list $objects
+}
+
+proc delete_objects_from_list_cmd { list objects } {
+  set list0 [lindex $list 0]
+  set list_is_object [is_object $list0]
+  set list_type [object_type $list0]
+  foreach obj $objects {
+    # If the list is a collection of tcl objects (returned by get_*),
+    # convert the obj to be removed from a name to an object of the same
+    # type.
+    if {$list_is_object && ![is_object $obj]} {
+      if {$list_type == "Clock"} {
+	set obj [find_clock $obj]
+      } elseif {$list_type == "Port"} {
+	set top_instance [top_instance]
+	set top_cell [$top_instance cell]
+	set obj [$top_cell find_port $obj]
+      } elseif {$list_type == "Pin"} {
+	set obj [find_pin $obj]
+      } elseif {$list_type == "Instance"} {
+	set obj [find_instance $obj]
+      } elseif {$list_type == "Net"} {
+	set obj [find_net $obj]
+      } elseif {$list_type == "LibertyLibrary"} {
+	set obj [find_liberty $obj]
+      } elseif {$list_type == "LibertyCell"} {
+	set obj [find_liberty_cell $obj]
+      } elseif {$list_type == "LibertyPort"} {
+	set obj [get_lib_pins $obj]
+      } else {
+	sta_error 439 "unsupported object type $list_type."
+      }
+    }
+    set index [lsearch $list $obj]
+    if { $index != -1 } {
+      set list [lreplace $list $index $index]
+    }
+  }
+  return $list
+}
+
+################################################################
+
+define_cmd_args "get_fanin" \
+  {-to sink_list [-flat] [-only_cells] [-startpoints_only]\
+     [-levels level_count] [-pin_levels pin_count]\
+     [-trace_arcs timing|enabled|all]}
+
+proc get_fanin { args } {
+  parse_key_args "get_fanin" args \
+    keys {-to -levels -pin_levels -trace_arcs} \
+    flags {-flat -only_cells -startpoints_only}
+  if { [llength $args] != 0 } {
+    cmd_usage_error "get_fanin"
+  }
+  if { ![info exists keys(-to)] } {
+    cmd_usage_error "get_fanin"
+  }
+  parse_port_pin_net_arg $keys(-to) pins nets
+  foreach net $nets {
+    lappend pins [net_driver_pins $net]
+  }
+  set flat [info exists flags(-flat)]
+  set only_insts [info exists flags(-only_cells)]
+  set startpoints_only [info exists flags(-startpoints_only)]
+  set inst_levels 0
+  if { [info exists keys(-levels)] } {
+    set inst_levels $keys(-levels)
+  }
+  set pin_levels 0
+  if { [info exists keys(-pin_levels)] } {
+    set pin_levels $keys(-pin_levels)
+  }
+
+  set thru_disabled 0
+  set thru_constants 0
+  if { [info exists keys(-trace_arcs)] } {
+    set trace_arcs $keys(-trace_arcs)
+    if { $trace_arcs == "timing" } {
+      set thru_disabled 0
+      set thru_constants 0
+    } elseif { $trace_arcs == "enabled" } {
+      set thru_disabled 0
+      set thru_constants 0
+    } elseif { $trace_arcs == "all" } {
+      set thru_disabled 1
+      set thru_constants 1
+    } else {
+      cmd_usage_error "get_fanin"
+    }
+  }
+  if { $only_insts } {
+    return [find_fanin_insts $pins $flat $startpoints_only \
+	      $inst_levels $pin_levels $thru_disabled $thru_constants]
+ } else {
+    return [find_fanin_pins $pins $flat $startpoints_only \
+	      $inst_levels $pin_levels $thru_disabled $thru_constants]
+  }
+}
+
+################################################################
+
+define_cmd_args "get_fanout" \
+  {-from source_list [-flat] [-only_cells] [-endpoints_only]\
+     [-levels level_count] [-pin_levels pin_count]\
+     [-trace_arcs timing|enabled|all]}
+
+proc get_fanout { args } {
+  parse_key_args "get_fanout" args \
+    keys {-from -levels -pin_levels -trace_arcs} \
+    flags {-flat -only_cells -endpoints_only}
+  if { [llength $args] != 0 } {
+    cmd_usage_error "get_fanout"
+  }
+  parse_port_pin_net_arg $keys(-from) pins nets
+  foreach net $nets {
+    lappend pins [net_load_pins $net]
+  }
+  set flat [info exists flags(-flat)]
+  set only_insts [info exists flags(-only_cells)]
+  set endpoints_only [info exists flags(-endpoints_only)]
+
+  set inst_levels 0
+  if { [info exists keys(-levels)] } {
+    set inst_levels $keys(-levels)
+  }
+
+  set pin_levels 0
+  if { [info exists keys(-pin_levels)] } {
+    set pin_levels $keys(-pin_levels)
+  }
+
+  set thru_disabled 0
+  set thru_constants 0
+  if { [info exists keys(-trace_arcs)] } {
+    set trace_arcs $keys(-trace_arcs)
+    if { $trace_arcs == "timing" } {
+      set thru_disabled 0
+      set thru_constants 0
+    } elseif { $trace_arcs == "enabled" } {
+      set thru_disabled 0
+      set thru_constants 0
+    } elseif { $trace_arcs == "all" } {
+      set thru_disabled 1
+      set thru_constants 1
+    } else {
+      cmd_usage_error "get_fanout"
+    }
+  }
+  if { $only_insts } {
+    return [find_fanout_insts $pins $flat $endpoints_only \
+	      $inst_levels $pin_levels $thru_disabled $thru_constants]
+  } else {
+    return [find_fanout_pins $pins $flat $endpoints_only \
+	      $inst_levels $pin_levels $thru_disabled $thru_constants]
+  }
+}
+
+################################################################
+
+define_cmd_args "get_name" {objects}
+define_cmd_args "get_full_name" {objects}
+
+################################################################
+
+define_cmd_args "get_property" \
+  {[-object_type cell|pin|net|port|clock|timing_arc] object property}
+
+proc get_property { args } {
+  return [get_property_cmd "get_property" "-object_type" $args]
+}
+
+################################################################
+
+proc get_property_cmd { cmd type_key cmd_args } {
+  parse_key_args $cmd cmd_args keys $type_key flags {-quiet}
+  set quiet [info exists flags(-quiet)]
+  check_argc_eq2 $cmd $cmd_args
+  set object [lindex $cmd_args 0]
+  if { $object == "" } {
+    sta_error 491 "$cmd object is null."
+  } elseif { ![is_object $object] } {
+    if [info exists keys($type_key)] {
+      set object_type $keys($type_key)
+    } else {
+      sta_error 492 "$cmd $type_key must be specified with object name argument."
+    }
+    set object [get_property_object_type $object_type $object $quiet]
+  }
+  set prop [lindex $cmd_args 1]
+  return [get_object_property $object $prop]
+}
+
+proc get_object_property { object prop } {
+  if { [is_object $object] } {
+    set object_type [object_type $object]
+    if { $object_type == "Instance" } {
+      return [instance_property $object $prop]
+    } elseif { $object_type == "Pin" } {
+      return [pin_property $object $prop]
+    } elseif { $object_type == "Net" } {
+      return [net_property $object $prop]
+    } elseif { $object_type == "Clock" } {
+      return [clock_property $object $prop]
+    } elseif { $object_type == "Port" } {
+      return [port_property $object $prop]
+    } elseif { $object_type == "LibertyPort" } {
+      return [liberty_port_property $object $prop]
+    } elseif { $object_type == "LibertyCell" } {
+      return [liberty_cell_property $object $prop]
+    } elseif { $object_type == "Cell" } {
+      return [cell_property $object $prop]
+    } elseif { $object_type == "Library" } {
+      return [library_property $object $prop]
+    } elseif { $object_type == "LibertyLibrary" } {
+      return [liberty_library_property $object $prop]
+    } elseif { $object_type == "Edge" } {
+      return [edge_property $object $prop]
+    } elseif { $object_type == "PathEnd" } {
+      return [path_end_property $object $prop]
+    } elseif { $object_type == "PathRef" } {
+      return [path_ref_property $object $prop]
+    } elseif { $object_type == "TimingArcSet" } {
+      return [timing_arc_set_property $object $prop]
+    } else {
+      sta_error 606 "get_property unsupported object type $object_type."
+    }
+  } else {
+    sta_error 493 "get_property $object is not an object."
+  }
+}
+
+proc get_property_object_type { object_type object_name quiet } {
+  set object "NULL"
+  if { $object_type == "cell" } {
+    set object [get_cells -quiet $object_name]
+  } elseif { $object_type == "pin" } {
+    set object [get_pins -quiet $object_name]
+  } elseif { $object_type == "net" } {
+    set object [get_nets -quiet $object_name]
+  } elseif { $object_type == "port" } {
+    set object [get_ports -quiet $object_name]
+  } elseif { $object_type == "clock" } {
+    set object [get_clocks -quiet $object_name]
+  } elseif { $object_type == "lib_cell" } {
+    set object [get_lib_cells -quiet $object_name]
+  } elseif { $object_type == "lib_pin" } {
+    set object [get_lib_pins -quiet $object_name]
+  } elseif { $object_type == "lib" } {
+    set object [get_libs -quiet $object_name]
+  } else {
+    sta_error 494 "$object_type not supported."
+  }
+  if { $object == "NULL" && !$quiet } {
+    sta_error 495 "$object_type '$object_name' not found."
+  }
+  return [lindex $object 0]
+}
+
+proc get_object_type { obj } {
+  set object_type [object_type $obj]
+  if { $object_type == "Clock" } {
+    return "clock"
+  } elseif { $object_type == "LibertyCell" } {
+    return "libcell"
+  } elseif { $object_type == "LibertyPort" } {
+    return "libpin"
+  } elseif { $object_type == "Cell" } {
+    return "design"
+  } elseif { $object_type == "Instance" } {
+    return "cell"
+  } elseif { $object_type == "Port" } {
+    return "port"
+  } elseif { $object_type == "Pin" } {
+    return "pin"
+  } elseif { $object_type == "Net" } {
+    return "net"
+  } elseif { $object_type == "Edge" } {
+    return "timing_arc"
+  } elseif { $object_type == "TimingArcSet" } {
+    return "timing_arc"
+  } else {
+    return "?"
+  }
+}
+
+proc get_name { object } {
+  return [get_object_property $object "name"]
+}
+
+proc get_full_name { object } {
+  return [get_object_property $object "full_name"]
+}
+
+proc sort_by_name { objects } {
+  return [lsort -command name_cmp $objects]
+}
+
+proc name_cmp { obj1 obj2 } {
+  return [string compare [get_name $obj1] [get_name $obj2]]
+}
+
+proc sort_by_full_name { objects } {
+  return [lsort -command full_name_cmp $objects]
+}
+
+proc full_name_cmp { obj1 obj2 } {
+  return [string compare [get_full_name $obj1] [get_full_name $obj2]]
+}
+
+################################################################
+
+define_cmd_args "get_timing_edges" \
+  {[-from from_pin] [-to to_pin] [-of_objects objects] [-filter expr]}
+
+proc get_timing_edges { args } {
+  return [get_timing_edges_cmd "get_timing_edges" $args]
+}
+
+proc get_timing_edges_cmd { cmd cmd_args } {
+  parse_key_args $cmd cmd_args \
+    keys {-from -to -of_objects -filter} flags {}
+  check_argc_eq0 $cmd $cmd_args
+
+  set arcs {}
+  if { [info exists keys(-of_objects)] } {
+    if { [info exists keys(-from)] \
+	   || [info exists keys(-from)] } {
+      sta_error 440 "-from/-to arguments not supported with -of_objects."
+    }
+    set arcs [get_timing_arcs_objects $keys(-of_objects)]
+  } elseif { [info exists keys(-from)] \
+	   && [info exists keys(-to)] } {
+    set arcs [get_timing_arcs_from_to \
+	      [get_port_pin_error "from" $keys(-from)] \
+	      [get_port_pin_error "to" $keys(-to)]]
+  } elseif { [info exists keys(-from)] } {
+    set arcs [get_timing_arcs_from $keys(-from)]
+  } elseif { [info exists keys(-to)] } {
+    set arcs [get_timing_arcs_to $keys(-to)]
+  } else {
+    cmd_usage_error $cmd
+  }
+  if [info exists keys(-filter)] {
+    set arcs [filter_timing_arcs1 $keys(-filter) $arcs]
+  }
+  return $arcs
+}
+
+proc get_timing_arcs_objects { object_arg } {
+  parse_libcell_inst_arg $object_arg libcells insts
+  if { $insts != {} } {
+    set edges {}
+    foreach inst $insts {
+      lappend edges [instance_edges $inst]
+    }
+    return $edges
+  } elseif { $libcells != {} } {
+    set arc_sets {}
+    foreach libcell $libcells {
+      lappend arc_sets [libcell_timing_arc_sets $libcell]
+    }
+    return $arc_sets
+  }
+}
+
+proc instance_edges { inst } {
+  set edges {}
+  set pin_iter [$inst pin_iterator]
+  while {[$pin_iter has_next]} {
+    set pin [$pin_iter next]
+    foreach vertex [$pin vertices] {
+      set edge_iter [$vertex out_edge_iterator]
+      while {[$edge_iter has_next]} {
+	set edge [$edge_iter next]
+	if { [$edge role] != "wire" } {
+	  lappend edges $edge
+	}
+      }
+      $edge_iter finish
+    }
+  }
+  $pin_iter finish
+  return $edges
+}
+
+proc libcell_timing_arc_sets { libcell } {
+  set arc_sets {}
+  set arc_iter [$libcell timing_arc_set_iterator]
+  while { [$arc_iter has_next] } {
+    lappend arc_sets [$arc_iter next]
+  }
+  $arc_iter finish
+  return $arc_sets
+}
+
+proc get_timing_arcs_from_to { from_pin_arg to_pin_arg } {
+  set edges {}
+  set from_pin [get_port_pin_error "from" $from_pin_arg]
+  set to_pin [get_port_pin_error "to" $to_pin_arg]
+  foreach from_vertex [$from_pin vertices] {
+    foreach to_vertex [$to_pin vertices] {
+      set edge_iter [$from_vertex out_edge_iterator]
+      while {[$edge_iter has_next]} {
+	set edge [$edge_iter next]
+	if { [$edge to] == $to_vertex } {
+	  lappend edges $edge
+	}
+      }
+      $edge_iter finish
+    }
+  }
+  return $edges
+}
+
+proc get_timing_arcs_from { from_pin_arg } {
+  set from_pin [get_port_pin_error "from" $from_pin_arg]
+  set edges {}
+  foreach from_vertex [$from_pin vertices] {
+    set edge_iter [$from_vertex out_edge_iterator]
+    while {[$edge_iter has_next]} {
+      set edge [$edge_iter next]
+      lappend edges $edge
+    }
+    $edge_iter finish
+  }
+  return $edges
+}
+
+proc get_timing_arcs_to { to_pin_arg } {
+  set to_pin [get_port_pin_error "to" $to_pin_arg]
+  set edges {}
+  foreach to_vertex [$to_pin vertices] {
+    set edge_iter [$to_vertex in_edge_iterator]
+    while {[$edge_iter has_next]} {
+      set edge [$edge_iter next]
+      lappend edges $edge
+    }
+    $edge_iter finish
+  }
+  return $edges
+}
+
+proc filter_timing_arcs1 { filter objects } {
+  variable filter_regexp1
+  variable filter_or_regexp
+  variable filter_and_regexp
+  set filtered_objects {}
+  # Ignore sub-exprs in filter_regexp1 for expr2 match var.
+  if { [regexp $filter_or_regexp $filter ignore expr1 \
+	  ignore ignore ignore expr2] } {
+    regexp $filter_regexp1 $expr1 ignore attr_name op arg
+    set filtered_objects1 [filter_timing_arcs $attr_name $op $arg $objects]
+    regexp $filter_regexp1 $expr2 ignore attr_name op arg
+    set filtered_objects2 [filter_timing_arcs $attr_name $op $arg $objects]
+    set filtered_objects [concat $filtered_objects1 $filtered_objects2]
+  } elseif { [regexp $filter_and_regexp $filter ignore expr1 \
+		ignore ignore ignore expr2] } {
+    regexp $filter_regexp1 $expr1 ignore attr_name op arg
+    set filtered_objects [filter_timing_arcs $attr_name $op $arg $objects]
+    regexp $filter_regexp1 $expr2 ignore attr_name op arg
+    set filtered_objects [filter_timing_arcs $attr_name $op \
+			    $arg $filtered_objects]
+  } elseif { [regexp $filter_regexp1 $filter ignore attr_name op arg] } {
+    set filtered_objects [filter_timing_arcs $attr_name $op $arg $objects]
+  } else {
+    sta_error 441 "unsupported -filter expression."
+  }
+  return $filtered_objects
+}
+
+################################################################
+
+define_cmd_args "report_clock_properties" {[clocks]}
+
+proc_redirect report_clock_properties {
+  check_argc_eq0or1 "report_clock_properties" $args
+  update_generated_clks
+  report_line "Clock                   Period          Waveform"
+  report_line "----------------------------------------------------"
+  if { [llength $args] == 0 } {
+    set clk_iter [clock_iterator]
+    while {[$clk_iter has_next]} {
+      set clk [$clk_iter next]
+      report_clock1 $clk
+    }
+    $clk_iter finish
+  } else {
+    foreach clk [get_clocks_warn "clock_name" [lindex $args 0]] {
+      report_clock1 $clk
+    }
+  }
+}
+
+proc report_clock1 { clk } {
+  global sta_report_default_digits
+
+  if { [$clk waveform_valid] } {
+    set digits $sta_report_default_digits
+    set waveform [$clk waveform]
+    if { $waveform == {} } {
+      set wave "                    "
+    } else {
+      set wave ""
+      foreach edge $waveform {
+	set wave "$wave[format "%10s" [format_time $edge $digits]]"
+      }
+    }
+    if {[$clk is_generated]} {
+      set generated " (generated)"
+    } else {
+      set generated ""
+    }
+    report_line "[format %-20s [get_name $clk]][format %10s [format_time [$clk period] $digits]]  $wave$generated"
+  }
+}
+
+################################################################
+
+define_cmd_args "report_object_full_names" {objects}
+
+proc report_object_full_names { objects } {
+  foreach obj [sort_by_full_name $objects] {
+    report_line [get_full_name $obj]
+  }
+}
+
+define_cmd_args "report_object_names" {objects}
+
+proc report_object_names { objects } {
+  foreach obj [sort_by_name $objects] {
+    report_line [get_name $obj]
+  }
+}
+
+################################################################
+
+define_cmd_args "report_units" {}
+
+proc report_units { args } {
+  check_argc_eq0 "report_units" $args
+  foreach unit {"time" "capacitance" "resistance" "voltage" "current" "power" "distance"} {
+    report_line " $unit 1[unit_scale_abreviation $unit][unit_suffix $unit]"
+  }
+}
+
+################################################################
+
+define_cmd_args "with_output_to_variable" { var { cmds }}
+
+# with_output_to_variable variable { command args... }
+proc with_output_to_variable { var_name args } {
+  upvar 1 $var_name var
+
+  set body [lindex $args 0]
+  sta::redirect_string_begin;
+  catch $body ret
+  set var [sta::redirect_string_end]
+  return $ret
+}
+
+define_cmd_args "set_pocv_sigma_factor" { factor }
+
+################################################################
+
+define_cmd_args "write_path_spice" { -path_args path_args\
+				       -spice_directory spice_directory\
+				       -lib_subckt_file lib_subckts_file\
+				       -model_file model_file\
+				       -power power\
+				       -ground ground}
+
+proc write_path_spice { args } {
+  parse_key_args "write_path_spice" args \
+    keys {-spice_directory -lib_subckt_file -model_file \
+	    -power -ground -path_args} \
+    flags {}
+
+  if { [info exists keys(-spice_directory)] } {
+    set spice_dir [file nativename $keys(-spice_directory)]
+    if { ![file exists $spice_dir] } {
+      sta_error 496 "Directory $spice_dir not found."
+    }
+    if { ![file isdirectory $spice_dir] } {
+      sta_error 497 "$spice_dir is not a directory."
+    }
+    if { ![file writable $spice_dir] } {
+      sta_error 498 "Cannot write in $spice_dir."
+    }
+  } else {
+    sta_error 499 "No -spice_directory specified."
+  }
+
+  if { [info exists keys(-lib_subckt_file)] } {
+    set lib_subckt_file [file nativename $keys(-lib_subckt_file)]
+    if { ![file readable $lib_subckt_file] } {
+      sta_error 500 "-lib_subckt_file $lib_subckt_file is not readable."
+    }
+  } else {
+    sta_error 501 "No -lib_subckt_file specified."
+  }
+
+  if { [info exists keys(-model_file)] } {
+    set model_file [file nativename $keys(-model_file)]
+    if { ![file readable $model_file] } {
+      sta_error 502 "-model_file $model_file is not readable."
+    }
+  } else {
+    sta_error 503 "No -model_file specified."
+  }
+
+  if { [info exists keys(-power)] } {
+    set power $keys(-power)
+  } else {
+    sta_error 504 "No -power specified."
+  }
+
+  if { [info exists keys(-ground)] } {
+    set ground $keys(-ground)
+  } else {
+    sta_error 505 "No -ground specified."
+  }
+
+  if { ![info exists keys(-path_args)] } {
+    sta_error 506 "No -path_args specified."
+  }
+  set path_args $keys(-path_args)
+  set path_ends [eval [concat find_timing_paths $path_args]]
+  if { $path_ends == {} } {
+    sta_error 507 "No paths found for -path_args $path_args."
+  } else {
+    set path_index 1
+    foreach path_end $path_ends {
+      set path [$path_end path]
+      set path_name "path_$path_index"
+      set spice_file [file join $spice_dir "$path_name.sp"]
+      set subckt_file [file join $spice_dir "$path_name.subckt"]
+      write_path_spice_cmd $path $spice_file $subckt_file \
+	$lib_subckt_file $model_file $power $ground
+      incr path_index
+    }
+  }
+}
+
+# sta namespace end.
+}
diff --git a/hacks/src/openlane/io_place.py b/hacks/src/openlane/io_place.py
new file mode 100644
index 0000000..1e8b2b1
--- /dev/null
+++ b/hacks/src/openlane/io_place.py
@@ -0,0 +1,482 @@
+#!/usr/bin/env python3
+# Copyright 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.
+
+"""
+Places the IOs according to an input file. Supports regexes.
+File format:
+#N|#S|#E|#W
+pin1_regex
+pin2_regex
+...
+
+#S|#N|#E|#W
+...
+...
+"""
+
+import os
+import re
+import sys
+import argparse
+import random
+import odb
+
+parser = argparse.ArgumentParser(description='''
+Places the IOs according to an input file. Supports regexes.
+File format:
+#N|#S|#E|#W
+pin1_regex (low co-ordinates to high co-ordinates; e.g., bot to top and left to right)
+pin2_regex
+...
+
+#S|#N|#E|#W
+...
+...
+''')
+
+parser.add_argument('--input-def', '-d', required=True,
+                    help='Input DEF')
+
+parser.add_argument('--input-lef', '-l', required=True,
+                    help='Input LEF')
+
+parser.add_argument('--output-def', '-o',
+                    default='output.def', help='Output DEF with new pin placements')
+
+parser.add_argument('--config', '-cfg',
+                    help='Configuration file. See -h for format')
+
+parser.add_argument('--ver-layer', '-vl',
+                    default=3,
+                    help='Number of metal layer to place the vertical pins on. Defaults to SKY130 metal layer names. 1-based.')
+
+parser.add_argument('--hor-layer', '-hl',
+                    default=4,
+                    help='Number of metal layer to place the horizontal pins on. Defaults to SKY130 metal layer names. 1-based.')
+
+parser.add_argument('--hor-width-mult', '-hwm',
+                    default=2,
+                    help='')
+
+parser.add_argument('--ver-width-mult', '-vwm',
+                    default=2,
+                    help='')
+
+parser.add_argument('--length', '-len', type=float,
+                    default=2,
+                    help='')
+
+parser.add_argument('--hor-extension', '-hext', type=float,
+                    default=0.0,
+                    help='')
+
+parser.add_argument('--ver-extension', '-vext', type=float,
+                    default=0.0,
+                    help='')
+
+parser.add_argument('--reverse', '-rev',
+                    choices=['N', 'E', 'S', 'W'],
+                    nargs='+',
+                    required=False,
+                    default=[],
+                    help='')
+
+parser.add_argument('--bus-sort', '-bsort', action='store_true',
+                    default=False,
+                    help='Sort pins so that bus bits with the same index are grouped'
+                    'together. e.g., a[0] b[0] c[0] a[1] b[1] c[1]')
+# TODO
+# width, length, and extension multipliers
+
+args = parser.parse_args()
+
+def_file_name = args.input_def
+lef_file_name = args.input_lef
+output_def_file_name = args.output_def
+config_file_name = args.config
+bus_sort_flag = args.bus_sort
+
+#Manual Pad Placement - Dinesh A
+manual_place_flag = False 
+
+h_layer_index = int(args.hor_layer)
+v_layer_index = int(args.ver_layer)
+
+h_width_mult = int(args.hor_width_mult)
+v_width_mult = int(args.ver_width_mult)
+
+LENGTH = int(1000*args.length)
+
+H_EXTENSION = int(1000*args.hor_extension)
+V_EXTENSION = int(1000*args.ver_extension)
+
+if H_EXTENSION < 0:
+    H_EXTENSION = 0
+
+if V_EXTENSION < 0:
+    V_EXTENSION = 0
+
+reverse_arr = args.reverse
+reverse_arr = ["#"+rev for rev in reverse_arr]
+
+def getGrid(origin, count, step):
+    tracks = []
+    pos = origin
+    for i in range(count):
+        tracks.append(pos)
+        pos += step
+    assert len(tracks) > 0
+    tracks.sort()
+
+    return tracks
+
+def equallySpacedSeq(m, arr):
+    seq = []
+    n = len(arr)
+    # Bresenham
+    indices = [i*n//m + n//(2*m) for i in range(m)]
+    for i in indices:
+        seq.append(arr[i])
+    return seq
+
+# HUMAN SORTING: https://stackoverflow.com/questions/5967500/how-to-correctly-sort-a-string-with-a-number-inside
+def atof(text):
+    try:
+        retval = float(text)
+    except ValueError:
+        retval = text
+    return retval
+
+def natural_keys(enum):
+    text = enum[0]
+    text = re.sub("(\[|\]|\.|\$)", "", text)
+    '''
+    alist.sort(key=natural_keys) sorts in human order
+    http://nedbatchelder.com/blog/200712/human_sorting.html
+    (see toothy's implementation in the comments)
+    float regex comes from https://stackoverflow.com/a/12643073/190597
+    '''
+    return [atof(c) for c in re.split(r'[+-]?([0-9]+(?:[.][0-9]*)?|[.][0-9]+)', text)]
+
+def bus_keys(enum):
+    text = enum[0]
+    m = re.match("^.*\[(\d+)\]$", text)
+    if not m:
+        return -1
+    else:
+        return int(m.group(1))
+
+# Find the Slot matching next nearest slot-DineshA
+def findSlot(val, arr):
+    for i in arr:
+        if(i > val):
+            return i
+    print("ERROR: Next Valid Position not found :",val)
+    return -1
+
+
+# read config
+
+pin_placement_cfg = {"#N": [], "#E": [], "#S": [], "#W": []}
+cur_side = None
+if config_file_name is not None and config_file_name != "":
+    with open(config_file_name, 'r') as config_file:
+        for line in config_file:
+            line = line.split()
+            if len(line) == 0:
+                continue
+
+            if(manual_place_flag == False):
+                if len(line) > 1:
+                    print("Only one entry allowed per line.")
+                    sys.exit(1)
+
+                token = line[0]
+            else:
+                #During Manual Place we are allowing Four field
+                # <Pad Name> <Offset> <Position> <Multiplier>
+                # Causion: Make sure that you have given absolute name, else it will give issue
+                if len(line) > 4:
+                    print("Only Four entry allowed per line.")
+                    sys.exit(1)
+                if line[0] not in ["#N", "#E", "#S", "#W", "#NR", "#ER", "#SR", "#WR"]:
+                    token = line
+                else:
+                    token = line[0]
+
+            if cur_side is not None and token[0] != "#":
+                pin_placement_cfg[cur_side].append(token)
+            elif token not in ["#N", "#E", "#S", "#W", "#NR", "#ER", "#SR", "#WR", "#BUS_SORT","#MANUAL_PLACE"]:
+                print("Invalid token: ",token)
+                print("Valid directives are #N, #E, #S, or #W. Append R for reversing the default order.",
+                      "Use #BUS_SORT to group 'bus bits' by index.",
+                      "Use #MANUAL_PLACE Manual Placement <padname> <offset> <pin number>.",
+                      "Please make sure you have set a valid side first before listing pins")
+                sys.exit(1)
+            elif token == "#BUS_SORT":
+                bus_sort_flag = True
+            elif token == "#MANUAL_PLACE":
+                print("Input token ",token)
+                manual_place_flag = True
+            else:
+                if len(token) == 3:
+                    token = token[0:2]
+                    reverse_arr.append(token)
+                cur_side = token
+
+# build a list of pins
+
+db_top = odb.dbDatabase.create()
+odb.read_lef(db_top, lef_file_name)
+odb.read_def(db_top, def_file_name)
+
+chip_top = db_top.getChip()
+block_top = chip_top.getBlock()
+top_design_name = block_top.getName()
+tech = db_top.getTech()
+
+H_LAYER = tech.findRoutingLayer(h_layer_index)
+V_LAYER = tech.findRoutingLayer(v_layer_index)
+
+H_WIDTH = h_width_mult * H_LAYER.getWidth()
+V_WIDTH = v_width_mult * V_LAYER.getWidth()
+
+print("Top-level design name:", top_design_name)
+
+bterms = block_top.getBTerms()
+bterms_enum = []
+for bterm in bterms:
+    pin_name = bterm.getName()
+    bterms_enum.append((pin_name, bterm))
+
+# sort them "humanly"
+bterms_enum.sort(key=natural_keys)
+if bus_sort_flag:
+    bterms_enum.sort(key=bus_keys)
+bterms = [bterm[1] for bterm in bterms_enum]
+
+pin_placement = {"#N": [], "#E": [], "#S": [], "#W": []}
+bterm_regex_map = {}
+if(manual_place_flag == False):
+    for side in pin_placement_cfg:
+        for regex in pin_placement_cfg[side]:  # going through them in order
+            regex += "$"  # anchor
+            for bterm in bterms:
+                # if a pin name matches multiple regexes, their order will be
+                # arbitrary. More refinement requires more strict regexes (or just
+                # the exact pin name).
+                pin_name = bterm.getName()
+                if re.match(regex, pin_name) is not None:
+                    if bterm in bterm_regex_map:
+                        print("Warning: Multiple regexes matched", pin_name,
+                              ". Those are", bterm_regex_map[bterm], "and", regex)
+                        print("Only the first one is taken into consideration.")
+                        continue
+                        # sys.exit(1)
+                    bterm_regex_map[bterm] = regex
+                    pin_placement[side].append(bterm)  # to maintain the order
+    
+    unmatched_bterms = [bterm for bterm in bterms if bterm not in bterm_regex_map]
+    
+    if len(unmatched_bterms) > 0:
+        print("Warning: Some pins weren't matched by the config file")
+        print("Those are:", [bterm.getName() for bterm in unmatched_bterms])
+        if True:
+            print("Assigning random sides to the above pins")
+            for bterm in unmatched_bterms:
+                random_side = random.choice(list(pin_placement.keys()))
+                pin_placement[random_side].append(bterm)
+        else:
+            sys.exit(1)
+else:
+    for side in pin_placement_cfg:
+        for regex in pin_placement_cfg[side]:  # going through them in order
+            regex = regex[0]  # take first value
+            regex += "$"  # anchor
+            for bterm in bterms:
+                # if a pin name matches multiple regexes, their order will be
+                # arbitrary. More refinement requires more strict regexes (or just
+                # the exact pin name).
+                pin_name = bterm.getName()
+                if re.match(regex, pin_name) is not None:
+                    print("Debug: Serching Pin match",regex)
+                    if bterm in bterm_regex_map:
+                        #print("Warning: Multiple regexes matched", pin_name)
+                        #      ". Those are", bterm_regex_map[bterm], "and", regex)
+                        sys.exit(1)
+                    bterm_regex_map[bterm] = regex
+                    pin_placement[side].append(bterm)  # to maintain the order
+    
+    unmatched_bterms = [bterm for bterm in bterms if bterm not in bterm_regex_map]
+    
+    if len(unmatched_bterms) > 0:
+        print("Warning: Some pins weren't matched by the config file")
+        print("Those are:", [bterm.getName() for bterm in unmatched_bterms])
+        sys.exit(1)
+
+
+assert len(block_top.getBTerms()) == len(pin_placement["#N"] + pin_placement["#E"] + pin_placement["#S"] + pin_placement["#W"])
+
+# generate slots
+
+
+DIE_AREA = block_top.getDieArea()
+BLOCK_LL_X = DIE_AREA.xMin()
+BLOCK_LL_Y = DIE_AREA.yMin()
+BLOCK_UR_X = DIE_AREA.xMax()
+BLOCK_UR_Y = DIE_AREA.yMax()
+
+print("Block boundaries:", BLOCK_LL_X, BLOCK_LL_Y, BLOCK_UR_X, BLOCK_UR_Y)
+
+
+origin, count, step = block_top.findTrackGrid(H_LAYER).getGridPatternY(0)
+
+# Save the horizontal origin and step - DineshA
+h_origin = origin
+h_step   = step
+
+h_tracks = getGrid(origin, count, step)
+
+origin, count, step = block_top.findTrackGrid(V_LAYER).getGridPatternX(0)
+
+# Save the horizontal origin and step - DineshA
+v_origin = origin
+v_step   = step
+
+v_tracks = getGrid(origin, count, step)
+
+for rev in reverse_arr:
+    pin_placement[rev].reverse()
+
+if(manual_place_flag == False):
+    # create the pins
+    # old logic
+    for side in pin_placement:
+        start = 0
+        if side in ["#N", "#S"]:
+            slots = equallySpacedSeq(len(pin_placement[side]), v_tracks)
+        else:
+            slots = equallySpacedSeq(len(pin_placement[side]), h_tracks)
+    
+        assert len(slots) == len(pin_placement[side])
+    
+        for i in range(len(pin_placement[side])):
+            bterm = pin_placement[side][i]
+            slot = slots[i]
+    
+            pin_name = bterm.getName()
+            pins = bterm.getBPins()
+            if len(pins) > 0:
+                print("Warning:", pin_name, "already has shapes. Modifying them")
+                assert len(pins) == 1
+                pin_bpin = pins[0]
+            else:
+                pin_bpin = odb.dbBPin_create(bterm)
+    
+            print("Dinesh: Placing Pad:" ,pin_name, " At Side: ", side, " Slot: ", slot)
+            pin_bpin.setPlacementStatus("PLACED")
+    
+            if side in ["#N", "#S"]:
+                rect = odb.Rect(0, 0, V_WIDTH, LENGTH+V_EXTENSION)
+                if side == "#N":
+                    y = BLOCK_UR_Y-LENGTH
+                else:
+                    y = BLOCK_LL_Y-V_EXTENSION
+                rect.moveTo(slot-V_WIDTH//2, y)
+                odb.dbBox_create(pin_bpin, V_LAYER, *rect.ll(), *rect.ur())
+            else:
+                rect = odb.Rect(0, 0, LENGTH+H_EXTENSION, H_WIDTH)
+                if side == "#E":
+                    x = BLOCK_UR_X-LENGTH
+                else:
+                    x = BLOCK_LL_X-H_EXTENSION
+                rect.moveTo(x, slot-H_WIDTH//2)
+                odb.dbBox_create(pin_bpin, H_LAYER, *rect.ll(), *rect.ur())
+else:
+    #New Logic, Manual Pin Placement - Dinesh A
+    #print("Allowed VTracks",v_tracks)
+    #print("Allowed hTracks",h_tracks)
+
+    for side in pin_placement:
+
+        if(len(pin_placement[side]) != len(pin_placement_cfg[side])):
+            print("ERROR : At Side:", side, " Total Pin Defined ",len(pin_placement_cfg[side]), "More than available:",len(pin_placement[side]))
+            
+        #check defined pad are more than avaibale one
+        assert len(pin_placement[side]) == len(pin_placement_cfg[side])
+        start = 0
+    
+        start_loc = 0
+        pad_pos   = 0
+        slot_pre = 0
+        #Dinesh: Give Step Multipler size *2  for better pad placement
+        multiplier= 2
+        for i in range(len(pin_placement_cfg[side])):
+            #Dinesh: Multiply the offset by 1000 for micro conversion
+            if(len(pin_placement_cfg[side][i]) > 1):
+                start_loc = int(pin_placement_cfg[side][i][1])
+            if(len(pin_placement_cfg[side][i]) > 2):
+                pad_pos   = int(pin_placement_cfg[side][i][2])
+            if(len(pin_placement_cfg[side][i]) > 3):
+                multiplier = int(pin_placement_cfg[side][i][3])
+
+            if side in ["#N", "#S"]:
+                slott = start_loc*1000+int(v_origin)+(int(v_step) * pad_pos * multiplier)
+                slot =findSlot(slott,v_tracks)
+            else:
+                slott = start_loc*1000+int(h_origin)+(int(h_step) * pad_pos * multiplier)
+                slot =findSlot(slott,h_tracks)
+          
+            pad_pos +=1
+            bterm = pin_placement[side][i]
+    
+            pin_name = bterm.getName()
+            pins = bterm.getBPins()
+            if len(pins) > 0:
+                print("Warning:", pin_name, "already has shapes. Modifying them")
+                assert len(pins) == 1
+                pin_bpin = pins[0]
+            else:
+                pin_bpin = odb.dbBPin_create(bterm)
+
+            if(slot < slot_pre):
+                print("ERROR:", "Current Pad:", pin_name, " Slot:" , slot, " is less than Previous Slot:",slot_pre)
+                sys.exit(1)
+
+            slot_pre = slot
+
+            print("Dinesh: Placing Pad:" ,pin_name, " At Side: ", side, " Slot: ", slot)
+            pin_bpin.setPlacementStatus("PLACED")
+    
+            if side in ["#N", "#S"]:
+                rect = odb.Rect(0, 0, V_WIDTH, LENGTH+V_EXTENSION)
+                if side == "#N":
+                    y = BLOCK_UR_Y-LENGTH
+                else:
+                    y = BLOCK_LL_Y-V_EXTENSION
+                rect.moveTo(slot-V_WIDTH//2, y)
+                odb.dbBox_create(pin_bpin, V_LAYER, *rect.ll(), *rect.ur())
+            else:
+                rect = odb.Rect(0, 0, LENGTH+H_EXTENSION, H_WIDTH)
+                if side == "#E":
+                    x = BLOCK_UR_X-LENGTH
+                else:
+                    x = BLOCK_LL_X-H_EXTENSION
+                rect.moveTo(x, slot-H_WIDTH//2)
+                odb.dbBox_create(pin_bpin, H_LAYER, *rect.ll(), *rect.ur())
+    
+
+print("Writing", output_def_file_name)
+odb.write_def(block_top, output_def_file_name)
diff --git a/hacks/src/openlane/synth.tcl b/hacks/src/openlane/synth.tcl
new file mode 100755
index 0000000..2cf1003
--- /dev/null
+++ b/hacks/src/openlane/synth.tcl
@@ -0,0 +1,373 @@
+# Copyright 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.
+
+# inputs expected as env vars
+#set opt $::env(SYNTH_OPT)
+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) {
+		lappend vIdirsArgs "-I$dir"
+	}
+	set vIdirsArgs [join $vIdirsArgs]
+}
+
+if { $::env(SYNTH_READ_BLACKBOX_LIB) } {
+	log "Reading $::env(LIB_SYNTH_COMPLETE_NO_PG) as a blackbox"
+	foreach lib $::env(LIB_SYNTH_COMPLETE_NO_PG) {
+		read_liberty -lib -ignore_miss_dir -setattr blackbox $lib
+	}
+}
+
+if { [info exists ::env(EXTRA_LIBS) ] } {
+	foreach lib $::env(EXTRA_LIBS) {
+		read_liberty -lib -ignore_miss_dir -setattr blackbox $lib
+	}
+}
+
+if { [info exists ::env(VERILOG_FILES_BLACKBOX)] } {
+	foreach verilog_file $::env(VERILOG_FILES_BLACKBOX) {
+		read_verilog -sv -lib {*}$vIdirsArgs $verilog_file
+	}
+}
+
+
+# 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}]
+}
+
+set adder_type $::env(SYNTH_ADDER_TYPE)
+if { !($adder_type in [list "YOSYS" "FA" "RCA" "CSA"]) } {
+	log -stderr "\[ERROR] Misformatted SYNTH_ADDER_TYPE (\"$::env(SYNTH_ADDER_TYPE)\")."
+	log -stderr "\[ERROR] Correct format is \"YOSYS|FA|RCA|CSA\"."
+	exit 1
+}
+
+for { set i 0 } { $i < [llength $::env(VERILOG_FILES)] } { incr i } {
+	read_verilog -sv {*}$vIdirsArgs [lindex $::env(VERILOG_FILES) $i]
+}
+## Module level parameter overide - Dinesh
+if { [info exists ::env(SYNTH_PARAMS) ] } {
+    log "Reading $::env(SYNTH_PARAMS) as a parameter"
+    set records [split $::env(SYNTH_PARAMS) ","]
+    foreach rec $records {
+       chparam -set [lindex $rec 0] [lindex $rec 1] $vtop
+    }
+} else {
+	log "No parameter define found"
+}
+
+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)"
+        }
+}
+
+# handle technology mapping of rca and csa adders
+if { $adder_type == "RCA"} {
+	if { [info exists ::env(RIPPLE_CARRY_ADDER_MAP)] && [file exists $::env(RIPPLE_CARRY_ADDER_MAP)] } {
+		techmap -map $::env(RIPPLE_CARRY_ADDER_MAP)
+	}
+} elseif { $adder_type == "CSA"} {
+	if { [info exists ::env(CARRY_SELECT_ADDER_MAP)] && [file exists $::env(CARRY_SELECT_ADDER_MAP)] } {
+		techmap -map $::env(CARRY_SELECT_ADDER_MAP)
+	}
+}
+
+if { $::env(SYNTH_NO_FLAT) } {
+	synth -top $vtop
+} else {
+	synth -top $vtop -flatten
+}
+
+# write a post techmap dot file
+show -format dot -prefix $::env(TMP_DIR)/synthesis/post_techmap
+
+if { $::env(SYNTH_SHARE_RESOURCES) } {
+	share -aggressive
+}
+
+set fa_map false
+if { $adder_type == "FA" } {
+	if { [info exists ::env(FULL_ADDER_MAP)] && [file exists $::env(FULL_ADDER_MAP)] } {
+		extract_fa -fa -v
+		extract_fa -ha -v
+		set fa_map true
+	}
+}
+
+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
+}
+
+# Map Full Adders.
+if { $fa_map } {
+	techmap -map $::env(FULL_ADDER_MAP)
+}
+
+# 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)
+
+		splitnets
+		opt_clean -purge
+		insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT)
+
+		tee -o "$::env(yosys_report_file_tag)_$index$chk_ext" check
+		tee -o "$::env(yosys_report_file_tag)$index$stat_ext" stat -top $vtop -liberty [lindex $::env(LIB_SYNTH_COMPLETE_NO_PG) 0]
+		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 init_floorplan fail
+	splitnets
+	opt_clean -purge
+	insbuf -buf {*}$::env(SYNTH_MIN_BUF_PORT)
+
+	tee -o "$::env(yosys_report_file_tag)_$strategy$chk_ext" check
+	tee -o "$::env(yosys_report_file_tag)_$strategy$stat_ext" stat -top $vtop -liberty [lindex $::env(LIB_SYNTH_COMPLETE_NO_PG) 0]
+	write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(SAVE_NETLIST)"
+}
+
+if { $::env(SYNTH_NO_FLAT) } {
+	design -reset
+	read_liberty -lib -ignore_miss_dir -setattr blackbox $::env(LIB_SYNTH_COMPLETE_NO_PG)
+	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
+	tee -o "$::env(yosys_report_file_tag)_$strategy$stat_ext" stat -top $vtop -liberty [lindex $::env(LIB_SYNTH_COMPLETE_NO_PG) 0]
+}
diff --git a/hacks/src/openlane/synth_top.tcl b/hacks/src/openlane/synth_top.tcl
new file mode 100755
index 0000000..65bb8fa
--- /dev/null
+++ b/hacks/src/openlane/synth_top.tcl
@@ -0,0 +1,97 @@
+# Copyright 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.
+
+set vtop $::env(DESIGN_NAME)
+#set sdc_file $::env(SDC_FILE)
+set sclib $::env(LIB_SYNTH)
+yosys -import
+
+set stat_ext    ".stat.rpt"
+set chk_ext    ".chk.rpt"
+set gl_ext      ".gl.v"
+set timing_ext  ".timing.txt"
+set abc_ext     ".abc"
+
+if { $::env(SYNTH_READ_BLACKBOX_LIB) } {
+	foreach lib $::env(LIB_SYNTH_COMPLETE_NO_PG) {
+		read_liberty -lib -ignore_miss_dir -setattr blackbox $lib
+	}
+}
+
+if { [info exists ::env(EXTRA_LIBS) ] } {
+	foreach lib $::env(EXTRA_LIBS) {
+		read_liberty -lib -ignore_miss_dir -setattr blackbox $lib
+	}
+}
+
+
+if { [info exists ::env(SYNTH_DEFINES) ] } {
+	foreach define $::env(SYNTH_DEFINES) {
+		verilog_defines -D$define
+	}
+}
+
+set vIdirsArgs ""
+if {[info exist ::env(VERILOG_INCLUDE_DIRS)]} {
+	foreach dir $::env(VERILOG_INCLUDE_DIRS) {
+		lappend vIdirsArgs "-I$dir"
+	}
+	set vIdirsArgs [join $vIdirsArgs]
+}
+
+if { [info exists ::env(VERILOG_FILES_BLACKBOX)] } {
+	foreach verilog_file $::env(VERILOG_FILES_BLACKBOX) {
+		read_verilog -lib {*}$vIdirsArgs $verilog_file
+	}
+}
+
+
+for { set i 0 } { $i < [llength $::env(VERILOG_FILES)] } { incr i } {
+  read_verilog {*}$vIdirsArgs [lindex $::env(VERILOG_FILES) $i]
+}
+
+select -module $vtop
+
+## Module level parameter overide - Dinesh
+if { [info exists ::env(SYNTH_PARAMS) ] } {
+    log "Reading $::env(SYNTH_PARAMS) as a parameter"
+    set records [split $::env(SYNTH_PARAMS) ","]
+    foreach rec $records {
+       chparam -set [lindex $rec 0] [lindex $rec 1] $vtop
+    }
+} else {
+	log "No parameter define found"
+}
+
+
+show -format dot -prefix $::env(TMP_DIR)/synthesis/hierarchy
+select -clear
+
+hierarchy -check -top $vtop
+if { $::env(SYNTH_FLAT_TOP) } {
+	flatten
+}
+
+setattr -set keep 1
+#synth -top $vtop
+tee -o "$::env(yosys_report_file_tag)_synth.stat" stat
+
+
+#debug opt_clean -purge
+#setundef -zero
+splitnets
+opt_clean -purge
+tee -o "$::env(yosys_report_file_tag)_$chk_ext" check
+tee -o "$::env(yosys_report_file_tag)$stat_ext" stat -top $vtop -liberty $sclib
+write_verilog -noattr -noexpr -nohex -nodec -defparam "$::env(SAVE_NETLIST)"
diff --git a/info.yaml b/info.yaml
new file mode 100644
index 0000000..3d40251
--- /dev/null
+++ b/info.yaml
@@ -0,0 +1,19 @@
+---
+project:
+  description: "A Custom SoC for Google sponsored Open MPW shuttles for SKY130."
+  foundry: "SkyWater"
+  git_url: "https://github.com/dineshannayya/yifive_r0.git"
+  organization: "None"
+  organization_url: "None"
+  owner: "Dinesh Annayya"
+  process: "SKY130"
+  project_name: "YiFive"
+  project_id: "00000000"
+  tags:
+    - "Open MPW"
+    - "MPW-TWO"
+  category: "Processor"
+  top_level_netlist: "caravel/verilog/gl/caravel.v"
+  user_level_netlist: "verilog/gl/user_project_wrapper.v"
+  version: "1.00"
+  cover_image: "docs/source/_static/YiFive_Soc.png"
diff --git a/lib/sky130_sram_2kbyte_1rw1r_32x512_8_TT_1p8V_25C.lib b/lib/sky130_sram_2kbyte_1rw1r_32x512_8_TT_1p8V_25C.lib
new file mode 100644
index 0000000..f1e226c
--- /dev/null
+++ b/lib/sky130_sram_2kbyte_1rw1r_32x512_8_TT_1p8V_25C.lib
@@ -0,0 +1,538 @@
+library (sky130_sram_2kbyte_1rw1r_32x512_8_TT_1p8V_25C_lib){
+    delay_model : "table_lookup";
+    time_unit : "1ns" ;
+    voltage_unit : "1V" ;
+    current_unit : "1mA" ;
+    resistance_unit : "1kohm" ;
+    capacitive_load_unit(1, pF) ;
+    leakage_power_unit : "1mW" ;
+    pulling_resistance_unit :"1kohm" ;
+    operating_conditions(OC){
+    process : 1.0 ;
+    voltage : 1.8 ;
+    temperature : 25;
+    }
+
+    input_threshold_pct_fall       :  50.0 ;
+    output_threshold_pct_fall      :  50.0 ;
+    input_threshold_pct_rise       :  50.0 ;
+    output_threshold_pct_rise      :  50.0 ;
+    slew_lower_threshold_pct_fall  :  10.0 ;
+    slew_upper_threshold_pct_fall  :  90.0 ;
+    slew_lower_threshold_pct_rise  :  10.0 ;
+    slew_upper_threshold_pct_rise  :  90.0 ;
+
+    nom_voltage : 1.8;
+    nom_temperature : 25;
+    nom_process : 1.0;
+    default_cell_leakage_power    : 0.0 ;
+    default_leakage_power_density : 0.0 ;
+    default_input_pin_cap    : 1.0 ;
+    default_inout_pin_cap    : 1.0 ;
+    default_output_pin_cap   : 0.0 ;
+    default_max_transition   : 0.5 ;
+    default_fanout_load      : 1.0 ;
+    default_max_fanout   : 4.0 ;
+    default_connection_class : universal ;
+
+    voltage_map ( VCCD1, 1.8 );
+    voltage_map ( VSSD1, 0 );
+
+    lu_table_template(CELL_TABLE){
+        variable_1 : input_net_transition;
+        variable_2 : total_output_net_capacitance;
+        index_1("0.00125, 0.005, 0.04");
+        index_2("0.0017224999999999999, 0.006889999999999999, 0.027559999999999998");
+    }
+
+    lu_table_template(CONSTRAINT_TABLE){
+        variable_1 : related_pin_transition;
+        variable_2 : constrained_pin_transition;
+        index_1("0.00125, 0.005, 0.04");
+        index_2("0.00125, 0.005, 0.04");
+    }
+
+    default_operating_conditions : OC; 
+
+
+    type (data){
+    base_type : array;
+    data_type : bit;
+    bit_width : 32;
+    bit_from : 31;
+    bit_to : 0;
+    }
+
+    type (addr){
+    base_type : array;
+    data_type : bit;
+    bit_width : 9;
+    bit_from : 8;
+    bit_to : 0;
+    }
+
+    type (wmask){
+    base_type : array;
+    data_type : bit;
+    bit_width : 4;
+    bit_from : 3;
+    bit_to : 0;
+    }
+
+cell (sky130_sram_2kbyte_1rw1r_32x512_8){
+    memory(){ 
+    type : ram;
+    address_width : 9;
+    word_width : 32;
+    }
+    interface_timing : true;
+    dont_use  : true;
+    map_only   : true;
+    dont_touch : true;
+    area : 284538.474;
+
+    pg_pin(vccd1) {
+         voltage_name : VCCD1;
+         pg_type : primary_power;
+    }
+
+    pg_pin(vssd1) {
+         voltage_name : VSSD1;
+         pg_type : primary_ground;
+    }
+
+    leakage_power () {
+      value : 0.017726;
+    }
+    cell_leakage_power : 0.017726;
+    bus(din0){
+        bus_type  : data; 
+        direction  : input; 
+        capacitance : 0.006889999999999999;  
+        memory_write(){ 
+            address : addr0; 
+            clocked_on  : clk0; 
+        }
+        pin(din0[31:0]){
+        timing(){ 
+            timing_type : setup_rising; 
+            related_pin  : "clk0"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+        }
+        timing(){ 
+            timing_type : hold_rising; 
+            related_pin  : "clk0"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+              }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+            }
+        }
+        }
+    }
+    bus(dout0){
+        bus_type  : data; 
+        direction  : output; 
+        max_capacitance : 0.027559999999999998;  
+        min_capacitance : 0.0017224999999999999;  
+        memory_read(){ 
+            address : addr0; 
+        }
+        pin(dout0[31:0]){
+        timing(){ 
+            timing_sense : non_unate; 
+            related_pin : "clk0"; 
+            timing_type : falling_edge; 
+            cell_rise(CELL_TABLE) {
+            values("0.383, 0.412, 0.529",\
+                   "0.383, 0.412, 0.529",\
+                   "0.383, 0.412, 0.529");
+            }
+            cell_fall(CELL_TABLE) {
+            values("0.383, 0.412, 0.529",\
+                   "0.383, 0.412, 0.529",\
+                   "0.383, 0.412, 0.529");
+            }
+            rise_transition(CELL_TABLE) {
+            values("0.002, 0.005, 0.016",\
+                   "0.002, 0.005, 0.016",\
+                   "0.002, 0.005, 0.016");
+            }
+            fall_transition(CELL_TABLE) {
+            values("0.002, 0.005, 0.016",\
+                   "0.002, 0.005, 0.016",\
+                   "0.002, 0.005, 0.016");
+            }
+        }
+        }
+    }
+
+    bus(addr0){
+        bus_type  : addr; 
+        direction  : input; 
+        capacitance : 0.006889999999999999;  
+        max_transition       : 0.04;
+        pin(addr0[8:0]){
+        timing(){ 
+            timing_type : setup_rising; 
+            related_pin  : "clk0"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+        }
+        timing(){ 
+            timing_type : hold_rising; 
+            related_pin  : "clk0"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+              }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+            }
+        }
+        }
+    }
+
+    bus(wmask0){
+        bus_type  : wmask; 
+        direction  : input; 
+        capacitance : 0.006889999999999999;  
+        max_transition       : 0.04;
+        pin(wmask0[3:0]){
+        timing(){ 
+            timing_type : setup_rising; 
+            related_pin  : "clk0"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+        }
+        timing(){ 
+            timing_type : hold_rising; 
+            related_pin  : "clk0"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+              }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+            }
+        }
+        }
+    }
+
+    pin(csb0){
+        direction  : input; 
+        capacitance : 0.006889999999999999;  
+        timing(){ 
+            timing_type : setup_rising; 
+            related_pin  : "clk0"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+        }
+        timing(){ 
+            timing_type : hold_rising; 
+            related_pin  : "clk0"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+              }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+            }
+        }
+    }
+
+    pin(web0){
+        direction  : input; 
+        capacitance : 0.006889999999999999;  
+        timing(){ 
+            timing_type : setup_rising; 
+            related_pin  : "clk0"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+        }
+        timing(){ 
+            timing_type : hold_rising; 
+            related_pin  : "clk0"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+              }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+            }
+        }
+    }
+
+    pin(clk0){
+        clock             : true;
+        direction  : input; 
+        capacitance : 0.006889999999999999;  
+        internal_power(){
+            when : "!csb0 & !web0"; 
+            rise_power(scalar){
+                values("1.380840e+01");
+            }
+            fall_power(scalar){
+                values("1.380840e+01");
+            }
+        }
+        internal_power(){
+            when : "csb0 & !web0"; 
+            rise_power(scalar){
+                values("1.380840e+01");
+            }
+            fall_power(scalar){
+                values("1.380840e+01");
+            }
+        }
+        internal_power(){
+            when : "!csb0 & web0"; 
+            rise_power(scalar){
+                values("1.380840e+01");
+            }
+            fall_power(scalar){
+                values("1.380840e+01");
+            }
+        }
+        internal_power(){
+            when : "csb0 & web0"; 
+            rise_power(scalar){
+                values("1.380840e+01");
+            }
+            fall_power(scalar){
+                values("1.380840e+01");
+            }
+        }
+        timing(){ 
+            timing_type :"min_pulse_width"; 
+            related_pin  : clk0; 
+            rise_constraint(scalar) {
+                values("0.978"); 
+            }
+            fall_constraint(scalar) {
+                values("0.978"); 
+            }
+         }
+        timing(){ 
+            timing_type :"minimum_period"; 
+            related_pin  : clk0; 
+            rise_constraint(scalar) {
+                values("1.956"); 
+            }
+            fall_constraint(scalar) {
+                values("1.956"); 
+            }
+         }
+    }
+
+    bus(dout1){
+        bus_type  : data; 
+        direction  : output; 
+        max_capacitance : 0.027559999999999998;  
+        min_capacitance : 0.0017224999999999999;  
+        memory_read(){ 
+            address : addr1; 
+        }
+        pin(dout1[31:0]){
+        timing(){ 
+            timing_sense : non_unate; 
+            related_pin : "clk1"; 
+            timing_type : falling_edge; 
+            cell_rise(CELL_TABLE) {
+            values("0.383, 0.412, 0.529",\
+                   "0.383, 0.412, 0.529",\
+                   "0.383, 0.412, 0.529");
+            }
+            cell_fall(CELL_TABLE) {
+            values("0.383, 0.412, 0.529",\
+                   "0.383, 0.412, 0.529",\
+                   "0.383, 0.412, 0.529");
+            }
+            rise_transition(CELL_TABLE) {
+            values("0.002, 0.005, 0.016",\
+                   "0.002, 0.005, 0.016",\
+                   "0.002, 0.005, 0.016");
+            }
+            fall_transition(CELL_TABLE) {
+            values("0.002, 0.005, 0.016",\
+                   "0.002, 0.005, 0.016",\
+                   "0.002, 0.005, 0.016");
+            }
+        }
+        }
+    }
+
+    bus(addr1){
+        bus_type  : addr; 
+        direction  : input; 
+        capacitance : 0.006889999999999999;  
+        max_transition       : 0.04;
+        pin(addr1[8:0]){
+        timing(){ 
+            timing_type : setup_rising; 
+            related_pin  : "clk1"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+        }
+        timing(){ 
+            timing_type : hold_rising; 
+            related_pin  : "clk1"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+              }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+            }
+        }
+        }
+    }
+
+    pin(csb1){
+        direction  : input; 
+        capacitance : 0.006889999999999999;  
+        timing(){ 
+            timing_type : setup_rising; 
+            related_pin  : "clk1"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103",\
+                   "0.103, 0.103, 0.103");
+            }
+        }
+        timing(){ 
+            timing_type : hold_rising; 
+            related_pin  : "clk1"; 
+            rise_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+              }
+            fall_constraint(CONSTRAINT_TABLE) {
+            values("-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056",\
+                   "-0.056, -0.056, -0.056");
+            }
+        }
+    }
+
+    pin(clk1){
+        clock             : true;
+        direction  : input; 
+        capacitance : 0.006889999999999999;  
+        internal_power(){
+            when : "!csb1"; 
+            rise_power(scalar){
+                values("1.380840e+01");
+            }
+            fall_power(scalar){
+                values("1.380840e+01");
+            }
+        }
+        internal_power(){
+            when : "csb1"; 
+            rise_power(scalar){
+                values("1.380840e+01");
+            }
+            fall_power(scalar){
+                values("1.380840e+01");
+            }
+        }
+        timing(){ 
+            timing_type :"min_pulse_width"; 
+            related_pin  : clk1; 
+            rise_constraint(scalar) {
+                values("0.978"); 
+            }
+            fall_constraint(scalar) {
+                values("0.978"); 
+            }
+         }
+        timing(){ 
+            timing_type :"minimum_period"; 
+            related_pin  : clk1; 
+            rise_constraint(scalar) {
+                values("1.956"); 
+            }
+            fall_constraint(scalar) {
+                values("1.956"); 
+            }
+         }
+    }
+
+    }
+}
diff --git a/openlane/Makefile b/openlane/Makefile
new file mode 100644
index 0000000..a960416
--- /dev/null
+++ b/openlane/Makefile
@@ -0,0 +1,91 @@
+# 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
+
+#SHELL = sh -xv
+BLOCKS = $(shell find * -maxdepth 0 -type d)
+CONFIG = $(foreach block,$(BLOCKS), ./$(block)/config.tcl)
+CLEAN = $(foreach block,$(BLOCKS), clean-$(block))
+
+OPENLANE_TAG ?= mpw4
+OPENLANE_IMAGE_NAME ?= dineshannayya/openlane:$(OPENLANE_TAG)
+OPENLANE_BASIC_COMMAND = "cd /project/openlane && flow.tcl -design ./$* -save_path .. -save -tag $* -overwrite"
+OPENLANE_INTERACTIVE_COMMAND = "cd /project/openlane && flow.tcl -it -file ./$*/interactive.tcl -design ./$* -save_path .. -save -tag $* -overwrite"
+
+all: $(BLOCKS)
+
+$(CONFIG) :
+	@echo "Missing $@. Please create a configuration for that design"
+	@exit 1
+
+$(BLOCKS) : % : ./%/config.tcl FORCE
+ifeq ($(OPENLANE_ROOT),)
+	@echo "Please export OPENLANE_ROOT"
+	@exit 1
+endif
+ifeq ($(PDK_ROOT),)
+	@echo "Please export PDK_ROOT"
+	@exit 1
+endif
+	@echo "###############################################"
+	@sleep 1
+
+	@if [ -f ./$*/interactive.tcl ]; then\
+		docker run -it -v $(OPENLANE_ROOT):/openLANE_flow \
+		-v $(PDK_ROOT):$(PDK_ROOT) \
+		-v $(PWD)/..:/project \
+		-v $(CARAVEL_ROOT):$(CARAVEL_ROOT) \
+		-e PDK_ROOT=$(PDK_ROOT) \
+		-e CARAVEL_ROOT=$(CARAVEL_ROOT) \
+		-u $(shell id -u $(USER)):$(shell id -g $(USER)) \
+		$(OPENLANE_IMAGE_NAME) sh -c $(OPENLANE_INTERACTIVE_COMMAND);\
+	else\
+		docker run -it -v $(OPENLANE_ROOT):/openLANE_flow \
+		-v $(PDK_ROOT):$(PDK_ROOT) \
+		-v $(PWD)/..:/project \
+		-v $(CARAVEL_ROOT):$(CARAVEL_ROOT) \
+		-e PDK_ROOT=$(PDK_ROOT) \
+		-e CARAVEL_ROOT=$(CARAVEL_ROOT) \
+		-u $(shell id -u $(USER)):$(shell id -g $(USER)) \
+		$(OPENLANE_IMAGE_NAME) sh -c $(OPENLANE_BASIC_COMMAND);\
+	fi
+	mkdir -p ../signoff/$*/
+	cp $*/runs/$*/OPENLANE_VERSION ../signoff/$*/
+	cp $*/runs/$*/PDK_SOURCES ../signoff/$*/
+	cp $*/runs/$*/reports/final_summary_report.csv ../signoff/$*/
+
+.PHONY: openlane
+openlane:
+ifeq ($(OPENLANE_ROOT),)
+	@echo "Please export OPENLANE_ROOT"
+	@exit 1
+endif
+	git clone https://github.com/efabless/OpenLane --branch=$(OPENLANE_TAG) --depth=1 $(OPENLANE_ROOT) && \
+		cd $(OPENLANE_ROOT) && \
+		export IMAGE_NAME=efabless/openlane:$(OPENLANE_TAG) && \
+		make openlane
+
+FORCE:
+
+clean:
+	@echo "Use clean_all to clean everything :)"
+
+clean_all: $(CLEAN)
+
+$(CLEAN): clean-% :
+	rm -rf runs/$*
+	rm -rf ../gds/$**
+	rm -rf ../mag/$**
+	rm -rf ../lef/$**
diff --git a/openlane/clk_skew_adjust/config.tcl b/openlane/clk_skew_adjust/config.tcl
new file mode 100644
index 0000000..8abd1f4
--- /dev/null
+++ b/openlane/clk_skew_adjust/config.tcl
@@ -0,0 +1,76 @@
+# 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
+# SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+
+# Global
+# ------
+
+set script_dir [file dirname [file normalize [info script]]]
+
+set ::env(DESIGN_NAME) clk_skew_adjust
+set verilog_root $script_dir/../../verilog/
+set lef_root $script_dir/../../lef/
+set gds_root $script_dir/../../gds/
+#section end
+
+# User Configurations
+#
+set ::env(DESIGN_IS_CORE) 0
+set ::env(FP_PDN_CORE_RING) "0"
+
+
+## Source Verilog Files
+set ::env(VERILOG_FILES) "\
+	$script_dir/../../verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv"
+
+## Clock configurations
+#set ::env(CLOCK_PORT) "clk_in"
+
+#set ::env(CLOCK_PERIOD) "10"
+
+## Internal Macros
+### Macro Placement
+set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+
+set ::env(FP_SIZING) absolute
+set ::env(DIE_AREA) "0 0 100 100"
+
+
+
+
+set ::env(VDD_PIN) [list {vccd1}]
+set ::env(GND_PIN) [list {vssd1}]
+
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+
+# Fill this
+set ::env(CLOCK_TREE_SYNTH) 0
+
+set ::env(CELL_PAD) 4
+
+set ::env(FP_CORE_UTIL) 40
+set ::env(PL_RANDOM_GLB_PLACEMENT) 1
+
+set ::env(BOTTOM_MARGIN_MULT) 2
+set ::env(TOP_MARGIN_MULT) 2
+set ::env(GLB_RT_MAXLAYER) 4
+
+# helps in anteena fix
+set ::env(USE_ARC_ANTENNA_CHECK) "0"
+
+set ::env(FP_PDN_VPITCH) 20
+set ::env(FP_PDN_HPITCH) 20
+set ::env(FP_PDN_VWIDTH) 3
+set ::env(FP_PDN_HWIDTH) 3
diff --git a/openlane/clk_skew_adjust/pin_order.cfg b/openlane/clk_skew_adjust/pin_order.cfg
new file mode 100644
index 0000000..73fa0a0
--- /dev/null
+++ b/openlane/clk_skew_adjust/pin_order.cfg
@@ -0,0 +1,13 @@
+#BUS_SORT
+
+#MANUAL_PLACE
+
+#W
+clk_out              0000 0
+
+#E
+clk_in              0000 0
+sel\[3\]            0000 10
+sel\[2\]            0000 11
+sel\[1\]            0000 12
+sel\[0\]            0000 13
diff --git a/openlane/io_place.py b/openlane/io_place.py
new file mode 100755
index 0000000..86ac1f2
--- /dev/null
+++ b/openlane/io_place.py
@@ -0,0 +1,528 @@
+# Copyright 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.
+
+"""
+Places the IOs according to an input file. Supports regexes.
+File format:
+#N|#S|#E|#W
+pin1_regex
+pin2_regex
+...
+
+#S|#N|#E|#W
+...
+...
+"""
+import odb
+
+import os
+import re
+import sys
+import click
+import random
+
+
+@click.command()
+@click.option("-l", "--input-lef", required=True, help="Input merged tlef/lef file.")
+@click.option(
+    "-o",
+    "--output-def",
+    default="./output.def",
+    help="Output DEF file with newly placed pins",
+)
+@click.option("-c", "--config", required=False, help="Optional configuration file.")
+@click.option(
+    "-r",
+    "--reverse",
+    default="",
+    type=str,
+    help="Reverse along comma,delimited,cardinals: e.g. N,E",
+)
+@click.option("-L", "--length", default=2, type=float, help="Pin length in microns.")
+@click.option(
+    "-V",
+    "--ver-layer",
+    required=True,
+    help="Name of metal layer to place vertical pins on.",
+)
+@click.option(
+    "-H",
+    "--hor-layer",
+    required=True,
+    help="Name of metal layer to place horizontal pins on.",
+)
+@click.option(
+    "--hor-extension",
+    default=0,
+    type=float,
+    help="Extension for vertical pins in microns.",
+)
+@click.option(
+    "--ver-extension",
+    default=0,
+    type=float,
+    help="Extension for horizontal pins in microns.",
+)
+@click.option(
+    "--ver-width-mult", default=2, type=float, help="Multiplier for vertical pins."
+)
+@click.option(
+    "--hor-width-mult", default=2, type=float, help="Multiplier for horizontal pins."
+)
+@click.option(
+    "--bus-sort/--no-bus-sort",
+    default=False,
+    help="Misnomer: pins are grouped by index instead of bus, i.e. a[0] goes with b[0] instead of a[1].",
+)
+@click.argument("input_def")
+def cli(
+    input_lef,
+    output_def,
+    config,
+    ver_layer,
+    hor_layer,
+    ver_width_mult,
+    hor_width_mult,
+    length,
+    hor_extension,
+    ver_extension,
+    reverse,
+    bus_sort,
+    input_def,
+):
+    """
+    Places the IOs in an input def with an optional config file that supports regexes.
+
+    Config format:
+    #N|#S|#E|#W
+    pin1_regex (low co-ordinates to high co-ordinates; e.g., bottom to top and left to right)
+    pin2_regex
+    ...
+
+    #S|#N|#E|#W
+    """
+
+    def_file_name = input_def
+    lef_file_name = input_lef
+    output_def_file_name = output_def
+    config_file_name = config
+    bus_sort_flag = bus_sort
+
+    #1. Manual Pad Placement - Dinesh A
+    manual_place_flag = False 
+
+    h_layer_name = hor_layer
+    v_layer_name = ver_layer
+
+    h_width_mult = float(hor_width_mult)
+    v_width_mult = float(ver_width_mult)
+
+    # Initialize OpenDB
+    db_top = odb.dbDatabase.create()
+    odb.read_lef(db_top, lef_file_name)
+    odb.read_def(db_top, def_file_name)
+    block = db_top.getChip().getBlock()
+
+    micron_in_units = block.getDefUnits()
+
+    LENGTH = int(micron_in_units * length)
+
+    H_EXTENSION = int(micron_in_units * hor_extension)
+    V_EXTENSION = int(micron_in_units * ver_extension)
+
+    if H_EXTENSION < 0:
+        H_EXTENSION = 0
+
+    if V_EXTENSION < 0:
+        V_EXTENSION = 0
+
+    reverse_arr_raw = reverse.split(",")
+    reverse_arr = []
+    for element in reverse_arr_raw:
+        if element.strip() != "":
+            reverse_arr.append(f"#{element}")
+
+    def getGrid(origin, count, step):
+        tracks = []
+        pos = origin
+        for i in range(count):
+            tracks.append(pos)
+            pos += step
+        assert len(tracks) > 0
+        tracks.sort()
+
+        return tracks
+
+    def equallySpacedSeq(m, arr):
+        seq = []
+        n = len(arr)
+        # Bresenham
+        indices = [i * n // m + n // (2 * m) for i in range(m)]
+        for i in indices:
+            seq.append(arr[i])
+        return seq
+
+    # HUMAN SORTING: https://stackoverflow.com/questions/5967500/how-to-correctly-sort-a-string-with-a-number-inside
+    def natural_keys(enum):
+        def atof(text):
+            try:
+                retval = float(text)
+            except ValueError:
+                retval = text
+            return retval
+
+        text = enum[0]
+        text = re.sub(r"(\[|\]|\.|\$)", "", text)
+        """
+        alist.sort(key=natural_keys) sorts in human order
+        http://nedbatchelder.com/blog/200712/human_sorting.html
+        (see toothy's implementation in the comments)
+        float regex comes from https://stackoverflow.com/a/12643073/190597
+        """
+        return [
+            atof(c) for c in re.split(r"[+-]?([0-9]+(?:[.][0-9]*)?|[.][0-9]+)", text)
+        ]
+
+    def bus_keys(enum):
+        text = enum[0]
+        m = re.match(r"^.*\[(\d+)\]$", text)
+        if not m:
+            return -1
+        else:
+            return int(m.group(1))
+
+    #2. Find the Slot matching next nearest slot-DineshA
+    def findSlot(val, arr):
+        for i in arr:
+            if(i > val):
+                return i
+        print("ERROR: Next Valid Position not found :",val)
+        return -1
+
+    # read config
+
+    pin_placement_cfg = {"#N": [], "#E": [], "#S": [], "#W": []}
+    cur_side = None
+    if config_file_name is not None and config_file_name != "":
+        with open(config_file_name, "r") as config_file:
+            for line in config_file:
+                line = line.split()
+                if len(line) == 0:
+                    continue
+
+                #3. Dinesh A - Start
+                if(manual_place_flag == False):
+                    if len(line) > 1:
+                        print("Only one entry allowed per line.")
+                        sys.exit(1)
+                    token = line[0]
+                else:
+                    #During Manual Place we are allowing Four field
+                    # <Pad Name> <Offset> <Position> <Multiplier>
+                    # Causion: Make sure that you have given absolute name, else it will give issue
+                    if len(line) > 4:
+                        print("Only Four entry allowed per line.")
+                        sys.exit(1)
+                    if line[0] not in ["#N", "#E", "#S", "#W", "#NR", "#ER", "#SR", "#WR"]:
+                        token = line
+                    else:
+                        token = line[0]
+
+                if cur_side is not None and token[0] != "#":
+                    pin_placement_cfg[cur_side].append(token)
+                elif token not in [
+                    "#N",
+                    "#E",
+                    "#S",
+                    "#W",
+                    "#NR",
+                    "#ER",
+                    "#SR",
+                    "#WR",
+                    "#BUS_SORT",
+                    "#MANUAL_PLACE"
+                ]:
+                    print(
+                        "Valid directives are #N, #E, #S, or #W. Append R for reversing the default order.",
+                        "Use #BUS_SORT to group 'bus bits' by index.",
+                        "Please make sure you have set a valid side first before listing pins",
+                    )
+                    sys.exit(1)
+                elif token == "#BUS_SORT":
+                    bus_sort_flag = True
+                #4 - Dinesh A
+                elif token == "#MANUAL_PLACE":
+                    print("Input token ",token)
+                    manual_place_flag = True
+                else:
+                    if len(token) == 3:
+                        token = token[0:2]
+                        reverse_arr.append(token)
+                    cur_side = token
+
+    # build a list of pins
+
+    chip_top = db_top.getChip()
+    block_top = chip_top.getBlock()
+    top_design_name = block_top.getName()
+    tech = db_top.getTech()
+
+    H_LAYER = tech.findLayer(h_layer_name)
+    V_LAYER = tech.findLayer(v_layer_name)
+
+    H_WIDTH = int(h_width_mult * H_LAYER.getWidth())
+    V_WIDTH = int(v_width_mult * V_LAYER.getWidth())
+
+    print("Top-level design name:", top_design_name)
+
+    bterms = block_top.getBTerms()
+    bterms_enum = []
+    for bterm in bterms:
+        pin_name = bterm.getName()
+        bterms_enum.append((pin_name, bterm))
+
+    # sort them "humanly"
+    bterms_enum.sort(key=natural_keys)
+    if bus_sort_flag:
+        bterms_enum.sort(key=bus_keys)
+    bterms = [bterm[1] for bterm in bterms_enum]
+
+    pin_placement = {"#N": [], "#E": [], "#S": [], "#W": []}
+    bterm_regex_map = {}
+    #5. Dinesh A
+    if(manual_place_flag == False):
+	    for side in pin_placement_cfg:
+                for regex in pin_placement_cfg[side]:  # going through them in order
+                    regex += "$"  # anchor
+                    for bterm in bterms:
+                        # if a pin name matches multiple regexes, their order will be
+                        # arbitrary. More refinement requires more strict regexes (or just
+                        # the exact pin name).
+                        pin_name = bterm.getName()
+                        if re.match(regex, pin_name) is not None:
+                            if bterm in bterm_regex_map:
+                                print(
+		                    "Error: Multiple regexes matched",
+		                    pin_name,
+		                    ". Those are",
+		                    bterm_regex_map[bterm],
+		                    "and",
+		                    regex,
+		                )
+                                sys.exit(os.EX_DATAERR)
+                            bterm_regex_map[bterm] = regex
+                            pin_placement[side].append(bterm)  # to maintain the order
+
+	    unmatched_bterms = [bterm for bterm in bterms if bterm not in bterm_regex_map]
+
+	    if len(unmatched_bterms) > 0:
+                print("Warning: Some pins weren't matched by the config file")
+                print("Those are:", [bterm.getName() for bterm in unmatched_bterms])
+                if True:
+                    print("Assigning random sides to the above pins")
+                    for bterm in unmatched_bterms:
+                        random_side = random.choice(list(pin_placement.keys()))
+                        pin_placement[random_side].append(bterm)
+                else:
+                    sys.exit(1)
+
+    #6 Dinesh A
+    else:
+	    for side in pin_placement_cfg:
+                for regex in pin_placement_cfg[side]:  # going through them in order
+                    regex = regex[0]  # take first value
+                    regex += "$"  # anchor
+                    for bterm in bterms:
+		        # if a pin name matches multiple regexes, their order will be
+		        # arbitrary. More refinement requires more strict regexes (or just
+		        # the exact pin name).
+                        pin_name = bterm.getName()
+                        if re.match(regex, pin_name) is not None:
+                            print("Debug: Serching Pin match",regex)
+                            if bterm in bterm_regex_map:
+                                #print("Warning: Multiple regexes matched", pin_name)
+                                #      ". Those are", bterm_regex_map[bterm], "and", regex)
+                                sys.exit(1)
+                            bterm_regex_map[bterm] = regex
+                            pin_placement[side].append(bterm)  # to maintain the order
+	    
+	    unmatched_bterms = [bterm for bterm in bterms if bterm not in bterm_regex_map]
+	    
+	    if len(unmatched_bterms) > 0:
+                print("Warning: Some pins weren't matched by the config file")
+                print("Those are:", [bterm.getName() for bterm in unmatched_bterms])
+                sys.exit(1)
+
+
+    assert len(block_top.getBTerms()) == len(
+        pin_placement["#N"]
+        + pin_placement["#E"]
+        + pin_placement["#S"]
+        + pin_placement["#W"]
+    )
+
+    # generate slots
+
+    DIE_AREA = block_top.getDieArea()
+    BLOCK_LL_X = DIE_AREA.xMin()
+    BLOCK_LL_Y = DIE_AREA.yMin()
+    BLOCK_UR_X = DIE_AREA.xMax()
+    BLOCK_UR_Y = DIE_AREA.yMax()
+
+    print("Block boundaries:", BLOCK_LL_X, BLOCK_LL_Y, BLOCK_UR_X, BLOCK_UR_Y)
+
+    origin, count, step = block_top.findTrackGrid(H_LAYER).getGridPatternY(0)
+
+    #7. Save the horizontal origin and step - DineshA
+    h_origin = origin
+    h_step   = step
+
+    h_tracks = getGrid(origin, count, step)
+
+    origin, count, step = block_top.findTrackGrid(V_LAYER).getGridPatternX(0)
+
+    #8. Save the horizontal origin and step - DineshA
+    v_origin = origin
+    v_step   = step
+
+    v_tracks = getGrid(origin, count, step)
+
+    for rev in reverse_arr:
+        pin_placement[rev].reverse()
+
+    # create the pins
+    #9.  DineshA
+    if(manual_place_flag == False):
+	    for side in pin_placement:
+                if side in ["#N", "#S"]:
+                    slots = equallySpacedSeq(len(pin_placement[side]), v_tracks)
+                else:
+                    slots = equallySpacedSeq(len(pin_placement[side]), h_tracks)
+
+                assert len(slots) == len(pin_placement[side])
+
+                for i in range(len(pin_placement[side])):
+                    bterm = pin_placement[side][i]
+                    slot = slots[i]
+
+                    pin_name = bterm.getName()
+                    pins = bterm.getBPins()
+                    if len(pins) > 0:
+                        print("Warning:", pin_name, "already has shapes. Modifying them")
+                        assert len(pins) == 1
+                        pin_bpin = pins[0]
+                    else:
+                        pin_bpin = odb.dbBPin_create(bterm)
+
+                    pin_bpin.setPlacementStatus("PLACED")
+
+                    if side in ["#N", "#S"]:
+                        rect = odb.Rect(0, 0, V_WIDTH, LENGTH + V_EXTENSION)
+                        if side == "#N":
+                            y = BLOCK_UR_Y - LENGTH
+                        else:
+                            y = BLOCK_LL_Y - V_EXTENSION
+                        rect.moveTo(slot - V_WIDTH // 2, y)
+                        odb.dbBox_create(pin_bpin, V_LAYER, *rect.ll(), *rect.ur())
+                    else:
+                        rect = odb.Rect(0, 0, LENGTH + H_EXTENSION, H_WIDTH)
+                        if side == "#E":
+                            x = BLOCK_UR_X - LENGTH
+                        else:
+                            x = BLOCK_LL_X - H_EXTENSION
+                        rect.moveTo(x, slot - H_WIDTH // 2)
+                        odb.dbBox_create(pin_bpin, H_LAYER, *rect.ll(), *rect.ur())
+
+    else:
+	    #10.New Logic, Manual Pin Placement - Dinesh A
+	    #print("Allowed VTracks",v_tracks)
+	    #print("Allowed hTracks",h_tracks)
+
+	    for side in pin_placement:
+
+                if(len(pin_placement[side]) != len(pin_placement_cfg[side])):
+                    print("ERROR : At Side:", side, " Total Pin Defined ",len(pin_placement_cfg[side]), "More than available:",len(pin_placement[side]))
+		    
+		#check defined pad are more than avaibale one
+                assert len(pin_placement[side]) == len(pin_placement_cfg[side])
+                start = 0
+	    
+                start_loc = 0
+                pad_pos   = 0
+                slot_pre = 0
+                #Dinesh: Give Step Multipler size *2  for better pad placement
+                multiplier= 2
+                for i in range(len(pin_placement_cfg[side])):
+                    #Dinesh: Multiply the offset by 1000 for micro conversion
+                    if(len(pin_placement_cfg[side][i]) > 1):
+                        start_loc = int(pin_placement_cfg[side][i][1])
+                    if(len(pin_placement_cfg[side][i]) > 2):
+                        pad_pos   = int(pin_placement_cfg[side][i][2])
+                    if(len(pin_placement_cfg[side][i]) > 3):
+                        multiplier = int(pin_placement_cfg[side][i][3])
+
+                    if side in ["#N", "#S"]:
+                        slott = start_loc*1000+int(v_origin)+(int(v_step) * pad_pos * multiplier)
+                        slot =findSlot(slott,v_tracks)
+                    else:
+                        slott = start_loc*1000+int(h_origin)+(int(h_step) * pad_pos * multiplier)
+                        slot =findSlot(slott,h_tracks)
+		  
+                    pad_pos +=1
+                    bterm = pin_placement[side][i]
+	    
+                    pin_name = bterm.getName()
+                    pins = bterm.getBPins()
+                    if len(pins) > 0:
+                        print("Warning:", pin_name, "already has shapes. Modifying them")
+                        assert len(pins) == 1
+                        pin_bpin = pins[0]
+                    else:
+                        pin_bpin = odb.dbBPin_create(bterm)
+
+                    if(slot < slot_pre):
+                        print("ERROR:", "Current Pad:", pin_name, " Slot:" , slot, " is less than Previous One:",slot_pre)
+                        sys.exit(1)
+
+                    slot_pre = slot
+
+                    print("Dinesh: Placing Pad:" ,pin_name, " At Side: ", side, " Slot: ", slot)
+                    pin_bpin.setPlacementStatus("PLACED")
+	    
+                    if side in ["#N", "#S"]:
+                        rect = odb.Rect(0, 0, V_WIDTH, LENGTH+V_EXTENSION)
+                        if side == "#N":
+                            y = BLOCK_UR_Y-LENGTH
+                        else:
+                            y = BLOCK_LL_Y-V_EXTENSION
+                        rect.moveTo(slot-V_WIDTH//2, y)
+                        odb.dbBox_create(pin_bpin, V_LAYER, *rect.ll(), *rect.ur())
+                    else:
+                        rect = odb.Rect(0, 0, LENGTH+H_EXTENSION, H_WIDTH)
+                        if side == "#E":
+                            x = BLOCK_UR_X-LENGTH
+                        else:
+                            x = BLOCK_LL_X-H_EXTENSION
+                        rect.moveTo(x, slot-H_WIDTH//2)
+                        odb.dbBox_create(pin_bpin, H_LAYER, *rect.ll(), *rect.ur())
+
+
+    print(
+        f"Writing {output_def_file_name}...",
+    )
+    odb.write_def(block_top, output_def_file_name)
+
+
+if __name__ == "__main__":
+    cli()
diff --git a/openlane/mbist/base.sdc b/openlane/mbist/base.sdc
new file mode 100644
index 0000000..26a1fe6
--- /dev/null
+++ b/openlane/mbist/base.sdc
@@ -0,0 +1,128 @@
+###############################################################################
+# Created by write_sdc
+# Sun Nov 14 09:33:23 2021
+###############################################################################
+current_design mbist_top
+###############################################################################
+# Timing Constraints
+###############################################################################
+create_clock -name wb_clk_i -period 10.0000 [get_ports {wb_clk_i}]
+create_clock -name wb_clk2_i -period 10.0000 [get_ports {wb_clk2_i}]
+create_generated_clock -name bist_mem_clk_a -add -source [get_ports {wb_clk2_i}] -master_clock [get_clocks wb_clk2_i] -divide_by 1 -comment {Mem Clock A} [get_ports mem_clk_a]
+create_generated_clock -name bist_mem_clk_b -add -source [get_ports {wb_clk2_i}] -master_clock [get_clocks wb_clk2_i] -divide_by 1 -comment {Mem Clock B} [get_ports mem_clk_b]
+
+set_clock_groups -name async_clock -asynchronous -comment "Async Clock group" -group [get_clocks {bist_mem_clk_a bist_mem_clk_b}]  -group [get_clocks {wb_clk_i }] -group [get_clocks {wb_clk2_i}]
+
+set_clock_transition 0.1500 [all_clocks]
+set_clock_uncertainty -setup 0.2500 [all_clocks]
+set_clock_uncertainty -hold 0.2500 [all_clocks]
+
+set ::env(SYNTH_TIMING_DERATE) 0.05
+puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %"
+set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
+set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}]
+
+set_input_delay  -max 5.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {rst_n}]
+set_input_delay  -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {rst_n}]
+
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_correct}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_done}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[0]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[1]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[2]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[3]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_sdo}]
+
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_correct}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_done}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[0]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[1]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[2]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[3]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_sdo}]
+
+set_false_path -from [get_ports {bist_en}]
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_load}]
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_run}]
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_sdi}]
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_shift}]
+
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_en}]
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_load}]
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_run}]
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_sdi}]
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_shift}]
+
+## Functional Inputs
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_adr_i[*]}]  
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_stb_i}]      
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_cyc_i}]      
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_we_i}]      
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wbd_mbist1_dat_o[*]}] 
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_sel_i[*]}]
+
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_adr_i[*]}]  
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_stb_i}]      
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_cyc_i}]      
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_we_i}]      
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wbd_mbist1_dat_o[*]}] 
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_sel_i[*]}]
+
+set_output_delay -max 5 -clock [get_clocks {wb_clk_i}] -add_delay     [get_ports {wb_dat_o[*]}]  
+set_output_delay -max 5 -clock [get_clocks {wb_clk_i}] -add_delay     [get_ports {wb_ack_o}]  
+set_output_delay -max 5 -clock [get_clocks {wb_clk_i}] -add_delay     [get_ports {wb_err_o}]  
+
+set_output_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay     [get_ports {wb_dat_o[*]}]  
+set_output_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay     [get_ports {wb_ack_o}]  
+set_output_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay     [get_ports {wb_err_o}]  
+
+## Towards MEMORY from MBIST CLOCK
+## PORT-A
+set_input_delay -max 4.0000 -clock [get_clocks {bist_mem_clk_a}] -add_delay [get_ports {mem_dout_a[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {bist_mem_clk_a}] -add_delay [get_ports {mem_dout_a[*]}]
+
+
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_a}] -add_delay [get_ports {mem_addr_a[*]}]
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_a}] -add_delay [get_ports {mem_cen_a}]
+
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_a}] -add_delay [get_ports {mem_addr_a[*]}]
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_a}] -add_delay [get_ports {mem_cen_a}]
+
+
+
+## PORT-B
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_cen_b}]
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_din_b[*]}]
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_mask_b[*]}]
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_web_b}]
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_addr_b[*]}]
+
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_cen_b}]
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_din_b[*]}]
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_mask_b[*]}]
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_web_b}]
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_addr_b[*]}]
+
+
+# Set max delay for clock skew
+
+set_max_delay   3.5 -from [get_ports {wbd_clk_int}]
+set_max_delay   2 -to   [get_ports {wbd_clk_mbist}]
+set_max_delay 3.5 -from wbd_clk_int -to wbd_clk_mbist
+
+###############################################################################
+# Environment
+###############################################################################
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin $::env(SYNTH_DRIVING_CELL_PIN) [all_inputs]
+set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0]
+puts "\[INFO\]: Setting load to: $cap_load"
+set_load  $cap_load [all_outputs]
+
+set_timing_derate -early 0.9500
+set_timing_derate -late 1.0500
+###############################################################################
+# Design Rules
+###############################################################################
+set_max_fanout 4.0000 [current_design]
diff --git a/openlane/mbist/config.tcl b/openlane/mbist/config.tcl
new file mode 100755
index 0000000..78cd955
--- /dev/null
+++ b/openlane/mbist/config.tcl
@@ -0,0 +1,123 @@
+# 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>
+
+# Global
+# ------
+
+set script_dir [file dirname [file normalize [info script]]]
+# Name
+
+set ::env(DESIGN_NAME) mbist_top
+
+set ::env(DESIGN_IS_CORE) "0"
+
+# Timing configuration
+set ::env(CLOCK_PERIOD) "10"
+#set ::env(CLOCK_PORT) "u_cts_wb_clk_b1.u_buf/X  \
+#	               u_cts_wb_clk_b2.u_buf/X  \
+#		       "
+set ::env(CLOCK_PORT) { wb_clk_i mem_no\[3\].u_mem_sel.u_mem_clk_sel.u_mux/X mem_no\[2\].u_mem_sel.u_mem_clk_sel.u_mux/X mem_no\[1\].u_mem_sel.u_mem_clk_sel.u_mux/X mem_no\[0\].u_mem_sel.u_mem_clk_sel.u_mux/X  }
+
+set ::env(SYNTH_MAX_FANOUT) 4
+
+## CTS BUFFER
+set ::env(CTS_CLK_BUFFER_LIST) "sky130_fd_sc_hd__clkbuf_4 sky130_fd_sc_hd__clkbuf_8"
+set ::env(CTS_SINK_CLUSTERING_SIZE) "16"
+set ::env(CLOCK_BUFFER_FANOUT) "8"
+
+
+# Sources
+# -------
+
+# Local sources + no2usb sources
+set ::env(VERILOG_FILES) "\
+     $script_dir/../../verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_addr_gen.sv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_fsm.sv     \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_op_sel.sv  \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_repair_addr.sv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_sti_sel.sv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_pat_sel.sv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_mux.sv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_data_cmp.sv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_mem_wrapper.sv \
+     $script_dir/../../verilog/rtl/mbist/src/top/mbist_top.sv  \
+     $script_dir/../../verilog/rtl/lib/ctech_cells.sv     \
+     $script_dir/../../verilog/rtl/lib/reset_sync.sv \
+     $script_dir/../../verilog/rtl/lib/ser_shift.sv \
+	     "
+
+set ::env(VERILOG_INCLUDE_DIRS) [glob $script_dir/../../verilog/rtl/mbist/include ]
+set ::env(SYNTH_DEFINES) [list SYNTHESIS ]
+
+
+set ::env(SYNTH_PARAMS) "BIST_ADDR_WD 9,\
+	                 BIST_DATA_WD 32,\
+		         BIST_ADDR_START 9'h000,\
+			 BIST_ADDR_END 9'h1FB,\
+			 BIST_REPAIR_ADDR_START 9'h1FC,\
+			 BIST_RAD_WD_I 9,\
+			 BIST_RAD_WD_O 9\
+			 "
+
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+set ::env(SDC_FILE) "$script_dir/base.sdc"
+set ::env(BASE_SDC_FILE) "$script_dir/base.sdc"
+
+set ::env(LEC_ENABLE) 0
+
+set ::env(VDD_PIN) [list {vccd1}]
+set ::env(GND_PIN) [list {vssd1}]
+
+
+# Floorplanning
+# -------------
+
+set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+
+set ::env(FP_SIZING) absolute
+set ::env(DIE_AREA) "0 0 1500 200"
+
+
+# If you're going to use multiple power domains, then keep this disabled.
+set ::env(RUN_CVC) 1
+
+#set ::env(PDN_CFG) $script_dir/pdn.tcl
+
+
+set ::env(PL_TIME_DRIVEN) 1
+set ::env(PL_TARGET_DENSITY) "0.30"
+
+
+
+set ::env(FP_IO_VEXTEND) 4
+set ::env(FP_IO_HEXTEND) 4
+
+set ::env(FP_PDN_VPITCH) 140
+set ::env(FP_PDN_HPITCH) 140
+set ::env(FP_PDN_VWIDTH) 5
+set ::env(FP_PDN_HWIDTH) 5
+
+set ::env(GLB_RT_MAXLAYER) 5
+set ::env(GLB_RT_MAX_DIODE_INS_ITERS) 10
+
+set ::env(DIODE_INSERTION_STRATEGY) 4
+
+
+set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
+set ::env(QUIT_ON_MAGIC_DRC) "1"
+set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/mbist/interactive.tcl b/openlane/mbist/interactive.tcl
new file mode 100644
index 0000000..f59586f
--- /dev/null
+++ b/openlane/mbist/interactive.tcl
@@ -0,0 +1,219 @@
+#!/usr/bin/tclsh
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+# Copyright 2020 Efabless Corporation
+# Copyright 2020 Sylvain Munaut
+#
+# 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
+
+package require openlane;
+
+
+proc run_placement_step {args} {
+    # set pdndef_dirname [file dirname $::env(pdn_tmp_file_tag).def]
+    # set pdndef [lindex [glob $pdndef_dirname/*pdn*] 0]
+    # set_def $pdndef
+    if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
+        set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
+    }
+
+    run_placement
+}
+
+proc run_cts_step {args} {
+    # set_def $::env(opendp_result_file_tag).def
+    if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
+        set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
+    }
+
+    run_cts
+    run_resizer_timing
+}
+
+proc run_routing_step {args} {
+    # set resizerdef_dirname [file dirname $::env(resizer_tmp_file_tag)_timing.def]
+    # set resizerdef [lindex [glob $resizerdef_dirname/*resizer*] 0]
+    # set_def $resizerdef
+    if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
+        set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
+    }
+    run_routing
+}
+
+proc run_diode_insertion_2_5_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
+        set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
+    }
+	if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+		run_antenna_check
+		heal_antenna_violators; # modifies the routed DEF
+	}
+
+}
+
+proc run_power_pins_insertion_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(POWER_PINS_INSERTION_CURRENT_DEF) ] } {
+        set ::env(POWER_PINS_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(POWER_PINS_INSERTION_CURRENT_DEF)
+    }
+    if { $::env(LVS_INSERT_POWER_PINS) } {
+		write_powered_verilog
+		set_netlist $::env(lvs_result_file_tag).powered.v
+    }
+
+}
+
+proc run_lvs_step {{ lvs_enabled 1 }} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
+        set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
+    }
+	if { $lvs_enabled } {
+		run_magic_spice_export
+		run_lvs; # requires run_magic_spice_export
+	}
+
+}
+
+proc run_drc_step {{ drc_enabled 1 }} {
+    if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
+        set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
+    }
+	if { $drc_enabled } {
+		run_magic_drc
+		run_klayout_drc
+	}
+}
+
+proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
+    if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
+        set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
+    }
+	if { $antenna_check_enabled } {
+		run_antenna_check
+	}
+}
+
+proc run_flow {args} {
+       set script_dir [file dirname [file normalize [info script]]]
+
+		set options {
+		{-design required}
+		{-save_path optional}
+		{-no_lvs optional}
+	    {-no_drc optional}
+	    {-no_antennacheck optional}
+	}
+	set flags {-save}
+	parse_key_args "run_flow" args arg_values $options flags_map $flags -no_consume
+
+	prep {*}$args
+
+        set LVS_ENABLED 1
+        set DRC_ENABLED 1
+        set ANTENNACHECK_ENABLED 1
+
+        set steps [dict create "synthesis" {run_synthesis "" } \
+                "floorplan" {run_floorplan ""} \
+                "placement" {run_placement_step ""} \
+                "cts" {run_cts_step ""} \
+                "routing" {run_routing_step ""}\
+                "diode_insertion" {run_diode_insertion_2_5_step ""} \
+                "power_pins_insertion" {run_power_pins_insertion_step ""} \
+                "gds_magic" {run_magic ""} \
+                "gds_drc_klayout" {run_klayout ""} \
+                "gds_xor_klayout" {run_klayout_gds_xor ""} \
+                "lvs" "run_lvs_step $LVS_ENABLED" \
+                "drc" "run_drc_step $DRC_ENABLED" \
+                "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED" \
+                "cvc" {run_lef_cvc}
+        ]
+
+       set_if_unset arg_values(-to) "cvc";
+
+       if {  [info exists ::env(CURRENT_STEP) ] } {
+           puts "\[INFO\]:Picking up where last execution left off"
+           puts [format "\[INFO\]:Current stage is %s " $::env(CURRENT_STEP)]
+       } else {
+           set ::env(CURRENT_STEP) "synthesis";
+       }
+       set_if_unset arg_values(-from) $::env(CURRENT_STEP);
+       set exe 0;
+       dict for {step_name step_exe} $steps {
+           if { [ string equal $arg_values(-from) $step_name ] } {
+               set exe 1;
+           }
+
+           if { $exe } {
+               # For when it fails
+               set ::env(CURRENT_STEP) $step_name
+               [lindex $step_exe 0] [lindex $step_exe 1] ;
+           }
+
+           if { [ string equal $arg_values(-to) $step_name ] } {
+               set exe 0:
+               break;
+           }
+
+       }
+
+       # for when it resumes
+       set steps_as_list [dict keys $steps]
+       set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
+       set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
+
+	if {  [info exists flags_map(-save) ] } {
+		if { ! [info exists arg_values(-save_path)] } {
+			set arg_values(-save_path) ""
+		}
+		save_views 	-lef_path $::env(magic_result_file_tag).lef \
+			-def_path $::env(CURRENT_DEF) \
+			-gds_path $::env(magic_result_file_tag).gds \
+			-mag_path $::env(magic_result_file_tag).mag \
+			-maglef_path $::env(magic_result_file_tag).lef.mag \
+			-spice_path $::env(magic_result_file_tag).spice \
+			-spef_path $::env(CURRENT_SPEF) \
+			-verilog_path $::env(CURRENT_NETLIST) \
+			-save_path $arg_values(-save_path) \
+			-tag $::env(RUN_TAG)
+	}
+
+
+	calc_total_runtime
+	save_state
+	generate_final_summary_report
+	
+	check_timing_violations
+
+	puts_success "Flow Completed Without Fatal Errors."
+
+}
+
+run_flow {*}$argv
diff --git a/openlane/mbist/pin_order.cfg b/openlane/mbist/pin_order.cfg
new file mode 100644
index 0000000..0416192
--- /dev/null
+++ b/openlane/mbist/pin_order.cfg
@@ -0,0 +1,527 @@
+#BUS_SORT
+
+#MANUAL_PLACE
+
+
+#S
+rst_n            0000 0        
+
+
+
+#E
+cfg_cska_mbist\[3\]  0000 0 4
+cfg_cska_mbist\[2\]
+cfg_cska_mbist\[1\]
+cfg_cska_mbist\[0\]
+wb_clk2_i         
+wb_clk_i         
+wbd_clk_mbist
+wbd_clk_int         
+
+wb_cyc_i            0025 0 2
+wb_stb_i
+wb_we_i
+wb_cs_i\[1\]
+wb_cs_i\[0\]
+wb_adr_i\[8\]
+wb_adr_i\[7\]
+wb_adr_i\[6\]
+wb_adr_i\[5\]
+wb_adr_i\[4\]
+wb_adr_i\[3\]
+wb_adr_i\[2\]
+wb_adr_i\[1\]
+wb_adr_i\[0\]
+wb_dat_i\[31\]
+wb_dat_i\[30\]
+wb_dat_i\[29\]
+wb_dat_i\[28\]
+wb_dat_i\[27\]
+wb_dat_i\[26\]
+wb_dat_i\[25\]
+wb_dat_i\[24\]
+wb_dat_i\[23\]
+wb_dat_i\[22\]
+wb_dat_i\[21\]
+wb_dat_i\[20\]
+wb_dat_i\[19\]
+wb_dat_i\[18\]
+wb_dat_i\[17\]
+wb_dat_i\[16\]
+wb_dat_i\[15\]
+wb_dat_i\[14\]
+wb_dat_i\[13\]
+wb_dat_i\[12\]
+wb_dat_i\[11\]
+wb_dat_i\[10\]
+wb_dat_i\[9\]
+wb_dat_i\[8\]
+wb_dat_i\[7\]
+wb_dat_i\[6\]
+wb_dat_i\[5\]
+wb_dat_i\[4\]
+wb_dat_i\[3\]
+wb_dat_i\[2\]
+wb_dat_i\[1\]
+wb_dat_i\[0\]
+wb_sel_i\[3\]
+wb_sel_i\[2\]
+wb_sel_i\[1\]
+wb_sel_i\[0\]
+wb_dat_o\[31\]
+wb_dat_o\[30\]
+wb_dat_o\[29\]
+wb_dat_o\[28\]
+wb_dat_o\[27\]
+wb_dat_o\[26\]
+wb_dat_o\[25\]
+wb_dat_o\[24\]
+wb_dat_o\[23\]
+wb_dat_o\[22\]
+wb_dat_o\[21\]
+wb_dat_o\[20\]
+wb_dat_o\[19\]
+wb_dat_o\[18\]
+wb_dat_o\[17\]
+wb_dat_o\[16\]
+wb_dat_o\[15\]
+wb_dat_o\[14\]
+wb_dat_o\[13\]
+wb_dat_o\[12\]
+wb_dat_o\[11\]
+wb_dat_o\[10\]
+wb_dat_o\[9\]
+wb_dat_o\[8\]
+wb_dat_o\[7\]
+wb_dat_o\[6\]
+wb_dat_o\[5\]
+wb_dat_o\[4\]
+wb_dat_o\[3\]
+wb_dat_o\[2\]
+wb_dat_o\[1\]
+wb_dat_o\[0\]
+wb_ack_o
+wb_err_o
+
+
+bist_error_cnt3\[3\] 0150 0 2
+bist_error_cnt3\[2\]
+bist_error_cnt3\[1\]
+bist_error_cnt3\[0\]
+bist_correct\[3\]
+bist_error\[3\]
+bist_error_cnt2\[3\]
+bist_error_cnt2\[2\]
+bist_error_cnt2\[1\]
+bist_error_cnt2\[0\]
+bist_correct\[2\]
+bist_error\[2\]
+bist_error_cnt1\[3\]
+bist_error_cnt1\[2\]
+bist_error_cnt1\[1\]
+bist_error_cnt1\[0\]
+bist_correct\[1\]
+bist_error\[1\]
+bist_error_cnt0\[3\]
+bist_error_cnt0\[2\]
+bist_error_cnt0\[1\]
+bist_error_cnt0\[0\]
+bist_correct\[0\]
+bist_error\[0\]
+bist_done
+bist_sdo
+bist_shift
+bist_sdi
+bist_load
+bist_run
+bist_en           
+
+#S
+mem_clk_a\[0\]       250 0 2
+mem_cen_a\[0\]
+mem_web_a\[0\]
+mem_addr_a0\[0\]
+mem_addr_a0\[1\]
+mem_addr_a0\[2\]
+mem_addr_a0\[3\]
+mem_addr_a0\[4\]
+mem_addr_a0\[5\]
+mem_addr_a0\[6\]
+mem_addr_a0\[7\]
+mem_addr_a0\[8\]
+mem_mask_a0\[0\]
+mem_mask_a0\[1\]
+mem_mask_a0\[2\]
+mem_mask_a0\[3\]
+mem_din_a0\[0\]
+mem_din_a0\[1\]
+mem_din_a0\[2\]
+mem_din_a0\[3\]
+mem_din_a0\[4\]
+mem_din_a0\[5\]
+mem_din_a0\[6\]
+mem_din_a0\[7\]
+mem_din_a0\[8\]
+mem_din_a0\[9\]
+mem_din_a0\[10\]
+mem_din_a0\[11\]
+mem_din_a0\[12\]
+mem_din_a0\[13\]
+mem_din_a0\[14\]
+mem_din_a0\[15\]
+mem_din_a0\[16\]
+mem_din_a0\[17\]
+mem_din_a0\[18\]
+mem_din_a0\[19\]
+mem_din_a0\[20\]
+mem_din_a0\[21\]
+mem_din_a0\[22\]
+mem_din_a0\[23\]
+mem_din_a0\[24\]
+mem_din_a0\[25\]
+mem_din_a0\[26\]
+mem_din_a0\[27\]
+mem_din_a0\[28\]
+mem_din_a0\[29\]
+mem_din_a0\[30\]
+mem_din_a0\[31\]
+
+
+mem_dout_a0\[0\]  350 0 2
+mem_dout_a0\[1\]
+mem_dout_a0\[2\]
+mem_dout_a0\[3\]
+mem_dout_a0\[4\]
+mem_dout_a0\[5\]
+mem_dout_a0\[6\]
+mem_dout_a0\[7\]
+mem_dout_a0\[8\]
+mem_dout_a0\[9\]
+mem_dout_a0\[10\]
+mem_dout_a0\[11\]
+mem_dout_a0\[12\]
+mem_dout_a0\[13\]
+mem_dout_a0\[14\]
+mem_dout_a0\[15\]
+mem_dout_a0\[16\]
+mem_dout_a0\[17\]
+mem_dout_a0\[18\]
+mem_dout_a0\[19\]
+mem_dout_a0\[20\]
+mem_dout_a0\[21\]
+mem_dout_a0\[22\]
+mem_dout_a0\[23\]
+mem_dout_a0\[24\]
+mem_dout_a0\[25\]
+mem_dout_a0\[26\]
+mem_dout_a0\[27\]
+mem_dout_a0\[28\]
+mem_dout_a0\[29\]
+mem_dout_a0\[30\]
+mem_dout_a0\[31\]
+
+
+mem_clk_b\[0\]    0450 0 2
+mem_cen_b\[0\]
+mem_addr_b0\[8\]
+mem_addr_b0\[7\]
+mem_addr_b0\[6\]
+mem_addr_b0\[5\]
+mem_addr_b0\[4\]
+mem_addr_b0\[3\]
+mem_addr_b0\[2\]
+mem_addr_b0\[1\]
+mem_addr_b0\[0\]
+
+
+mem_clk_a\[1\]       1000 0 2
+mem_cen_a\[1\]
+mem_web_a\[1\]
+mem_addr_a1\[0\]
+mem_addr_a1\[1\]
+mem_addr_a1\[2\]
+mem_addr_a1\[3\]
+mem_addr_a1\[4\]
+mem_addr_a1\[5\]
+mem_addr_a1\[6\]
+mem_addr_a1\[7\]
+mem_addr_a1\[8\]
+mem_mask_a1\[0\]
+mem_mask_a1\[1\]
+mem_mask_a1\[2\]
+mem_mask_a1\[3\]
+mem_din_a1\[0\]
+mem_din_a1\[1\]
+mem_din_a1\[2\]
+mem_din_a1\[3\]
+mem_din_a1\[4\]
+mem_din_a1\[5\]
+mem_din_a1\[6\]
+mem_din_a1\[7\]
+mem_din_a1\[8\]
+mem_din_a1\[9\]
+mem_din_a1\[10\]
+mem_din_a1\[11\]
+mem_din_a1\[12\]
+mem_din_a1\[13\]
+mem_din_a1\[14\]
+mem_din_a1\[15\]
+mem_din_a1\[16\]
+mem_din_a1\[17\]
+mem_din_a1\[18\]
+mem_din_a1\[19\]
+mem_din_a1\[20\]
+mem_din_a1\[21\]
+mem_din_a1\[22\]
+mem_din_a1\[23\]
+mem_din_a1\[24\]
+mem_din_a1\[25\]
+mem_din_a1\[26\]
+mem_din_a1\[27\]
+mem_din_a1\[28\]
+mem_din_a1\[29\]
+mem_din_a1\[30\]
+mem_din_a1\[31\]
+
+
+mem_dout_a1\[0\]  1100 0 2
+mem_dout_a1\[1\]
+mem_dout_a1\[2\]
+mem_dout_a1\[3\]
+mem_dout_a1\[4\]
+mem_dout_a1\[5\]
+mem_dout_a1\[6\]
+mem_dout_a1\[7\]
+mem_dout_a1\[8\]
+mem_dout_a1\[9\]
+mem_dout_a1\[10\]
+mem_dout_a1\[11\]
+mem_dout_a1\[12\]
+mem_dout_a1\[13\]
+mem_dout_a1\[14\]
+mem_dout_a1\[15\]
+mem_dout_a1\[16\]
+mem_dout_a1\[17\]
+mem_dout_a1\[18\]
+mem_dout_a1\[19\]
+mem_dout_a1\[20\]
+mem_dout_a1\[21\]
+mem_dout_a1\[22\]
+mem_dout_a1\[23\]
+mem_dout_a1\[24\]
+mem_dout_a1\[25\]
+mem_dout_a1\[26\]
+mem_dout_a1\[27\]
+mem_dout_a1\[28\]
+mem_dout_a1\[29\]
+mem_dout_a1\[30\]
+mem_dout_a1\[31\]
+
+
+mem_clk_b\[1\]    1200 0 2
+mem_cen_b\[1\]
+mem_addr_b1\[8\]
+mem_addr_b1\[7\]
+mem_addr_b1\[6\]
+mem_addr_b1\[5\]
+mem_addr_b1\[4\]
+mem_addr_b1\[3\]
+mem_addr_b1\[2\]
+mem_addr_b1\[1\]
+mem_addr_b1\[0\]
+
+
+#N
+mem_clk_a\[2\]       250 0 2
+mem_cen_a\[2\]
+mem_web_a\[2\]
+mem_addr_a2\[0\]
+mem_addr_a2\[1\]
+mem_addr_a2\[2\]
+mem_addr_a2\[3\]
+mem_addr_a2\[4\]
+mem_addr_a2\[5\]
+mem_addr_a2\[6\]
+mem_addr_a2\[7\]
+mem_addr_a2\[8\]
+mem_mask_a2\[0\]
+mem_mask_a2\[1\]
+mem_mask_a2\[2\]
+mem_mask_a2\[3\]
+mem_din_a2\[0\]
+mem_din_a2\[1\]
+mem_din_a2\[2\]
+mem_din_a2\[3\]
+mem_din_a2\[4\]
+mem_din_a2\[5\]
+mem_din_a2\[6\]
+mem_din_a2\[7\]
+mem_din_a2\[8\]
+mem_din_a2\[9\]
+mem_din_a2\[10\]
+mem_din_a2\[11\]
+mem_din_a2\[12\]
+mem_din_a2\[13\]
+mem_din_a2\[14\]
+mem_din_a2\[15\]
+mem_din_a2\[16\]
+mem_din_a2\[17\]
+mem_din_a2\[18\]
+mem_din_a2\[19\]
+mem_din_a2\[20\]
+mem_din_a2\[21\]
+mem_din_a2\[22\]
+mem_din_a2\[23\]
+mem_din_a2\[24\]
+mem_din_a2\[25\]
+mem_din_a2\[26\]
+mem_din_a2\[27\]
+mem_din_a2\[28\]
+mem_din_a2\[29\]
+mem_din_a2\[30\]
+mem_din_a2\[31\]
+
+
+mem_dout_a2\[0\]  0350 0 2
+mem_dout_a2\[1\]
+mem_dout_a2\[2\]
+mem_dout_a2\[3\]
+mem_dout_a2\[4\]
+mem_dout_a2\[5\]
+mem_dout_a2\[6\]
+mem_dout_a2\[7\]
+mem_dout_a2\[8\]
+mem_dout_a2\[9\]
+mem_dout_a2\[10\]
+mem_dout_a2\[11\]
+mem_dout_a2\[12\]
+mem_dout_a2\[13\]
+mem_dout_a2\[14\]
+mem_dout_a2\[15\]
+mem_dout_a2\[16\]
+mem_dout_a2\[17\]
+mem_dout_a2\[18\]
+mem_dout_a2\[19\]
+mem_dout_a2\[20\]
+mem_dout_a2\[21\]
+mem_dout_a2\[22\]
+mem_dout_a2\[23\]
+mem_dout_a2\[24\]
+mem_dout_a2\[25\]
+mem_dout_a2\[26\]
+mem_dout_a2\[27\]
+mem_dout_a2\[28\]
+mem_dout_a2\[29\]
+mem_dout_a2\[30\]
+mem_dout_a2\[31\]
+
+
+mem_clk_b\[2\]    0450 0 2
+mem_cen_b\[2\]
+mem_addr_b2\[8\]
+mem_addr_b2\[7\]
+mem_addr_b2\[6\]
+mem_addr_b2\[5\]
+mem_addr_b2\[4\]
+mem_addr_b2\[3\]
+mem_addr_b2\[2\]
+mem_addr_b2\[1\]
+mem_addr_b2\[0\]
+
+
+mem_clk_a\[3\]       1000 0 2
+mem_cen_a\[3\]
+mem_web_a\[3\]
+mem_addr_a3\[0\]
+mem_addr_a3\[1\]
+mem_addr_a3\[2\]
+mem_addr_a3\[3\]
+mem_addr_a3\[4\]
+mem_addr_a3\[5\]
+mem_addr_a3\[6\]
+mem_addr_a3\[7\]
+mem_addr_a3\[8\]
+mem_mask_a3\[0\]
+mem_mask_a3\[1\]
+mem_mask_a3\[2\]
+mem_mask_a3\[3\]
+mem_din_a3\[0\]
+mem_din_a3\[1\]
+mem_din_a3\[2\]
+mem_din_a3\[3\]
+mem_din_a3\[4\]
+mem_din_a3\[5\]
+mem_din_a3\[6\]
+mem_din_a3\[7\]
+mem_din_a3\[8\]
+mem_din_a3\[9\]
+mem_din_a3\[10\]
+mem_din_a3\[11\]
+mem_din_a3\[12\]
+mem_din_a3\[13\]
+mem_din_a3\[14\]
+mem_din_a3\[15\]
+mem_din_a3\[16\]
+mem_din_a3\[17\]
+mem_din_a3\[18\]
+mem_din_a3\[19\]
+mem_din_a3\[20\]
+mem_din_a3\[21\]
+mem_din_a3\[22\]
+mem_din_a3\[23\]
+mem_din_a3\[24\]
+mem_din_a3\[25\]
+mem_din_a3\[26\]
+mem_din_a3\[27\]
+mem_din_a3\[28\]
+mem_din_a3\[29\]
+mem_din_a3\[30\]
+mem_din_a3\[31\]
+
+
+mem_dout_a3\[0\]  1100 0 2
+mem_dout_a3\[1\]
+mem_dout_a3\[2\]
+mem_dout_a3\[3\]
+mem_dout_a3\[4\]
+mem_dout_a3\[5\]
+mem_dout_a3\[6\]
+mem_dout_a3\[7\]
+mem_dout_a3\[8\]
+mem_dout_a3\[9\]
+mem_dout_a3\[10\]
+mem_dout_a3\[11\]
+mem_dout_a3\[12\]
+mem_dout_a3\[13\]
+mem_dout_a3\[14\]
+mem_dout_a3\[15\]
+mem_dout_a3\[16\]
+mem_dout_a3\[17\]
+mem_dout_a3\[18\]
+mem_dout_a3\[19\]
+mem_dout_a3\[20\]
+mem_dout_a3\[21\]
+mem_dout_a3\[22\]
+mem_dout_a3\[23\]
+mem_dout_a3\[24\]
+mem_dout_a3\[25\]
+mem_dout_a3\[26\]
+mem_dout_a3\[27\]
+mem_dout_a3\[28\]
+mem_dout_a3\[29\]
+mem_dout_a3\[30\]
+mem_dout_a3\[31\]
+
+
+mem_clk_b\[3\]    1200 0 2
+mem_cen_b\[3\]
+mem_addr_b3\[8\]
+mem_addr_b3\[7\]
+mem_addr_b3\[6\]
+mem_addr_b3\[5\]
+mem_addr_b3\[4\]
+mem_addr_b3\[3\]
+mem_addr_b3\[2\]
+mem_addr_b3\[1\]
+mem_addr_b3\[0\]
+
diff --git a/openlane/mbist/sta.tcl b/openlane/mbist/sta.tcl
new file mode 100644
index 0000000..57a6c35
--- /dev/null
+++ b/openlane/mbist/sta.tcl
@@ -0,0 +1,88 @@
+# 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>
+
+
+set ::env(LIB_FASTEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ff_n40C_1v95.lib"
+set ::env(LIB_TYPICAL) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib"
+set ::env(LIB_SLOWEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ss_100C_1v60.lib"
+set ::env(DESIGN_NAME) "mbist_top"
+set ::env(BASE_SDC_FILE) "base.sdc"
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8"
+set ::env(SYNTH_DRIVING_CELL_PIN) "Y"
+set ::env(SYNTH_CAP_LOAD) "17.65"
+set ::env(WIRE_RC_LAYER) "met1"
+
+#To disable empty filler cell black box get created
+#set link_make_black_boxes 0
+
+
+set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um
+define_corners wc bc tt
+read_liberty -corner bc $::env(LIB_FASTEST)
+read_liberty -corner wc $::env(LIB_SLOWEST)
+read_liberty -corner tt $::env(LIB_TYPICAL)
+
+
+read_verilog ../user_project_wrapper/netlist/mbist.v
+link_design  $::env(DESIGN_NAME)
+
+
+read_spef ../../spef/mbist_top.spef  
+
+
+read_sdc -echo $::env(BASE_SDC_FILE)
+
+# check for missing constraints
+check_setup  -verbose > unconstraints.rpt
+
+set_operating_conditions -analysis_type single
+# Propgate the clock
+set_propagated_clock [all_clocks]
+
+report_tns
+report_wns
+#report_power 
+echo "################ CORNER : WC (SLOW) TIMING Report ###################" > timing_ss_max.rpt
+report_checks -unique -path_delay max -slack_max -0.0 -group_count 100 -corner wc >> timing_ss_max.rpt
+report_checks -group_count 100 -path_delay max  -path_group bist_clk  -corner wc  >> timing_ss_max.rpt
+report_checks -group_count 100 -path_delay max  -path_group mem_clk_a  -corner wc  >> timing_ss_max.rpt
+report_checks -group_count 100 -path_delay max  -path_group mem_clk_b -corner wc  >> timing_ss_max.rpt
+report_checks -path_delay max   -corner wc >> timing_ss_max.rpt
+
+echo "################ CORNER : BC (SLOW) TIMING Report ###################" > timing_ff_min.rpt
+report_checks -unique -path_delay min -slack_min -0.0 -group_count 100 -corner bc >> timing_ff_min.rpt
+report_checks -group_count 100  -path_delay min -path_group bist_clk  -corner bc  >> timing_ff_min.rpt
+report_checks -group_count 100  -path_delay min -path_group mem_clk_a  -corner bc  >> timing_ff_min.rpt
+report_checks -group_count 100  -path_delay min -path_group mem_clk_b -corner bc  >> timing_ff_min.rpt
+report_checks -path_delay min  -corner bc >> timing_ff_min.rpt
+
+echo "################ CORNER : TT (MAX) TIMING Report ###################" > timing_tt_max.rpt
+report_checks -unique -path_delay min -slack_min -0.0 -group_count 100 -corner tt >> timing_tt_max.rpt
+report_checks -group_count 100  -path_delay max -path_group bist_clk  -corner tt  >> timing_tt_max.rpt
+report_checks -group_count 100  -path_delay max -path_group mem_clk_a  -corner tt  >> timing_tt_max.rpt
+report_checks -group_count 100  -path_delay max -path_group mem_clk_b -corner tt  >> timing_tt_max.rpt
+report_checks -path_delay min  -corner tt >> timing_tt_min.rpt
+
+echo "################ CORNER : TT (MIN) TIMING Report ###################" > timing_tt_min.rpt
+report_checks -unique -path_delay min -slack_min -0.0 -group_count 100 -corner tt >> timing_tt_min.rpt
+report_checks -group_count 100  -path_delay min -path_group bist_clk  -corner tt  >> timing_tt_min.rpt
+report_checks -group_count 100  -path_delay min -path_group mem_clk_a -corner tt  >> timing_tt_min.rpt
+report_checks -group_count 100  -path_delay min -path_group mem_clk_b -corner tt  >> timing_tt_min.rpt
+report_checks -path_delay min  -corner tt >> timing_tt_min.rpt
+
+report_checks -path_delay min
+
+#exit
diff --git a/openlane/mbist1/base.sdc b/openlane/mbist1/base.sdc
new file mode 100644
index 0000000..8ae25b1
--- /dev/null
+++ b/openlane/mbist1/base.sdc
@@ -0,0 +1,163 @@
+###############################################################################
+# Created by write_sdc
+# Sun Nov 14 09:33:23 2021
+###############################################################################
+current_design mbist_top
+###############################################################################
+# Timing Constraints
+###############################################################################
+create_clock -name wb_clk_i -period 10.0000 [get_ports {wb_clk_i}]
+create_generated_clock -name bist_mem_clk_a -add -source [get_ports {wb_clk_i}] -master_clock [get_clocks wb_clk_i] -divide_by 1 -comment {Mem Clock A} [get_ports mem_clk_a]
+create_generated_clock -name bist_mem_clk_b -add -source [get_ports {wb_clk_i}] -master_clock [get_clocks wb_clk_i] -divide_by 1 -comment {Mem Clock B} [get_ports mem_clk_b]
+
+set_clock_groups -name async_clock -asynchronous -comment "Async Clock group" -group [get_clocks {wb_clk_i bist_mem_clk_a bist_mem_clk_b}]  
+
+set_clock_transition 0.1500 [get_clocks {wb_clk_i}]
+set_clock_uncertainty -setup 0.2500 wb_clk_i
+set_clock_uncertainty -setup 0.2500 mem_clk_a
+set_clock_uncertainty -setup 0.2500 mem_clk_b
+
+set_clock_uncertainty -hold 0.2500 wb_clk_i
+set_clock_uncertainty -hold 0.2500 mem_clk_a
+set_clock_uncertainty -hold 0.2500 mem_clk_b
+
+set ::env(SYNTH_TIMING_DERATE) 0.05
+puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %"
+set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
+set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}]
+
+set_input_delay  -max 5.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {rst_n}]
+set_input_delay  -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {rst_n}]
+
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_correct}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_done}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[0]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[1]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[2]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[3]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_sdo}]
+
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_correct}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_done}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[0]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[1]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[2]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_error_cnt[3]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_sdo}]
+
+set_false_path -from [get_ports {bist_en}]
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_load}]
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_run}]
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_sdi}]
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_shift}]
+
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_en}]
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_load}]
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_run}]
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_sdi}]
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay [get_ports {bist_shift}]
+
+## Functional Inputs
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_adr_i[*]}]  
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_stb_i}]      
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_cyc_i}]      
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_we_i}]      
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wbd_mbist1_dat_o[*]}] 
+set_input_delay -max 4 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_sel_i[*]}]
+
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_adr_i[*]}]  
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_stb_i}]      
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_cyc_i}]      
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_we_i}]      
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wbd_mbist1_dat_o[*]}] 
+set_input_delay -min 2 -clock [get_clocks {wb_clk_i}] -add_delay   [get_ports {wb_sel_i[*]}]
+
+set_output_delay -max 5 -clock [get_clocks {wb_clk_i}] -add_delay     [get_ports {wb_dat_o[*]}]  
+set_output_delay -max 5 -clock [get_clocks {wb_clk_i}] -add_delay     [get_ports {wb_ack_o}]  
+set_output_delay -max 5 -clock [get_clocks {wb_clk_i}] -add_delay     [get_ports {wb_err_o}]  
+
+set_output_delay -min 1 -clock [get_clocks {wb_clk_i}] -add_delay     [get_ports {wb_dat_o[*]}]  
+set_output_delay -min 1 -clock [get_clocks {wb_clk_i}] -add_delay     [get_ports {wb_ack_o}]  
+set_output_delay -min 1 -clock [get_clocks {wb_clk_i}] -add_delay     [get_ports {wb_err_o}]  
+
+## Towards MEMORY from MBIST CLOCK
+## PORT-A
+set_input_delay -max 4.0000 -clock [get_clocks {bist_mem_clk_a}] -add_delay [get_ports {mem_dout_a[*]}]
+set_input_delay -min 1.0000 -clock [get_clocks {bist_mem_clk_a}] -add_delay [get_ports {mem_dout_a[*]}]
+
+
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_a}] -add_delay [get_ports {mem_addr_a[*]}]
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_a}] -add_delay [get_ports {mem_cen_a}]
+
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_a}] -add_delay [get_ports {mem_addr_a[*]}]
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_a}] -add_delay [get_ports {mem_cen_a}]
+
+
+
+## PORT-B
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_cen_b}]
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_din_b[*]}]
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_mask_b[*]}]
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_web_b}]
+set_output_delay -max 4 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_addr_b[*]}]
+
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_cen_b}]
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_din_b[*]}]
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_mask_b[*]}]
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_web_b}]
+set_output_delay -min -0.5 -clock [get_clocks {bist_mem_clk_b}] -add_delay [get_ports {mem_addr_b[*]}]
+
+
+# Set max delay for clock skew
+
+set_max_delay   3.5 -from [get_ports {wbd_clk_int}]
+set_max_delay   2 -to   [get_ports {wbd_clk_mbist}]
+set_max_delay 3.5 -from wbd_clk_int -to wbd_clk_mbist
+
+###############################################################################
+# Environment
+###############################################################################
+set_load -pin_load 0.0334 [get_ports {bist_correct}]
+set_load -pin_load 0.0334 [get_ports {bist_done}]
+set_load -pin_load 0.0334 [get_ports {bist_error}]
+set_load -pin_load 0.0334 [get_ports {bist_sdo}]
+set_load -pin_load 0.0334 [get_ports {mem_cen_a}]
+set_load -pin_load 0.0334 [get_ports {mem_cen_b}]
+set_load -pin_load 0.0334 [get_ports {mem_clk_a}]
+set_load -pin_load 0.0334 [get_ports {mem_clk_b}]
+set_load -pin_load 0.0334 [get_ports {mem_web_b}]
+set_load -pin_load 0.0334 [get_ports {bist_error_cnt[3]}]
+set_load -pin_load 0.0334 [get_ports {bist_error_cnt[2]}]
+set_load -pin_load 0.0334 [get_ports {bist_error_cnt[1]}]
+set_load -pin_load 0.0334 [get_ports {bist_error_cnt[0]}]
+set_load -pin_load 0.0334 [get_ports {wb_cyc_i}]
+set_load -pin_load 0.0334 [get_ports {wb_stb_i}]
+set_load -pin_load 0.0334 [get_ports {wb_adr_i[*]}]
+set_load -pin_load 0.0334 [get_ports {wb_we_i}]
+set_load -pin_load 0.0334 [get_ports {wb_dat_i[*]}]
+set_load -pin_load 0.0334 [get_ports {wb_sel_i[*]}]
+set_load -pin_load 0.0334 [get_ports {mem_addr_a[*]}]
+set_load -pin_load 0.0334 [get_ports {mem_addr_b[*]}]
+set_load -pin_load 0.0334 [get_ports {mem_din_b[*]}]
+set_load -pin_load 0.0334 [get_ports {mem_mask_b[*]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wb_cyc_i}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {bist_en}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {bist_load}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {bist_run}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {bist_sdi}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {bist_shift}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wb_cyc_i}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wb_adr_i[*]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wb_we_i}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wb_dat_i[*]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wb_sel_i[*]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {rst_n}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {mem_dout_a[*]}]
+set_timing_derate -early 0.9500
+set_timing_derate -late 1.0500
+###############################################################################
+# Design Rules
+###############################################################################
+set_max_fanout 4.0000 [current_design]
diff --git a/openlane/mbist1/config.tcl b/openlane/mbist1/config.tcl
new file mode 100755
index 0000000..1876487
--- /dev/null
+++ b/openlane/mbist1/config.tcl
@@ -0,0 +1,113 @@
+# 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>
+
+# Global
+# ------
+
+set script_dir [file dirname [file normalize [info script]]]
+# Name
+
+set ::env(DESIGN_NAME) mbist_top1
+
+set ::env(DESIGN_IS_CORE) "0"
+
+# Timing configuration
+set ::env(CLOCK_PERIOD) "10"
+set ::env(CLOCK_PORT) "u_cts_wb_clk_b1.u_buf/X  u_cts_wb_clk_b2.u_buf/X u_mem_sel.u_cts_mem_clk_a.u_buf/X u_mem_sel.u_cts_mem_clk_b.u_buf/X"
+
+set ::env(SYNTH_MAX_FANOUT) 4
+
+# Sources
+# -------
+
+# Local sources + no2usb sources
+set ::env(VERILOG_FILES) "\
+     $script_dir/../../verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_addr_gen.sv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_fsm.sv     \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_op_sel.sv  \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_repair_addr.sv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_sti_sel.sv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_pat_sel.sv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_mux.sv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_data_cmp.sv \
+     $script_dir/../../verilog/rtl/mbist/src/core/mbist_mem_wrapper.sv \
+     $script_dir/../../verilog/rtl/mbist/src/top/mbist_top1.sv  \
+     $script_dir/../../verilog/rtl/lib/ctech_cells.sv     \
+     $script_dir/../../verilog/rtl/lib/reset_sync.sv \
+	     "
+
+set ::env(VERILOG_INCLUDE_DIRS) [glob $script_dir/../../verilog/rtl/mbist/include ]
+set ::env(SYNTH_DEFINES) [list SYNTHESIS ]
+
+
+set ::env(SYNTH_PARAMS) "BIST_ADDR_WD 9,\
+	                 BIST_DATA_WD 32,\
+		         BIST_ADDR_START 9'h000,\
+			 BIST_ADDR_END 9'h1FB,\
+			 BIST_REPAIR_ADDR_START 9'h1FC,\
+			 BIST_RAD_WD_I 9,\
+			 BIST_RAD_WD_O 9\
+			 "
+
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+set ::env(SDC_FILE) "$script_dir/base.sdc"
+set ::env(BASE_SDC_FILE) "$script_dir/base.sdc"
+
+set ::env(LEC_ENABLE) 0
+
+set ::env(VDD_PIN) [list {vccd1}]
+set ::env(GND_PIN) [list {vssd1}]
+
+
+# Floorplanning
+# -------------
+
+set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+
+set ::env(FP_SIZING) absolute
+set ::env(DIE_AREA) "0 0 200 275"
+
+
+# If you're going to use multiple power domains, then keep this disabled.
+set ::env(RUN_CVC) 1
+
+#set ::env(PDN_CFG) $script_dir/pdn.tcl
+
+
+set ::env(PL_TIME_DRIVEN) 1
+set ::env(PL_TARGET_DENSITY) "0.35"
+
+
+
+set ::env(FP_IO_VEXTEND) 4
+set ::env(FP_IO_HEXTEND) 4
+
+set ::env(FP_PDN_VPITCH) 100
+set ::env(FP_PDN_HPITCH) 100
+set ::env(FP_PDN_VWIDTH) 5
+set ::env(FP_PDN_HWIDTH) 5
+
+set ::env(GLB_RT_MAXLAYER) 5
+set ::env(GLB_RT_MAX_DIODE_INS_ITERS) 10
+
+set ::env(DIODE_INSERTION_STRATEGY) 4
+
+
+set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
+set ::env(QUIT_ON_MAGIC_DRC) "1"
+set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/mbist1/interactive.tcl b/openlane/mbist1/interactive.tcl
new file mode 100644
index 0000000..f59586f
--- /dev/null
+++ b/openlane/mbist1/interactive.tcl
@@ -0,0 +1,219 @@
+#!/usr/bin/tclsh
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+# Copyright 2020 Efabless Corporation
+# Copyright 2020 Sylvain Munaut
+#
+# 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
+
+package require openlane;
+
+
+proc run_placement_step {args} {
+    # set pdndef_dirname [file dirname $::env(pdn_tmp_file_tag).def]
+    # set pdndef [lindex [glob $pdndef_dirname/*pdn*] 0]
+    # set_def $pdndef
+    if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
+        set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
+    }
+
+    run_placement
+}
+
+proc run_cts_step {args} {
+    # set_def $::env(opendp_result_file_tag).def
+    if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
+        set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
+    }
+
+    run_cts
+    run_resizer_timing
+}
+
+proc run_routing_step {args} {
+    # set resizerdef_dirname [file dirname $::env(resizer_tmp_file_tag)_timing.def]
+    # set resizerdef [lindex [glob $resizerdef_dirname/*resizer*] 0]
+    # set_def $resizerdef
+    if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
+        set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
+    }
+    run_routing
+}
+
+proc run_diode_insertion_2_5_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
+        set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
+    }
+	if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+		run_antenna_check
+		heal_antenna_violators; # modifies the routed DEF
+	}
+
+}
+
+proc run_power_pins_insertion_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(POWER_PINS_INSERTION_CURRENT_DEF) ] } {
+        set ::env(POWER_PINS_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(POWER_PINS_INSERTION_CURRENT_DEF)
+    }
+    if { $::env(LVS_INSERT_POWER_PINS) } {
+		write_powered_verilog
+		set_netlist $::env(lvs_result_file_tag).powered.v
+    }
+
+}
+
+proc run_lvs_step {{ lvs_enabled 1 }} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
+        set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
+    }
+	if { $lvs_enabled } {
+		run_magic_spice_export
+		run_lvs; # requires run_magic_spice_export
+	}
+
+}
+
+proc run_drc_step {{ drc_enabled 1 }} {
+    if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
+        set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
+    }
+	if { $drc_enabled } {
+		run_magic_drc
+		run_klayout_drc
+	}
+}
+
+proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
+    if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
+        set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
+    }
+	if { $antenna_check_enabled } {
+		run_antenna_check
+	}
+}
+
+proc run_flow {args} {
+       set script_dir [file dirname [file normalize [info script]]]
+
+		set options {
+		{-design required}
+		{-save_path optional}
+		{-no_lvs optional}
+	    {-no_drc optional}
+	    {-no_antennacheck optional}
+	}
+	set flags {-save}
+	parse_key_args "run_flow" args arg_values $options flags_map $flags -no_consume
+
+	prep {*}$args
+
+        set LVS_ENABLED 1
+        set DRC_ENABLED 1
+        set ANTENNACHECK_ENABLED 1
+
+        set steps [dict create "synthesis" {run_synthesis "" } \
+                "floorplan" {run_floorplan ""} \
+                "placement" {run_placement_step ""} \
+                "cts" {run_cts_step ""} \
+                "routing" {run_routing_step ""}\
+                "diode_insertion" {run_diode_insertion_2_5_step ""} \
+                "power_pins_insertion" {run_power_pins_insertion_step ""} \
+                "gds_magic" {run_magic ""} \
+                "gds_drc_klayout" {run_klayout ""} \
+                "gds_xor_klayout" {run_klayout_gds_xor ""} \
+                "lvs" "run_lvs_step $LVS_ENABLED" \
+                "drc" "run_drc_step $DRC_ENABLED" \
+                "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED" \
+                "cvc" {run_lef_cvc}
+        ]
+
+       set_if_unset arg_values(-to) "cvc";
+
+       if {  [info exists ::env(CURRENT_STEP) ] } {
+           puts "\[INFO\]:Picking up where last execution left off"
+           puts [format "\[INFO\]:Current stage is %s " $::env(CURRENT_STEP)]
+       } else {
+           set ::env(CURRENT_STEP) "synthesis";
+       }
+       set_if_unset arg_values(-from) $::env(CURRENT_STEP);
+       set exe 0;
+       dict for {step_name step_exe} $steps {
+           if { [ string equal $arg_values(-from) $step_name ] } {
+               set exe 1;
+           }
+
+           if { $exe } {
+               # For when it fails
+               set ::env(CURRENT_STEP) $step_name
+               [lindex $step_exe 0] [lindex $step_exe 1] ;
+           }
+
+           if { [ string equal $arg_values(-to) $step_name ] } {
+               set exe 0:
+               break;
+           }
+
+       }
+
+       # for when it resumes
+       set steps_as_list [dict keys $steps]
+       set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
+       set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
+
+	if {  [info exists flags_map(-save) ] } {
+		if { ! [info exists arg_values(-save_path)] } {
+			set arg_values(-save_path) ""
+		}
+		save_views 	-lef_path $::env(magic_result_file_tag).lef \
+			-def_path $::env(CURRENT_DEF) \
+			-gds_path $::env(magic_result_file_tag).gds \
+			-mag_path $::env(magic_result_file_tag).mag \
+			-maglef_path $::env(magic_result_file_tag).lef.mag \
+			-spice_path $::env(magic_result_file_tag).spice \
+			-spef_path $::env(CURRENT_SPEF) \
+			-verilog_path $::env(CURRENT_NETLIST) \
+			-save_path $arg_values(-save_path) \
+			-tag $::env(RUN_TAG)
+	}
+
+
+	calc_total_runtime
+	save_state
+	generate_final_summary_report
+	
+	check_timing_violations
+
+	puts_success "Flow Completed Without Fatal Errors."
+
+}
+
+run_flow {*}$argv
diff --git a/openlane/mbist1/pin_order.cfg b/openlane/mbist1/pin_order.cfg
new file mode 100644
index 0000000..82dd636
--- /dev/null
+++ b/openlane/mbist1/pin_order.cfg
@@ -0,0 +1,213 @@
+#BUS_SORT
+
+#MANUAL_PLACE
+
+
+#S
+rst_n            0000 0        
+
+
+
+#E
+cfg_cska_mbist\[3\]  0000 0 4
+cfg_cska_mbist\[2\]
+cfg_cska_mbist\[1\]
+cfg_cska_mbist\[0\]
+wb_clk_i         
+wbd_clk_mbist
+wbd_clk_int         
+
+wb_cyc_i            0025 0 2
+wb_stb_i
+wb_we_i
+wb_adr_i\[8\]
+wb_adr_i\[7\]
+wb_adr_i\[6\]
+wb_adr_i\[5\]
+wb_adr_i\[4\]
+wb_adr_i\[3\]
+wb_adr_i\[2\]
+wb_adr_i\[1\]
+wb_adr_i\[0\]
+wb_dat_i\[31\]
+wb_dat_i\[30\]
+wb_dat_i\[29\]
+wb_dat_i\[28\]
+wb_dat_i\[27\]
+wb_dat_i\[26\]
+wb_dat_i\[25\]
+wb_dat_i\[24\]
+wb_dat_i\[23\]
+wb_dat_i\[22\]
+wb_dat_i\[21\]
+wb_dat_i\[20\]
+wb_dat_i\[19\]
+wb_dat_i\[18\]
+wb_dat_i\[17\]
+wb_dat_i\[16\]
+wb_dat_i\[15\]
+wb_dat_i\[14\]
+wb_dat_i\[13\]
+wb_dat_i\[12\]
+wb_dat_i\[11\]
+wb_dat_i\[10\]
+wb_dat_i\[9\]
+wb_dat_i\[8\]
+wb_dat_i\[7\]
+wb_dat_i\[6\]
+wb_dat_i\[5\]
+wb_dat_i\[4\]
+wb_dat_i\[3\]
+wb_dat_i\[2\]
+wb_dat_i\[1\]
+wb_dat_i\[0\]
+wb_sel_i\[3\]
+wb_sel_i\[2\]
+wb_sel_i\[1\]
+wb_sel_i\[0\]
+wb_dat_o\[31\]
+wb_dat_o\[30\]
+wb_dat_o\[29\]
+wb_dat_o\[28\]
+wb_dat_o\[27\]
+wb_dat_o\[26\]
+wb_dat_o\[25\]
+wb_dat_o\[24\]
+wb_dat_o\[23\]
+wb_dat_o\[22\]
+wb_dat_o\[21\]
+wb_dat_o\[20\]
+wb_dat_o\[19\]
+wb_dat_o\[18\]
+wb_dat_o\[17\]
+wb_dat_o\[16\]
+wb_dat_o\[15\]
+wb_dat_o\[14\]
+wb_dat_o\[13\]
+wb_dat_o\[12\]
+wb_dat_o\[11\]
+wb_dat_o\[10\]
+wb_dat_o\[9\]
+wb_dat_o\[8\]
+wb_dat_o\[7\]
+wb_dat_o\[6\]
+wb_dat_o\[5\]
+wb_dat_o\[4\]
+wb_dat_o\[3\]
+wb_dat_o\[2\]
+wb_dat_o\[1\]
+wb_dat_o\[0\]
+wb_ack_o
+wb_err_o
+
+
+bist_error_cnt\[3\] 0150 0 2
+bist_error_cnt\[2\]
+bist_error_cnt\[1\]
+bist_error_cnt\[0\]
+bist_correct
+bist_error
+bist_done
+bist_sdo
+bist_shift
+bist_sdi
+bist_load
+bist_run
+bist_en           
+
+#W
+mem_clk_b       0000 0 2
+mem_cen_b
+mem_web_b
+mem_mask_b\[0\]
+mem_mask_b\[1\]
+mem_mask_b\[2\]
+mem_mask_b\[3\]
+mem_addr_b\[0\]
+mem_addr_b\[1\]
+mem_addr_b\[2\]
+mem_addr_b\[3\]
+mem_addr_b\[4\]
+mem_addr_b\[5\]
+mem_addr_b\[6\]
+mem_addr_b\[7\]
+mem_addr_b\[8\]
+mem_din_b\[0\]
+mem_din_b\[1\]
+mem_din_b\[2\]
+mem_din_b\[3\]
+mem_din_b\[4\]
+mem_din_b\[5\]
+mem_din_b\[6\]
+mem_din_b\[7\]
+mem_din_b\[8\]
+mem_din_b\[9\]
+mem_din_b\[10\]
+mem_din_b\[11\]
+mem_din_b\[12\]
+mem_din_b\[13\]
+mem_din_b\[14\]
+mem_din_b\[15\]
+mem_din_b\[16\]
+mem_din_b\[17\]
+mem_din_b\[18\]
+mem_din_b\[19\]
+mem_din_b\[20\]
+mem_din_b\[21\]
+mem_din_b\[22\]
+mem_din_b\[23\]
+mem_din_b\[24\]
+mem_din_b\[25\]
+mem_din_b\[26\]
+mem_din_b\[27\]
+mem_din_b\[28\]
+mem_din_b\[29\]
+mem_din_b\[30\]
+mem_din_b\[31\]
+
+
+mem_dout_a\[0\]  0100 0 2
+mem_dout_a\[1\]
+mem_dout_a\[2\]
+mem_dout_a\[3\]
+mem_dout_a\[4\]
+mem_dout_a\[5\]
+mem_dout_a\[6\]
+mem_dout_a\[7\]
+mem_dout_a\[8\]
+mem_dout_a\[9\]
+mem_dout_a\[10\]
+mem_dout_a\[11\]
+mem_dout_a\[12\]
+mem_dout_a\[13\]
+mem_dout_a\[14\]
+mem_dout_a\[15\]
+mem_dout_a\[16\]
+mem_dout_a\[17\]
+mem_dout_a\[18\]
+mem_dout_a\[19\]
+mem_dout_a\[20\]
+mem_dout_a\[21\]
+mem_dout_a\[22\]
+mem_dout_a\[23\]
+mem_dout_a\[24\]
+mem_dout_a\[25\]
+mem_dout_a\[26\]
+mem_dout_a\[27\]
+mem_dout_a\[28\]
+mem_dout_a\[29\]
+mem_dout_a\[30\]
+mem_dout_a\[31\]
+
+
+mem_clk_a          0200 0 2
+mem_cen_a
+mem_addr_a\[8\]
+mem_addr_a\[7\]
+mem_addr_a\[6\]
+mem_addr_a\[5\]
+mem_addr_a\[4\]
+mem_addr_a\[3\]
+mem_addr_a\[2\]
+mem_addr_a\[1\]
+mem_addr_a\[0\]
diff --git a/openlane/mbist1/sta.tcl b/openlane/mbist1/sta.tcl
new file mode 100644
index 0000000..57a6c35
--- /dev/null
+++ b/openlane/mbist1/sta.tcl
@@ -0,0 +1,88 @@
+# 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>
+
+
+set ::env(LIB_FASTEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ff_n40C_1v95.lib"
+set ::env(LIB_TYPICAL) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib"
+set ::env(LIB_SLOWEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ss_100C_1v60.lib"
+set ::env(DESIGN_NAME) "mbist_top"
+set ::env(BASE_SDC_FILE) "base.sdc"
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8"
+set ::env(SYNTH_DRIVING_CELL_PIN) "Y"
+set ::env(SYNTH_CAP_LOAD) "17.65"
+set ::env(WIRE_RC_LAYER) "met1"
+
+#To disable empty filler cell black box get created
+#set link_make_black_boxes 0
+
+
+set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um
+define_corners wc bc tt
+read_liberty -corner bc $::env(LIB_FASTEST)
+read_liberty -corner wc $::env(LIB_SLOWEST)
+read_liberty -corner tt $::env(LIB_TYPICAL)
+
+
+read_verilog ../user_project_wrapper/netlist/mbist.v
+link_design  $::env(DESIGN_NAME)
+
+
+read_spef ../../spef/mbist_top.spef  
+
+
+read_sdc -echo $::env(BASE_SDC_FILE)
+
+# check for missing constraints
+check_setup  -verbose > unconstraints.rpt
+
+set_operating_conditions -analysis_type single
+# Propgate the clock
+set_propagated_clock [all_clocks]
+
+report_tns
+report_wns
+#report_power 
+echo "################ CORNER : WC (SLOW) TIMING Report ###################" > timing_ss_max.rpt
+report_checks -unique -path_delay max -slack_max -0.0 -group_count 100 -corner wc >> timing_ss_max.rpt
+report_checks -group_count 100 -path_delay max  -path_group bist_clk  -corner wc  >> timing_ss_max.rpt
+report_checks -group_count 100 -path_delay max  -path_group mem_clk_a  -corner wc  >> timing_ss_max.rpt
+report_checks -group_count 100 -path_delay max  -path_group mem_clk_b -corner wc  >> timing_ss_max.rpt
+report_checks -path_delay max   -corner wc >> timing_ss_max.rpt
+
+echo "################ CORNER : BC (SLOW) TIMING Report ###################" > timing_ff_min.rpt
+report_checks -unique -path_delay min -slack_min -0.0 -group_count 100 -corner bc >> timing_ff_min.rpt
+report_checks -group_count 100  -path_delay min -path_group bist_clk  -corner bc  >> timing_ff_min.rpt
+report_checks -group_count 100  -path_delay min -path_group mem_clk_a  -corner bc  >> timing_ff_min.rpt
+report_checks -group_count 100  -path_delay min -path_group mem_clk_b -corner bc  >> timing_ff_min.rpt
+report_checks -path_delay min  -corner bc >> timing_ff_min.rpt
+
+echo "################ CORNER : TT (MAX) TIMING Report ###################" > timing_tt_max.rpt
+report_checks -unique -path_delay min -slack_min -0.0 -group_count 100 -corner tt >> timing_tt_max.rpt
+report_checks -group_count 100  -path_delay max -path_group bist_clk  -corner tt  >> timing_tt_max.rpt
+report_checks -group_count 100  -path_delay max -path_group mem_clk_a  -corner tt  >> timing_tt_max.rpt
+report_checks -group_count 100  -path_delay max -path_group mem_clk_b -corner tt  >> timing_tt_max.rpt
+report_checks -path_delay min  -corner tt >> timing_tt_min.rpt
+
+echo "################ CORNER : TT (MIN) TIMING Report ###################" > timing_tt_min.rpt
+report_checks -unique -path_delay min -slack_min -0.0 -group_count 100 -corner tt >> timing_tt_min.rpt
+report_checks -group_count 100  -path_delay min -path_group bist_clk  -corner tt  >> timing_tt_min.rpt
+report_checks -group_count 100  -path_delay min -path_group mem_clk_a -corner tt  >> timing_tt_min.rpt
+report_checks -group_count 100  -path_delay min -path_group mem_clk_b -corner tt  >> timing_tt_min.rpt
+report_checks -path_delay min  -corner tt >> timing_tt_min.rpt
+
+report_checks -path_delay min
+
+#exit
diff --git a/openlane/pinmux/base.sdc b/openlane/pinmux/base.sdc
new file mode 100644
index 0000000..bea31b6
--- /dev/null
+++ b/openlane/pinmux/base.sdc
@@ -0,0 +1,61 @@
+###############################################################################
+# Created by write_sdc
+# Thu Nov 11 05:33:42 2021
+###############################################################################
+current_design pinmux
+###############################################################################
+# Timing Constraints
+###############################################################################
+create_clock -name mclk -period 10.0000 [get_ports {mclk}]
+set_propagated_clock [get_clocks {mclk}]
+
+set_clock_transition 0.1500 [all_clocks]
+set_clock_uncertainty -setup 0.2500 [all_clocks]
+set_clock_uncertainty -hold 0.2500 [all_clocks]
+
+set ::env(SYNTH_TIMING_DERATE) 0.05
+puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %"
+set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
+set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}]
+
+### ClkSkew Adjust
+set_case_analysis 0 [get_ports {cfg_cska_pinmux[0]}]
+set_case_analysis 0 [get_ports {cfg_cska_pinmux[1]}]
+set_case_analysis 0 [get_ports {cfg_cska_pinmux[2]}]
+set_case_analysis 0 [get_ports {cfg_cska_pinmux[3]}]
+
+
+set_max_delay   3.5 -from [get_ports {wbd_clk_int}]
+set_max_delay   2 -to   [get_ports {wbd_clk_pinmux}]
+set_max_delay 3.5 -from wbd_clk_int -to wbd_clk_pinmux
+
+set_input_delay 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {h_reset_n}]
+
+set_input_delay -max 4.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_addr[*]}]
+set_input_delay -max 4.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_be[*]}]
+set_input_delay -max 4.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_cs}]
+set_input_delay -max 4.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_wdata[*]}]
+set_input_delay -max 4.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_wr}]
+
+set_input_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_addr[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_be[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_cs}]
+set_input_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_wdata[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_wr}]
+
+
+set_output_delay -max 4.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_ack}]
+set_output_delay -max 4.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_rdata[*]}]
+
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_ack}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {reg_rdata[*]}]
+###############################################################################
+# Environment
+###############################################################################
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin $::env(SYNTH_DRIVING_CELL_PIN) [all_inputs]
+set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0]
+puts "\[INFO\]: Setting load to: $cap_load"
+set_load  $cap_load [all_outputs]
+###############################################################################
+# Design Rules
+###############################################################################
diff --git a/openlane/pinmux/config.tcl b/openlane/pinmux/config.tcl
new file mode 100755
index 0000000..ce6c000
--- /dev/null
+++ b/openlane/pinmux/config.tcl
@@ -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: Modified by Dinesh Annayya <dinesha@opencores.org>
+
+# Global
+# ------
+
+set script_dir [file dirname [file normalize [info script]]]
+# Name
+
+set ::env(DESIGN_NAME) pinmux
+
+set ::env(DESIGN_IS_CORE) "0"
+set ::env(FP_PDN_CORE_RING) "0"
+
+# Timing configuration
+set ::env(CLOCK_PERIOD) "10"
+set ::env(CLOCK_PORT) "mclk"
+
+set ::env(SYNTH_MAX_FANOUT) 4
+
+## CTS BUFFER
+set ::env(CTS_CLK_BUFFER_LIST) "sky130_fd_sc_hd__clkbuf_4 sky130_fd_sc_hd__clkbuf_8"
+set ::env(CTS_SINK_CLUSTERING_SIZE) "16"
+set ::env(CLOCK_BUFFER_FANOUT) "8"
+
+# Sources
+# -------
+
+# Local sources + no2usb sources
+set ::env(VERILOG_FILES) "\
+     $script_dir/../../verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv \
+     $script_dir/../../verilog/rtl/pinmux/src/pinmux.sv     \
+     $script_dir/../../verilog/rtl/pinmux/src/pinmux_reg.sv \
+     $script_dir/../../verilog/rtl/pinmux/src/gpio_intr.sv  \
+     $script_dir/../../verilog/rtl/pinmux/src/pwm.sv        \
+     $script_dir/../../verilog/rtl/lib/pulse_gen_type1.sv   \
+     $script_dir/../../verilog/rtl/lib/pulse_gen_type2.sv   \
+     $script_dir/../../verilog/rtl/lib/ser_inf_32b.sv       \
+     $script_dir/../../verilog/rtl/lib/registers.v"
+
+
+set ::env(SYNTH_DEFINES) [list SYNTHESIS ]
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+set ::env(SDC_FILE) "$script_dir/base.sdc"
+set ::env(BASE_SDC_FILE) "$script_dir/base.sdc"
+
+set ::env(LEC_ENABLE) 0
+
+set ::env(VDD_PIN) [list {vccd1}]
+set ::env(GND_PIN) [list {vssd1}]
+
+
+# Floorplanning
+# -------------
+
+set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+
+set ::env(FP_SIZING) absolute
+set ::env(DIE_AREA) "0 0 550 450"
+
+
+# If you're going to use multiple power domains, then keep this disabled.
+set ::env(RUN_CVC) 0
+
+#set ::env(PDN_CFG) $script_dir/pdn.tcl
+
+
+set ::env(PL_TIME_DRIVEN) 1
+set ::env(PL_TARGET_DENSITY) "0.30"
+set ::env(CELL_PAD) "4"
+
+
+# helps in anteena fix
+set ::env(USE_ARC_ANTENNA_CHECK) "0"
+
+set ::env(FP_IO_VEXTEND) 4
+set ::env(FP_IO_HEXTEND) 4
+
+set ::env(FP_PDN_VPITCH) 100
+set ::env(FP_PDN_HPITCH) 100
+set ::env(FP_PDN_VWIDTH) 5
+set ::env(FP_PDN_HWIDTH) 5
+
+set ::env(GLB_RT_MAXLAYER) 5
+set ::env(GLB_RT_MAX_DIODE_INS_ITERS) 10
+
+set ::env(DIODE_INSERTION_STRATEGY) 4
+
+
+set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
+set ::env(QUIT_ON_MAGIC_DRC) "0"
+set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/pinmux/interactive.tcl b/openlane/pinmux/interactive.tcl
new file mode 100644
index 0000000..b44b517
--- /dev/null
+++ b/openlane/pinmux/interactive.tcl
@@ -0,0 +1,219 @@
+#!/usr/bin/tclsh
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+# Copyright 2020 Efabless Corporation
+# Copyright 2020 Sylvain Munaut
+#
+# 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
+
+package require openlane;
+
+
+proc run_placement_step {args} {
+    # set pdndef_dirname [file dirname $::env(pdn_tmp_file_tag).def]
+    # set pdndef [lindex [glob $pdndef_dirname/*pdn*] 0]
+    # set_def $pdndef
+    if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
+        set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
+    }
+
+    run_placement
+}
+
+proc run_cts_step {args} {
+    # set_def $::env(opendp_result_file_tag).def
+    if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
+        set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
+    }
+
+    run_cts
+    run_resizer_timing
+}
+
+proc run_routing_step {args} {
+    # set resizerdef_dirname [file dirname $::env(resizer_tmp_file_tag)_timing.def]
+    # set resizerdef [lindex [glob $resizerdef_dirname/*resizer*] 0]
+    # set_def $resizerdef
+    if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
+        set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
+    }
+    run_routing
+}
+
+proc run_diode_insertion_2_5_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
+        set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
+    }
+	if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+		run_antenna_check
+		heal_antenna_violators; # modifies the routed DEF
+	}
+
+}
+
+proc run_power_pins_insertion_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(POWER_PINS_INSERTION_CURRENT_DEF) ] } {
+        set ::env(POWER_PINS_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(POWER_PINS_INSERTION_CURRENT_DEF)
+    }
+    if { $::env(LVS_INSERT_POWER_PINS) } {
+		write_powered_verilog
+		set_netlist $::env(lvs_result_file_tag).powered.v
+    }
+
+}
+
+proc run_lvs_step {{ lvs_enabled 1 }} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
+        set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
+    }
+	if { $lvs_enabled } {
+		run_magic_spice_export
+		run_lvs; # requires run_magic_spice_export
+	}
+
+}
+
+proc run_drc_step {{ drc_enabled 1 }} {
+    if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
+        set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
+    }
+	if { $drc_enabled } {
+		run_magic_drc
+		run_klayout_drc
+	}
+}
+
+proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
+    if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
+        set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
+    }
+	if { $antenna_check_enabled } {
+		run_antenna_check
+	}
+}
+
+proc run_flow {args} {
+       set script_dir [file dirname [file normalize [info script]]]
+
+		set options {
+		{-design required}
+		{-save_path optional}
+		{-no_lvs optional}
+	    {-no_drc optional}
+	    {-no_antennacheck optional}
+	}
+	set flags {-save}
+	parse_key_args "run_flow" args arg_values $options flags_map $flags -no_consume
+
+	prep {*}$args
+
+        set LVS_ENABLED 1
+        set DRC_ENABLED 0
+        set ANTENNACHECK_ENABLED 1
+
+        set steps [dict create "synthesis" {run_synthesis "" } \
+                "floorplan" {run_floorplan ""} \
+                "placement" {run_placement_step ""} \
+                "cts" {run_cts_step ""} \
+                "routing" {run_routing_step ""}\
+                "diode_insertion" {run_diode_insertion_2_5_step ""} \
+                "power_pins_insertion" {run_power_pins_insertion_step ""} \
+                "gds_magic" {run_magic ""} \
+                "gds_drc_klayout" {run_klayout ""} \
+                "gds_xor_klayout" {run_klayout_gds_xor ""} \
+                "lvs" "run_lvs_step $LVS_ENABLED" \
+                "drc" "run_drc_step $DRC_ENABLED" \
+                "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED" \
+                "cvc" {run_lef_cvc}
+        ]
+
+       set_if_unset arg_values(-to) "cvc";
+
+       if {  [info exists ::env(CURRENT_STEP) ] } {
+           puts "\[INFO\]:Picking up where last execution left off"
+           puts [format "\[INFO\]:Current stage is %s " $::env(CURRENT_STEP)]
+       } else {
+           set ::env(CURRENT_STEP) "synthesis";
+       }
+       set_if_unset arg_values(-from) $::env(CURRENT_STEP);
+       set exe 0;
+       dict for {step_name step_exe} $steps {
+           if { [ string equal $arg_values(-from) $step_name ] } {
+               set exe 1;
+           }
+
+           if { $exe } {
+               # For when it fails
+               set ::env(CURRENT_STEP) $step_name
+               [lindex $step_exe 0] [lindex $step_exe 1] ;
+           }
+
+           if { [ string equal $arg_values(-to) $step_name ] } {
+               set exe 0:
+               break;
+           }
+
+       }
+
+       # for when it resumes
+       set steps_as_list [dict keys $steps]
+       set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
+       set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
+
+	if {  [info exists flags_map(-save) ] } {
+		if { ! [info exists arg_values(-save_path)] } {
+			set arg_values(-save_path) ""
+		}
+		save_views 	-lef_path $::env(magic_result_file_tag).lef \
+			-def_path $::env(CURRENT_DEF) \
+			-gds_path $::env(magic_result_file_tag).gds \
+			-mag_path $::env(magic_result_file_tag).mag \
+			-maglef_path $::env(magic_result_file_tag).lef.mag \
+			-spice_path $::env(magic_result_file_tag).spice \
+			-spef_path $::env(CURRENT_SPEF) \
+			-verilog_path $::env(CURRENT_NETLIST) \
+			-save_path $arg_values(-save_path) \
+			-tag $::env(RUN_TAG)
+	}
+
+
+	calc_total_runtime
+	save_state
+	generate_final_summary_report
+	
+	check_timing_violations
+
+	puts_success "Flow Completed Without Fatal Errors."
+
+}
+
+run_flow {*}$argv
diff --git a/openlane/pinmux/pin_order.cfg b/openlane/pinmux/pin_order.cfg
new file mode 100644
index 0000000..ffdf50f
--- /dev/null
+++ b/openlane/pinmux/pin_order.cfg
@@ -0,0 +1,383 @@
+#BUS_SORT
+#MANUAL_PLACE
+
+#S
+h_reset_n             000 0 2
+user_irq\[0\]
+user_irq\[1\]
+user_irq\[2\]
+usb_dp_o 
+usb_dn_o 
+usb_oen 
+usb_dp_i 
+usb_dn_i 
+uart_txd 
+uart_rxd
+i2cm_clk_o 
+i2cm_clk_i 
+i2cm_clk_oen 
+i2cm_data_oen 
+i2cm_data_o 
+i2cm_data_i 
+spim_sck 
+spim_ss 
+spim_miso
+spim_mosi
+pulse1m_mclk
+i2cm_intr
+usb_intr
+uartm_rxd
+uartm_txd
+
+pinmux_debug\[0\] 0100 0  2
+pinmux_debug\[1\]
+pinmux_debug\[2\]
+pinmux_debug\[3\]
+pinmux_debug\[4\]
+pinmux_debug\[5\]
+pinmux_debug\[6\]
+pinmux_debug\[7\]
+pinmux_debug\[8\]
+pinmux_debug\[9\]
+pinmux_debug\[10\]
+pinmux_debug\[11\]
+pinmux_debug\[12\]
+pinmux_debug\[13\]
+pinmux_debug\[14\]
+pinmux_debug\[15\]
+pinmux_debug\[16\]
+pinmux_debug\[17\]
+pinmux_debug\[18\]
+pinmux_debug\[19\]
+pinmux_debug\[20\]
+pinmux_debug\[21\]
+pinmux_debug\[22\]
+pinmux_debug\[23\]
+pinmux_debug\[24\]
+pinmux_debug\[25\]
+pinmux_debug\[26\]
+pinmux_debug\[27\]
+pinmux_debug\[28\]
+pinmux_debug\[29\]
+pinmux_debug\[30\]
+pinmux_debug\[31\]
+
+#W
+bist_error_cnt3\[3\]    000 0 2
+bist_error_cnt3\[2\]
+bist_error_cnt3\[1\]
+bist_error_cnt3\[0\]
+bist_correct\[3\]
+bist_error\[3\]
+
+bist_error_cnt2\[3\]   
+bist_error_cnt2\[2\]
+bist_error_cnt2\[1\]
+bist_error_cnt2\[0\]
+bist_correct\[2\]
+bist_error\[2\]
+
+bist_error_cnt1\[3\]   
+bist_error_cnt1\[2\]
+bist_error_cnt1\[1\]
+bist_error_cnt1\[0\]
+bist_correct\[1\]
+bist_error\[1\]
+
+bist_error_cnt0\[3\]
+bist_error_cnt0\[2\]
+bist_error_cnt0\[1\]
+bist_error_cnt0\[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\]     
+irq_lines\[14\]     
+irq_lines\[13\]     
+irq_lines\[12\]     
+irq_lines\[11\]     
+irq_lines\[10\]     
+irq_lines\[9\]     
+irq_lines\[8\]     
+irq_lines\[7\]     
+irq_lines\[6\]     
+irq_lines\[5\]     
+irq_lines\[4\]     
+irq_lines\[3\]     
+irq_lines\[2\]     
+irq_lines\[1\]     
+irq_lines\[0\]     
+fuse_mhartid\[31\] 
+fuse_mhartid\[30\] 
+fuse_mhartid\[29\] 
+fuse_mhartid\[28\] 
+fuse_mhartid\[27\] 
+fuse_mhartid\[26\] 
+fuse_mhartid\[25\] 
+fuse_mhartid\[24\] 
+fuse_mhartid\[23\] 
+fuse_mhartid\[22\] 
+fuse_mhartid\[21\] 
+fuse_mhartid\[20\] 
+fuse_mhartid\[19\] 
+fuse_mhartid\[18\] 
+fuse_mhartid\[17\] 
+fuse_mhartid\[16\] 
+fuse_mhartid\[15\] 
+fuse_mhartid\[14\] 
+fuse_mhartid\[13\] 
+fuse_mhartid\[12\] 
+fuse_mhartid\[11\] 
+fuse_mhartid\[10\] 
+fuse_mhartid\[9\] 
+fuse_mhartid\[8\] 
+fuse_mhartid\[7\] 
+fuse_mhartid\[6\] 
+fuse_mhartid\[5\] 
+fuse_mhartid\[4\] 
+fuse_mhartid\[3\] 
+fuse_mhartid\[2\] 
+fuse_mhartid\[1\] 
+fuse_mhartid\[0\] 
+
+cfg_cska_pinmux\[3\]  
+cfg_cska_pinmux\[2\]
+cfg_cska_pinmux\[1\]
+cfg_cska_pinmux\[0\]
+wbd_clk_int             
+wbd_clk_pinmux
+mclk            
+
+
+
+reg_cs            200 0
+reg_wr           
+reg_addr\[7\]    
+reg_addr\[6\]    
+reg_addr\[5\]    
+reg_addr\[4\]    
+reg_addr\[3\]    
+reg_addr\[2\]    
+reg_addr\[1\]    
+reg_addr\[0\]    
+reg_be\[3\]    
+reg_be\[2\]    
+reg_be\[1\]    
+reg_be\[0\]    
+reg_wdata\[31\]   
+reg_wdata\[30\]   
+reg_wdata\[29\]   
+reg_wdata\[28\]   
+reg_wdata\[27\]   
+reg_wdata\[26\]   
+reg_wdata\[25\]   
+reg_wdata\[24\]   
+reg_wdata\[23\]   
+reg_wdata\[22\]   
+reg_wdata\[21\]   
+reg_wdata\[20\]   
+reg_wdata\[19\]   
+reg_wdata\[18\]   
+reg_wdata\[17\]   
+reg_wdata\[16\]   
+reg_wdata\[15\]   
+reg_wdata\[14\]   
+reg_wdata\[13\]   
+reg_wdata\[12\]  
+reg_wdata\[11\]  
+reg_wdata\[10\]  
+reg_wdata\[9\]   
+reg_wdata\[8\]   
+reg_wdata\[7\]   
+reg_wdata\[6\]   
+reg_wdata\[5\]   
+reg_wdata\[4\]   
+reg_wdata\[3\]   
+reg_wdata\[2\]   
+reg_wdata\[1\]   
+reg_wdata\[0\]   
+reg_rdata\[31\]  
+reg_rdata\[30\]  
+reg_rdata\[29\]  
+reg_rdata\[28\]  
+reg_rdata\[27\]  
+reg_rdata\[26\]  
+reg_rdata\[25\]  
+reg_rdata\[24\]  
+reg_rdata\[23\]  
+reg_rdata\[22\]  
+reg_rdata\[21\]  
+reg_rdata\[20\]  
+reg_rdata\[19\]  
+reg_rdata\[18\]  
+reg_rdata\[17\]  
+reg_rdata\[16\]  
+reg_rdata\[15\]  
+reg_rdata\[14\]  
+reg_rdata\[13\]  
+reg_rdata\[12\]  
+reg_rdata\[11\]  
+reg_rdata\[10\]  
+reg_rdata\[9\]  
+reg_rdata\[8\]  
+reg_rdata\[7\]  
+reg_rdata\[6\]  
+reg_rdata\[5\]  
+reg_rdata\[4\]  
+reg_rdata\[3\]  
+reg_rdata\[2\]  
+reg_rdata\[1\]  
+reg_rdata\[0\]  
+reg_ack       
+
+
+#N
+digital_io_oen\[37\]  000 0 2
+digital_io_out\[37\]
+digital_io_in\[37\]
+digital_io_oen\[36\]
+digital_io_out\[36\]
+digital_io_in\[36\]
+digital_io_oen\[35\]
+digital_io_out\[35\]
+digital_io_in\[35\]
+digital_io_oen\[34\]
+digital_io_out\[34\]
+digital_io_in\[34\]
+digital_io_oen\[33\]
+digital_io_out\[33\]
+digital_io_in\[33\]
+digital_io_oen\[32\]
+digital_io_out\[32\]
+digital_io_in\[32\]
+digital_io_oen\[31\]
+digital_io_out\[31\]
+digital_io_in\[31\]
+digital_io_oen\[30\]
+digital_io_out\[30\]
+digital_io_in\[30\]
+digital_io_oen\[29\]
+digital_io_out\[29\]
+digital_io_in\[29\]
+digital_io_oen\[28\]
+digital_io_out\[28\]
+
+
+
+digital_io_in\[28\]  0300 0 2
+digital_io_oen\[27\]
+digital_io_out\[27\]
+digital_io_in\[27\]
+digital_io_oen\[26\]
+digital_io_out\[26\]
+digital_io_in\[26\]
+digital_io_oen\[25\]
+digital_io_out\[25\]
+digital_io_in\[25\]
+digital_io_oen\[24\]
+digital_io_out\[24\]
+digital_io_in\[24\]
+
+sflash_oen\[0\]    350 0 2
+sflash_oen\[1\]
+sflash_oen\[2\]
+sflash_oen\[3\]
+sflash_ss\[0\]
+sflash_ss\[1\]
+sflash_ss\[2\]
+sflash_ss\[3\]
+sflash_sck   
+sflash_do\[0\]
+sflash_do\[1\]
+sflash_do\[2\]
+sflash_do\[3\]
+sflash_di\[0\]      
+sflash_di\[1\]      
+sflash_di\[2\]      
+sflash_di\[3\]      
+
+digital_io_in\[23\]     400  0
+digital_io_out\[23\]
+digital_io_oen\[23\]
+digital_io_in\[22\]     
+digital_io_out\[22\]
+digital_io_oen\[22\]
+digital_io_in\[21\]     
+digital_io_out\[21\]
+digital_io_oen\[21\]
+digital_io_in\[20\]     
+digital_io_out\[20\]
+digital_io_oen\[20\]
+digital_io_in\[19\]     
+digital_io_out\[19\]
+digital_io_oen\[19\]
+digital_io_in\[18\]     
+digital_io_out\[18\]
+digital_io_oen\[18\]
+digital_io_in\[17\]     
+digital_io_out\[17\]
+digital_io_oen\[17\]
+digital_io_in\[16\]     
+digital_io_out\[16\]
+digital_io_oen\[16\]
+digital_io_in\[15\]     
+digital_io_out\[15\]
+digital_io_oen\[15\]
+
+
+#E
+digital_io_in\[0\]   0000 0 4
+digital_io_out\[0\]
+digital_io_oen\[0\]
+digital_io_in\[1\]
+digital_io_out\[1\]
+digital_io_oen\[1\]
+digital_io_in\[2\]
+digital_io_out\[2\]
+digital_io_oen\[2\]
+digital_io_in\[3\]
+digital_io_out\[3\]
+digital_io_oen\[3\]
+digital_io_in\[4\]
+digital_io_out\[4\]
+digital_io_oen\[4\]
+digital_io_in\[5\]
+digital_io_out\[5\]
+digital_io_oen\[5\]
+digital_io_in\[6\]
+digital_io_out\[6\]
+digital_io_oen\[6\]
+digital_io_in\[7\]
+digital_io_out\[7\]
+digital_io_oen\[7\]
+digital_io_in\[8\]
+digital_io_out\[8\]
+digital_io_oen\[8\]
+digital_io_in\[9\]
+digital_io_out\[9\]
+digital_io_oen\[9\]
+digital_io_in\[10\]
+digital_io_out\[10\]
+digital_io_oen\[10\]
+digital_io_in\[11\]
+digital_io_out\[11\]
+digital_io_oen\[11\]
+digital_io_in\[12\]
+digital_io_out\[12\]
+digital_io_oen\[12\]
+digital_io_in\[13\]
+digital_io_out\[13\]
+digital_io_oen\[13\]
+digital_io_in\[14\]
+digital_io_out\[14\]
+digital_io_oen\[14\]
+
+
diff --git a/openlane/qspim/base.sdc b/openlane/qspim/base.sdc
new file mode 100644
index 0000000..4166d36
--- /dev/null
+++ b/openlane/qspim/base.sdc
@@ -0,0 +1,332 @@
+###############################################################################
+# Created by write_sdc
+# Wed Nov 10 17:01:46 2021
+###############################################################################
+current_design qspim_top
+###############################################################################
+# Timing Constraints
+###############################################################################
+create_clock -name mclk -period 10.0000 [get_ports {mclk}]
+set_propagated_clock [get_clocks {mclk}]
+create_generated_clock -name spiclk -add -source [get_ports {mclk}] -master_clock [get_clocks {mclk}] -divide_by 2 -comment {SPI Clock Out} [get_ports {spi_clk}]
+#Keep in transparent zero delay path
+set_case_analysis 0 [get_ports {cfg_cska_spi[3]}]
+set_case_analysis 0 [get_ports {cfg_cska_spi[2]}]
+set_case_analysis 0 [get_ports {cfg_cska_spi[1]}]
+set_case_analysis 0 [get_ports {cfg_cska_spi[0]}]
+
+#Keep the Clock Skew in center of the Mux
+set_case_analysis 0 [get_ports {cfg_cska_sp_co[3]}]
+set_case_analysis 1 [get_ports {cfg_cska_sp_co[2]}]
+set_case_analysis 0 [get_ports {cfg_cska_sp_co[1]}]
+set_case_analysis 0 [get_ports {cfg_cska_sp_co[0]}]
+
+set_propagated_clock [get_clocks {spiclk}]
+
+set_clock_transition 0.1500 [all_clocks]
+set_clock_uncertainty -setup 0.2500 [all_clocks]
+set_clock_uncertainty -hold 0.2500 [all_clocks]
+
+set ::env(SYNTH_TIMING_DERATE) 0.05
+puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %"
+set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
+set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}]
+
+### ClkSkew Adjust
+set_case_analysis 0 [get_ports {cfg_cska_spi[0]}]
+set_case_analysis 0 [get_ports {cfg_cska_spi[1]}]
+set_case_analysis 0 [get_ports {cfg_cska_spi[2]}]
+set_case_analysis 0 [get_ports {cfg_cska_spi[3]}]
+
+
+set_max_delay   3.5 -from [get_ports {wbd_clk_int}]
+set_max_delay   2 -to   [get_ports {wbd_clk_spi}]
+set_max_delay 3.5 -from wbd_clk_int -to wbd_clk_spi
+
+#Static Clock Skew control
+set_case_analysis 0 [get_ports {cfg_cska_sp_co[0]}]
+set_case_analysis 0 [get_ports {cfg_cska_sp_co[1]}]
+set_case_analysis 0 [get_ports {cfg_cska_sp_co[2]}]
+set_case_analysis 0 [get_ports {cfg_cska_sp_co[3]}]
+
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {rst_n}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {rst_n}]
+
+set_input_delay -max 5.0000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdi[0]}]
+set_input_delay -max 5.0000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdi[1]}]
+set_input_delay -max 5.0000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdi[2]}]
+set_input_delay -max 5.0000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdi[3]}]
+
+
+set_input_delay -min 0.0000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdi[0]}]
+set_input_delay -min 0.0000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdi[1]}]
+set_input_delay -min 0.0000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdi[2]}]
+set_input_delay -min 0.0000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdi[3]}]
+
+
+set_output_delay -max 4.0000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_csn0}]
+set_output_delay -max 4.0000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdo[0]}]
+set_output_delay -max 4.0000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdo[1]}]
+set_output_delay -max 4.0000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdo[2]}]
+set_output_delay -max 4.0000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdo[3]}]
+
+set_output_delay -min -0.5000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_csn0}]
+set_output_delay -min -0.5000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdo[0]}]
+set_output_delay -min -0.5000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdo[1]}]
+set_output_delay -min -0.5000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdo[2]}]
+set_output_delay -min -0.5000 -clock [get_clocks {spiclk}] -add_delay [get_ports {spi_sdo[3]}]
+
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[0]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[10]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[11]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[12]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[13]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[14]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[15]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[16]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[17]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[18]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[19]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[1]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[20]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[21]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[22]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[23]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[24]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[25]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[26]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[27]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[28]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[29]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[2]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[30]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[31]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[3]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[4]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[5]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[6]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[7]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[8]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[9]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[0]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[10]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[11]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[12]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[13]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[14]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[15]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[16]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[17]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[18]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[19]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[1]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[20]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[21]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[22]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[23]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[24]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[25]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[26]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[27]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[28]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[29]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[2]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[30]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[31]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[3]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[4]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[5]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[6]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[7]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[8]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[9]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_sel_i[0]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_sel_i[1]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_sel_i[2]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_sel_i[3]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_stb_i}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_we_i}]
+
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[0]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[10]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[11]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[12]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[13]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[14]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[15]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[16]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[17]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[18]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[19]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[1]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[20]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[21]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[22]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[23]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[24]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[25]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[26]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[27]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[28]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[29]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[2]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[30]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[31]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[3]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[4]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[5]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[6]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[7]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[8]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_adr_i[9]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[0]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[10]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[11]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[12]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[13]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[14]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[15]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[16]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[17]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[18]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[19]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[1]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[20]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[21]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[22]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[23]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[24]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[25]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[26]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[27]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[28]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[29]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[2]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[30]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[31]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[3]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[4]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[5]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[6]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[7]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[8]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_i[9]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_sel_i[0]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_sel_i[1]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_sel_i[2]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_sel_i[3]}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_stb_i}]
+set_input_delay -min 3.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_we_i}]
+
+set_max_delay  10.0000 -to [get_ports {spi_debug[0]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[10]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[11]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[12]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[13]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[14]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[15]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[16]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[17]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[18]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[19]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[1]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[20]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[21]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[22]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[23]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[24]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[25]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[26]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[27]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[28]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[29]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[2]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[30]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[31]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[3]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[4]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[5]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[6]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[7]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[8]}]
+set_max_delay  10.0000 -to [get_ports {spi_debug[9]}]
+
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_ack_o}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[0]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[10]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[11]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[12]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[13]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[14]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[15]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[16]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[17]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[18]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[19]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[1]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[20]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[21]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[22]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[23]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[24]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[25]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[26]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[27]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[28]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[29]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[2]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[30]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[31]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[3]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[4]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[5]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[6]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[7]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[8]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[9]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_err_o}]
+
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_ack_o}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[0]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[10]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[11]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[12]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[13]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[14]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[15]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[16]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[17]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[18]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[19]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[1]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[20]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[21]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[22]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[23]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[24]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[25]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[26]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[27]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[28]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[29]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[2]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[30]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[31]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[3]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[4]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[5]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[6]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[7]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[8]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_dat_o[9]}]
+set_output_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_err_o}]
+###############################################################################
+# Environment
+###############################################################################
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin $::env(SYNTH_DRIVING_CELL_PIN) [all_inputs]
+set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0]
+puts "\[INFO\]: Setting load to: $cap_load"
+set_load  $cap_load [all_outputs]
+###############################################################################
+# Design Rules
+###############################################################################
diff --git a/openlane/qspim/config.tcl b/openlane/qspim/config.tcl
new file mode 100755
index 0000000..dd9596a
--- /dev/null
+++ b/openlane/qspim/config.tcl
@@ -0,0 +1,104 @@
+# 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>
+
+# Global
+# ------
+
+set script_dir [file dirname [file normalize [info script]]]
+# Name
+
+set ::env(DESIGN_NAME) qspim_top
+
+set ::env(DESIGN_IS_CORE) "0"
+set ::env(FP_PDN_CORE_RING) "0"
+
+# Timing configuration
+set ::env(CLOCK_PERIOD) "10"
+set ::env(CLOCK_PORT) "mclk"
+
+set ::env(SYNTH_MAX_FANOUT) 4
+
+## CTS BUFFER
+set ::env(CTS_CLK_BUFFER_LIST) "sky130_fd_sc_hd__clkbuf_4 sky130_fd_sc_hd__clkbuf_8"
+set ::env(CTS_SINK_CLUSTERING_SIZE) "16"
+set ::env(CLOCK_BUFFER_FANOUT) "8"
+
+# Sources
+# -------
+
+# Local sources + no2usb sources
+set ::env(VERILOG_FILES) "\
+        $script_dir/../../verilog/rtl/lib/clk_skew_adjust.gv \
+        $script_dir/../../verilog/rtl/lib/reset_sync.sv      \
+        $script_dir/../../verilog/rtl/qspim/src/qspim_top.sv \
+        $script_dir/../../verilog/rtl/qspim/src/qspim_if.sv \
+        $script_dir/../../verilog/rtl/qspim/src/qspim_regs.sv \
+        $script_dir/../../verilog/rtl/qspim/src/qspim_fifo.sv \
+        $script_dir/../../verilog/rtl/qspim/src/qspim_clkgen.sv \
+        $script_dir/../../verilog/rtl/qspim/src/qspim_ctrl.sv \
+        $script_dir/../../verilog/rtl/qspim/src/qspim_rx.sv \
+        $script_dir/../../verilog/rtl/qspim/src/qspim_tx.sv \
+	$script_dir/../../verilog/rtl/lib/ctech_cells.sv     \
+	"
+
+set ::env(SYNTH_DEFINES) [list SYNTHESIS ]
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+set ::env(SDC_FILE) "$script_dir/base.sdc"
+set ::env(BASE_SDC_FILE) "$script_dir/base.sdc"
+
+set ::env(LEC_ENABLE) 0
+
+set ::env(VDD_PIN) [list {vccd1}]
+set ::env(GND_PIN) [list {vssd1}]
+
+
+# Floorplanning
+# -------------
+
+set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+
+set ::env(FP_SIZING) absolute
+set ::env(DIE_AREA) "0 0 450 550"
+
+set ::env(PL_TIME_DRIVEN) 1
+set ::env(PL_TARGET_DENSITY) "0.42"
+
+# If you're going to use multiple power domains, then keep this disabled.
+set ::env(RUN_CVC) 0
+
+#set ::env(PDN_CFG) $script_dir/pdn.tcl
+
+
+# helps in anteena fix
+set ::env(USE_ARC_ANTENNA_CHECK) "0"
+
+set ::env(FP_IO_VEXTEND) 4
+set ::env(FP_IO_HEXTEND) 4
+
+set ::env(FP_PDN_VPITCH) 100
+set ::env(FP_PDN_HPITCH) 100
+set ::env(FP_PDN_VWIDTH) 5
+set ::env(FP_PDN_HWIDTH) 5
+
+set ::env(GLB_RT_MAXLAYER) 5
+set ::env(GLB_RT_MAX_DIODE_INS_ITERS) 10
+set ::env(DIODE_INSERTION_STRATEGY) 4
+
+
+set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
+set ::env(QUIT_ON_MAGIC_DRC) "1"
+set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/qspim/interactive.tcl b/openlane/qspim/interactive.tcl
new file mode 100644
index 0000000..b44b517
--- /dev/null
+++ b/openlane/qspim/interactive.tcl
@@ -0,0 +1,219 @@
+#!/usr/bin/tclsh
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+# Copyright 2020 Efabless Corporation
+# Copyright 2020 Sylvain Munaut
+#
+# 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
+
+package require openlane;
+
+
+proc run_placement_step {args} {
+    # set pdndef_dirname [file dirname $::env(pdn_tmp_file_tag).def]
+    # set pdndef [lindex [glob $pdndef_dirname/*pdn*] 0]
+    # set_def $pdndef
+    if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
+        set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
+    }
+
+    run_placement
+}
+
+proc run_cts_step {args} {
+    # set_def $::env(opendp_result_file_tag).def
+    if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
+        set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
+    }
+
+    run_cts
+    run_resizer_timing
+}
+
+proc run_routing_step {args} {
+    # set resizerdef_dirname [file dirname $::env(resizer_tmp_file_tag)_timing.def]
+    # set resizerdef [lindex [glob $resizerdef_dirname/*resizer*] 0]
+    # set_def $resizerdef
+    if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
+        set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
+    }
+    run_routing
+}
+
+proc run_diode_insertion_2_5_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
+        set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
+    }
+	if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+		run_antenna_check
+		heal_antenna_violators; # modifies the routed DEF
+	}
+
+}
+
+proc run_power_pins_insertion_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(POWER_PINS_INSERTION_CURRENT_DEF) ] } {
+        set ::env(POWER_PINS_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(POWER_PINS_INSERTION_CURRENT_DEF)
+    }
+    if { $::env(LVS_INSERT_POWER_PINS) } {
+		write_powered_verilog
+		set_netlist $::env(lvs_result_file_tag).powered.v
+    }
+
+}
+
+proc run_lvs_step {{ lvs_enabled 1 }} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
+        set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
+    }
+	if { $lvs_enabled } {
+		run_magic_spice_export
+		run_lvs; # requires run_magic_spice_export
+	}
+
+}
+
+proc run_drc_step {{ drc_enabled 1 }} {
+    if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
+        set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
+    }
+	if { $drc_enabled } {
+		run_magic_drc
+		run_klayout_drc
+	}
+}
+
+proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
+    if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
+        set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
+    }
+	if { $antenna_check_enabled } {
+		run_antenna_check
+	}
+}
+
+proc run_flow {args} {
+       set script_dir [file dirname [file normalize [info script]]]
+
+		set options {
+		{-design required}
+		{-save_path optional}
+		{-no_lvs optional}
+	    {-no_drc optional}
+	    {-no_antennacheck optional}
+	}
+	set flags {-save}
+	parse_key_args "run_flow" args arg_values $options flags_map $flags -no_consume
+
+	prep {*}$args
+
+        set LVS_ENABLED 1
+        set DRC_ENABLED 0
+        set ANTENNACHECK_ENABLED 1
+
+        set steps [dict create "synthesis" {run_synthesis "" } \
+                "floorplan" {run_floorplan ""} \
+                "placement" {run_placement_step ""} \
+                "cts" {run_cts_step ""} \
+                "routing" {run_routing_step ""}\
+                "diode_insertion" {run_diode_insertion_2_5_step ""} \
+                "power_pins_insertion" {run_power_pins_insertion_step ""} \
+                "gds_magic" {run_magic ""} \
+                "gds_drc_klayout" {run_klayout ""} \
+                "gds_xor_klayout" {run_klayout_gds_xor ""} \
+                "lvs" "run_lvs_step $LVS_ENABLED" \
+                "drc" "run_drc_step $DRC_ENABLED" \
+                "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED" \
+                "cvc" {run_lef_cvc}
+        ]
+
+       set_if_unset arg_values(-to) "cvc";
+
+       if {  [info exists ::env(CURRENT_STEP) ] } {
+           puts "\[INFO\]:Picking up where last execution left off"
+           puts [format "\[INFO\]:Current stage is %s " $::env(CURRENT_STEP)]
+       } else {
+           set ::env(CURRENT_STEP) "synthesis";
+       }
+       set_if_unset arg_values(-from) $::env(CURRENT_STEP);
+       set exe 0;
+       dict for {step_name step_exe} $steps {
+           if { [ string equal $arg_values(-from) $step_name ] } {
+               set exe 1;
+           }
+
+           if { $exe } {
+               # For when it fails
+               set ::env(CURRENT_STEP) $step_name
+               [lindex $step_exe 0] [lindex $step_exe 1] ;
+           }
+
+           if { [ string equal $arg_values(-to) $step_name ] } {
+               set exe 0:
+               break;
+           }
+
+       }
+
+       # for when it resumes
+       set steps_as_list [dict keys $steps]
+       set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
+       set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
+
+	if {  [info exists flags_map(-save) ] } {
+		if { ! [info exists arg_values(-save_path)] } {
+			set arg_values(-save_path) ""
+		}
+		save_views 	-lef_path $::env(magic_result_file_tag).lef \
+			-def_path $::env(CURRENT_DEF) \
+			-gds_path $::env(magic_result_file_tag).gds \
+			-mag_path $::env(magic_result_file_tag).mag \
+			-maglef_path $::env(magic_result_file_tag).lef.mag \
+			-spice_path $::env(magic_result_file_tag).spice \
+			-spef_path $::env(CURRENT_SPEF) \
+			-verilog_path $::env(CURRENT_NETLIST) \
+			-save_path $arg_values(-save_path) \
+			-tag $::env(RUN_TAG)
+	}
+
+
+	calc_total_runtime
+	save_state
+	generate_final_summary_report
+	
+	check_timing_violations
+
+	puts_success "Flow Completed Without Fatal Errors."
+
+}
+
+run_flow {*}$argv
diff --git a/openlane/qspim/pdn.tcl b/openlane/qspim/pdn.tcl
new file mode 100644
index 0000000..1fe689b
--- /dev/null
+++ b/openlane/qspim/pdn.tcl
@@ -0,0 +1,49 @@
+# 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
+
+# Power nets
+set ::power_nets $::env(VDD_PIN)
+set ::ground_nets $::env(GND_PIN)
+
+set ::macro_blockage_layer_list "li1 met1 met2 met3 met4 met5"
+
+pdngen::specify_grid stdcell {
+    name grid
+    rails {
+	    met1 {width 0.48 pitch $::env(PLACE_SITE_HEIGHT) offset 0}
+    }
+    straps {
+	    met4 {width 1.6 pitch $::env(FP_PDN_VPITCH) offset $::env(FP_PDN_VOFFSET)}
+	    met5 {width 1.6 pitch $::env(FP_PDN_HPITCH) offset $::env(FP_PDN_HOFFSET)}
+    }
+    connect {{met1 met4} {met4 met5}}
+}
+
+pdngen::specify_grid macro {
+    power_pins "VPWR"
+    ground_pins "VGND"
+    blockages "li1 met1 met2 met3 met4"
+    straps { 
+    } 
+    connect {{met4_PIN_ver met5}}
+}
+
+set ::halo 5
+
+# POWER or GROUND #Std. cell rails starting with power or ground rails at the bottom of the core area
+set ::rails_start_with "POWER" ;
+
+# POWER or GROUND #Upper metal stripes starting with power or ground rails at the left/bottom of the core area
+set ::stripes_start_with "POWER" ;
diff --git a/openlane/qspim/pin_order.cfg b/openlane/qspim/pin_order.cfg
new file mode 100644
index 0000000..a0c3c37
--- /dev/null
+++ b/openlane/qspim/pin_order.cfg
@@ -0,0 +1,187 @@
+#BUS_SORT
+#MANUAL_PLACE
+
+#E
+spi_debug\[0\]        0000 0  2
+spi_debug\[1\]        
+spi_debug\[2\]        
+spi_debug\[3\]        
+spi_debug\[4\]        
+spi_debug\[5\]        
+spi_debug\[6\]        
+spi_debug\[7\]        
+spi_debug\[8\]        
+spi_debug\[9\]        
+spi_debug\[10\]        
+spi_debug\[11\]        
+spi_debug\[12\]        
+spi_debug\[13\]        
+spi_debug\[14\]        
+spi_debug\[15\]        
+spi_debug\[16\]        
+spi_debug\[17\]        
+spi_debug\[18\]        
+spi_debug\[19\]        
+spi_debug\[20\]        
+spi_debug\[21\]        
+spi_debug\[22\]        
+spi_debug\[23\]        
+spi_debug\[24\]        
+spi_debug\[25\]        
+spi_debug\[26\]        
+spi_debug\[27\]        
+spi_debug\[28\]        
+spi_debug\[29\]        
+spi_debug\[30\]        
+spi_debug\[31\]        
+
+spi_sdi\[3\]             0200 0 2
+spi_sdi\[2\]        
+spi_sdi\[1\]        
+spi_sdi\[0\]        
+spi_sdo\[3\]        
+spi_sdo\[2\]        
+spi_sdo\[1\]        
+spi_sdo\[0\]  
+spi_clk 
+spi_csn\[3\]
+spi_csn\[2\]
+spi_csn\[1\]
+spi_csn\[0\]
+spi_oen\[3\]     
+spi_oen\[2\]     
+spi_oen\[1\]     
+spi_oen\[0\]     
+
+#N
+rst_n                  
+
+#W
+cfg_cska_sp_co\[3\]   0000 0 2
+cfg_cska_sp_co\[2\]
+cfg_cska_sp_co\[1\]
+cfg_cska_sp_co\[0\]
+cfg_cska_spi\[3\]
+cfg_cska_spi\[2\]
+cfg_cska_spi\[1\]
+cfg_cska_spi\[0\]
+wbd_clk_int
+wbd_clk_spi
+mclk                   
+
+wbd_stb_i              0100 0 2
+wbd_we_i               
+wbd_adr_i\[31\]        
+wbd_adr_i\[30\]        
+wbd_adr_i\[29\]        
+wbd_adr_i\[28\]        
+wbd_adr_i\[27\]        
+wbd_adr_i\[26\]        
+wbd_adr_i\[25\]        
+wbd_adr_i\[24\]        
+wbd_adr_i\[23\]      
+wbd_adr_i\[22\]      
+wbd_adr_i\[21\]      
+wbd_adr_i\[20\]      
+wbd_adr_i\[19\]      
+wbd_adr_i\[18\]      
+wbd_adr_i\[17\]      
+wbd_adr_i\[16\]      
+wbd_adr_i\[15\]      
+wbd_adr_i\[14\]      
+wbd_adr_i\[13\]      
+wbd_adr_i\[12\]      
+wbd_adr_i\[11\]      
+wbd_adr_i\[10\]      
+wbd_adr_i\[9\]       
+wbd_adr_i\[8\]       
+wbd_adr_i\[7\]       
+wbd_adr_i\[6\]       
+wbd_adr_i\[5\]       
+wbd_adr_i\[4\]       
+wbd_adr_i\[3\]       
+wbd_adr_i\[2\]       
+wbd_adr_i\[1\]       
+wbd_adr_i\[0\]       
+wbd_sel_i\[3\]       
+wbd_sel_i\[2\]       
+wbd_sel_i\[1\]       
+wbd_sel_i\[0\]       
+wbd_bl_i\[9\]       
+wbd_bl_i\[8\]       
+wbd_bl_i\[7\]       
+wbd_bl_i\[6\]       
+wbd_bl_i\[5\]       
+wbd_bl_i\[4\]       
+wbd_bl_i\[3\]       
+wbd_bl_i\[2\]       
+wbd_bl_i\[1\]       
+wbd_bl_i\[0\]       
+wbd_bry_i
+wbd_dat_i\[31\]      
+wbd_dat_i\[30\]      
+wbd_dat_i\[29\]      
+wbd_dat_i\[28\]      
+wbd_dat_i\[27\]      
+wbd_dat_i\[26\]      
+wbd_dat_i\[25\]      
+wbd_dat_i\[24\]      
+wbd_dat_i\[23\]      
+wbd_dat_i\[22\]      
+wbd_dat_i\[21\]      
+wbd_dat_i\[20\]      
+wbd_dat_i\[19\]      
+wbd_dat_i\[18\]      
+wbd_dat_i\[17\]      
+wbd_dat_i\[16\]      
+wbd_dat_i\[15\]      
+wbd_dat_i\[14\]      
+wbd_dat_i\[13\]      
+wbd_dat_i\[12\]      
+wbd_dat_i\[11\]      
+wbd_dat_i\[10\]      
+wbd_dat_i\[9\]       
+wbd_dat_i\[8\]       
+wbd_dat_i\[7\]       
+wbd_dat_i\[6\]       
+wbd_dat_i\[5\]       
+wbd_dat_i\[4\]       
+wbd_dat_i\[3\]       
+wbd_dat_i\[2\]       
+wbd_dat_i\[1\]       
+wbd_dat_i\[0\]       
+wbd_dat_o\[31\]      
+wbd_dat_o\[30\]      
+wbd_dat_o\[29\]      
+wbd_dat_o\[28\]      
+wbd_dat_o\[27\]      
+wbd_dat_o\[26\]      
+wbd_dat_o\[25\]      
+wbd_dat_o\[24\]      
+wbd_dat_o\[23\]      
+wbd_dat_o\[22\]      
+wbd_dat_o\[21\]      
+wbd_dat_o\[20\]      
+wbd_dat_o\[19\]      
+wbd_dat_o\[18\]      
+wbd_dat_o\[17\]      
+wbd_dat_o\[16\]      
+wbd_dat_o\[15\]      
+wbd_dat_o\[14\]      
+wbd_dat_o\[13\]      
+wbd_dat_o\[12\]      
+wbd_dat_o\[11\]      
+wbd_dat_o\[10\]      
+wbd_dat_o\[9\]      
+wbd_dat_o\[8\]      
+wbd_dat_o\[7\]      
+wbd_dat_o\[6\]      
+wbd_dat_o\[5\]      
+wbd_dat_o\[4\]      
+wbd_dat_o\[3\]      
+wbd_dat_o\[2\]      
+wbd_dat_o\[1\]      
+wbd_dat_o\[0\]      
+wbd_ack_o           
+wbd_lack_o           
+wbd_err_o           
diff --git a/openlane/qspim/sta.tcl b/openlane/qspim/sta.tcl
new file mode 100644
index 0000000..af91726
--- /dev/null
+++ b/openlane/qspim/sta.tcl
@@ -0,0 +1,88 @@
+# 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>
+
+
+set ::env(LIB_FASTEST) "/home/dinesha/workarea/pdk/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ff_n40C_1v95.lib"
+set ::env(LIB_SLOWEST) "/home/dinesha/workarea/pdk/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ss_100C_1v60.lib"
+set ::env(CURRENT_NETLIST) /project/openlane/spi_master/runs/spi_master/results/lvs/spim_top.lvs.powered.v
+set ::env(DESIGN_NAME) "spim_top"
+set ::env(CURRENT_SPEF) /project/openlane/spi_master/runs/spi_master/results/routing/spim_top.spef
+set ::env(BASE_SDC_FILE) "/project/openlane/spi_master/base.sdc"
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8"
+set ::env(SYNTH_DRIVING_CELL_PIN) "Y"
+set ::env(SYNTH_CAP_LOAD) "17.65"
+set ::env(WIRE_RC_LAYER) "met1"
+
+
+set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um
+read_liberty -min $::env(LIB_FASTEST)
+read_liberty -max $::env(LIB_SLOWEST)
+read_verilog $::env(CURRENT_NETLIST)
+link_design  $::env(DESIGN_NAME)
+
+read_spef  $::env(CURRENT_SPEF)
+
+read_sdc -echo $::env(BASE_SDC_FILE)
+
+# check for missing constraints
+check_setup  -verbose > unconstraints.rpt
+
+set_operating_conditions -analysis_type single
+# Propgate the clock
+set_propagated_clock [all_clocks]
+
+report_tns
+report_wns
+report_power 
+report_checks -unique -slack_max -0.0 -group_count 100 
+report_checks -unique -slack_min -0.0 -group_count 100 
+report_checks -path_delay min_max 
+report_checks -group_count 100  -slack_max -0.01  > timing.rpt
+
+report_checks -group_count 100  -slack_min -0.01 >> timing.rpt
+
+
+report_checks -to [get_port io_out[5]] -path_delay min >> timing.rpt
+report_checks -to [get_port io_out[4]] -path_delay min >> timing.rpt
+report_checks -to [get_port io_out[3]] -path_delay min >> timing.rpt
+report_checks -to [get_port io_out[2]] -path_delay min >> timing.rpt
+report_checks -to [get_port io_out[1]] -path_delay min >> timing.rpt
+
+report_checks -to [get_port io_out[5]] -path_delay max >> timing.rpt
+report_checks -to [get_port io_out[4]] -path_delay max >> timing.rpt
+report_checks -to [get_port io_out[3]] -path_delay max >> timing.rpt
+report_checks -to [get_port io_out[2]] -path_delay max >> timing.rpt
+report_checks -to [get_port io_out[1]] -path_delay max >> timing.rpt
+
+report_checks -to [get_port io_oeb[5]] -path_delay min >> timing.rpt
+report_checks -to [get_port io_oeb[4]] -path_delay min >> timing.rpt
+report_checks -to [get_port io_oeb[3]] -path_delay min >> timing.rpt
+report_checks -to [get_port io_oeb[2]] -path_delay min >> timing.rpt
+
+report_checks -to [get_port io_oeb[5]] -path_delay max >> timing.rpt
+report_checks -to [get_port io_oeb[4]] -path_delay max >> timing.rpt
+report_checks -to [get_port io_oeb[3]] -path_delay max >> timing.rpt
+report_checks -to [get_port io_oeb[2]] -path_delay max >> timing.rpt
+
+report_checks -from [get_port io_in[5]] -path_delay min >> timing.rpt
+report_checks -from [get_port io_in[4]] -path_delay min >> timing.rpt
+report_checks -from [get_port io_in[3]] -path_delay min >> timing.rpt
+report_checks -from [get_port io_in[2]] -path_delay min >> timing.rpt
+
+report_checks -from [get_port io_in[5]] -path_delay max >> timing.rpt
+report_checks -from [get_port io_in[4]] -path_delay max >> timing.rpt
+report_checks -from [get_port io_in[3]] -path_delay max >> timing.rpt
+report_checks -from [get_port io_in[2]] -path_delay max >> timing.rpt
diff --git a/openlane/sar_adc/config.tcl b/openlane/sar_adc/config.tcl
new file mode 100644
index 0000000..7b6c845
--- /dev/null
+++ b/openlane/sar_adc/config.tcl
@@ -0,0 +1,86 @@
+# 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
+
+# section begin
+set script_dir [file dirname [file normalize [info script]]]
+
+set ::env(DESIGN_NAME) sar_adc
+#section end
+set ::env(RUN_KLAYOUT) 0
+set ::env(DESIGN_IS_CORE) 0
+set ::env(FP_PDN_CORE_RING) 0 
+
+# User Configurations
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+
+## Source Verilog Files
+set ::env(VERILOG_FILES) "\
+	$script_dir/../../caravel/verilog/rtl/defines.v \
+	$script_dir/../../verilog/rtl/sar_adc/SAR.sv \
+	$script_dir/../../verilog/rtl/sar_adc/ACMP.sv \
+	$script_dir/../../verilog/rtl/sar_adc/sar_adc.sv \
+	$script_dir/../../verilog/rtl/sar_adc/adc_reg.sv \
+        $script_dir/../../verilog/rtl/lib/registers.v"
+
+## Clock configurations
+set ::env(CLOCK_PORT) "clk"
+set ::env(CLOCK_NET)  "clk"
+
+set ::env(CLOCK_PERIOD) "100"
+
+set ::env(FP_PIN_ORDER_CFG) $script_dir/pin_order.cfg
+set ::env(PDN_CFG) $script_dir/pdn.tcl
+
+set ::env(FP_SIZING) "absolute"
+set ::env(DIE_AREA) "0 0 500 300"
+
+#set ::env(FP_HORIZONTAL_HALO) 15
+#set ::env(FP_VERTICAL_HALO)   15
+
+#set ::env(GLB_RT_OBS) "met2 109.85000 19.89500 171.54500 69.22000"
+set ::env(CLOCK_TREE_SYNTH) 0
+
+set ::env(PL_TARGET_DENSITY) "0.01"
+set ::env(GLB_RT_MAXLAYER) 5
+set ::env(GLB_RT_ADJUSTMENT) 0.15
+
+set ::env(FP_PDN_CHECK_NODES) 0
+set ::env(FP_PDN_VPITCH) "45"
+set ::env(FP_PDN_VWIDTH) "3.5"
+#
+set ::env(FP_PDN_HPITCH) "40"
+set ::env(FP_PDN_HWIDTH) "6.5"
+
+set ::env(PL_RESIZER_DESIGN_OPTIMIZATIONS) 1
+set ::env(PL_RESIZER_TIMING_OPTIMIZATIONS) 1
+
+set ::env(DIODE_INSERTION_STRATEGY) 4
+
+#set ::env(FP_VERTICAL_HALO) "35"
+#set ::env(FP_HERTICAL_HALO) "35"
+
+
+## Internal Macros
+### Macro Placement
+#set ::env(MACRO_PLACEMENT_CFG) $script_dir/macro.cfg
+
+### Black-box verilog and views
+
+set ::env(VDD_NETS) [list {vccd1} {vccd2}]
+set ::env(GND_NETS) [list {vssd1} {vssd2}]
+set ::env(SYNTH_USE_PG_PINS_DEFINES) "USE_POWER_PINS"
+
+## LVS mismatch is to be solved manually by shorting VDD and VSS pins to the core ring 
+set ::env(QUIT_ON_LVS_ERROR) "0"
diff --git a/openlane/sar_adc/interactive.tcl b/openlane/sar_adc/interactive.tcl
new file mode 100644
index 0000000..b44b517
--- /dev/null
+++ b/openlane/sar_adc/interactive.tcl
@@ -0,0 +1,219 @@
+#!/usr/bin/tclsh
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+# Copyright 2020 Efabless Corporation
+# Copyright 2020 Sylvain Munaut
+#
+# 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
+
+package require openlane;
+
+
+proc run_placement_step {args} {
+    # set pdndef_dirname [file dirname $::env(pdn_tmp_file_tag).def]
+    # set pdndef [lindex [glob $pdndef_dirname/*pdn*] 0]
+    # set_def $pdndef
+    if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
+        set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
+    }
+
+    run_placement
+}
+
+proc run_cts_step {args} {
+    # set_def $::env(opendp_result_file_tag).def
+    if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
+        set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
+    }
+
+    run_cts
+    run_resizer_timing
+}
+
+proc run_routing_step {args} {
+    # set resizerdef_dirname [file dirname $::env(resizer_tmp_file_tag)_timing.def]
+    # set resizerdef [lindex [glob $resizerdef_dirname/*resizer*] 0]
+    # set_def $resizerdef
+    if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
+        set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
+    }
+    run_routing
+}
+
+proc run_diode_insertion_2_5_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
+        set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
+    }
+	if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+		run_antenna_check
+		heal_antenna_violators; # modifies the routed DEF
+	}
+
+}
+
+proc run_power_pins_insertion_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(POWER_PINS_INSERTION_CURRENT_DEF) ] } {
+        set ::env(POWER_PINS_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(POWER_PINS_INSERTION_CURRENT_DEF)
+    }
+    if { $::env(LVS_INSERT_POWER_PINS) } {
+		write_powered_verilog
+		set_netlist $::env(lvs_result_file_tag).powered.v
+    }
+
+}
+
+proc run_lvs_step {{ lvs_enabled 1 }} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
+        set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
+    }
+	if { $lvs_enabled } {
+		run_magic_spice_export
+		run_lvs; # requires run_magic_spice_export
+	}
+
+}
+
+proc run_drc_step {{ drc_enabled 1 }} {
+    if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
+        set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
+    }
+	if { $drc_enabled } {
+		run_magic_drc
+		run_klayout_drc
+	}
+}
+
+proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
+    if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
+        set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
+    }
+	if { $antenna_check_enabled } {
+		run_antenna_check
+	}
+}
+
+proc run_flow {args} {
+       set script_dir [file dirname [file normalize [info script]]]
+
+		set options {
+		{-design required}
+		{-save_path optional}
+		{-no_lvs optional}
+	    {-no_drc optional}
+	    {-no_antennacheck optional}
+	}
+	set flags {-save}
+	parse_key_args "run_flow" args arg_values $options flags_map $flags -no_consume
+
+	prep {*}$args
+
+        set LVS_ENABLED 1
+        set DRC_ENABLED 0
+        set ANTENNACHECK_ENABLED 1
+
+        set steps [dict create "synthesis" {run_synthesis "" } \
+                "floorplan" {run_floorplan ""} \
+                "placement" {run_placement_step ""} \
+                "cts" {run_cts_step ""} \
+                "routing" {run_routing_step ""}\
+                "diode_insertion" {run_diode_insertion_2_5_step ""} \
+                "power_pins_insertion" {run_power_pins_insertion_step ""} \
+                "gds_magic" {run_magic ""} \
+                "gds_drc_klayout" {run_klayout ""} \
+                "gds_xor_klayout" {run_klayout_gds_xor ""} \
+                "lvs" "run_lvs_step $LVS_ENABLED" \
+                "drc" "run_drc_step $DRC_ENABLED" \
+                "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED" \
+                "cvc" {run_lef_cvc}
+        ]
+
+       set_if_unset arg_values(-to) "cvc";
+
+       if {  [info exists ::env(CURRENT_STEP) ] } {
+           puts "\[INFO\]:Picking up where last execution left off"
+           puts [format "\[INFO\]:Current stage is %s " $::env(CURRENT_STEP)]
+       } else {
+           set ::env(CURRENT_STEP) "synthesis";
+       }
+       set_if_unset arg_values(-from) $::env(CURRENT_STEP);
+       set exe 0;
+       dict for {step_name step_exe} $steps {
+           if { [ string equal $arg_values(-from) $step_name ] } {
+               set exe 1;
+           }
+
+           if { $exe } {
+               # For when it fails
+               set ::env(CURRENT_STEP) $step_name
+               [lindex $step_exe 0] [lindex $step_exe 1] ;
+           }
+
+           if { [ string equal $arg_values(-to) $step_name ] } {
+               set exe 0:
+               break;
+           }
+
+       }
+
+       # for when it resumes
+       set steps_as_list [dict keys $steps]
+       set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
+       set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
+
+	if {  [info exists flags_map(-save) ] } {
+		if { ! [info exists arg_values(-save_path)] } {
+			set arg_values(-save_path) ""
+		}
+		save_views 	-lef_path $::env(magic_result_file_tag).lef \
+			-def_path $::env(CURRENT_DEF) \
+			-gds_path $::env(magic_result_file_tag).gds \
+			-mag_path $::env(magic_result_file_tag).mag \
+			-maglef_path $::env(magic_result_file_tag).lef.mag \
+			-spice_path $::env(magic_result_file_tag).spice \
+			-spef_path $::env(CURRENT_SPEF) \
+			-verilog_path $::env(CURRENT_NETLIST) \
+			-save_path $arg_values(-save_path) \
+			-tag $::env(RUN_TAG)
+	}
+
+
+	calc_total_runtime
+	save_state
+	generate_final_summary_report
+	
+	check_timing_violations
+
+	puts_success "Flow Completed Without Fatal Errors."
+
+}
+
+run_flow {*}$argv
diff --git a/openlane/sar_adc/pdn.tcl b/openlane/sar_adc/pdn.tcl
new file mode 100644
index 0000000..c23f68f
--- /dev/null
+++ b/openlane/sar_adc/pdn.tcl
@@ -0,0 +1,92 @@
+# Power nets
+
+if { ! [info exists ::env(VDD_NET)] } {
+	set ::env(VDD_NET) $::env(VDD_PIN)
+}
+
+if { ! [info exists ::env(GND_NET)] } {
+	set ::env(GND_NET) $::env(GND_PIN)
+}
+
+set ::power_nets $::env(VDD_NET)
+set ::ground_nets $::env(GND_NET)
+
+if { [info exists ::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS)] } {
+    if { $::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS) == 1 } {
+        add_global_connection -net $::env(VDD_NET) -inst_pattern .* -pin_pattern {VPWR} -power
+        add_global_connection -net $::env(VDD_NET) -inst_pattern .* -pin_pattern {VPB} -power
+        add_global_connection -net $::env(GND_NET) -inst_pattern .* -pin_pattern {VGND} -ground
+        add_global_connection -net $::env(GND_NET) -inst_pattern .* -pin_pattern {VNB} -ground
+    }
+}
+
+set_voltage_domain -name CORE -power $::env(VDD_NET) -ground $::env(GND_NET)
+
+# Assesses whether the deisgn is the core of the chip or not based on the 
+# value of $::env(DESIGN_IS_CORE) and uses the appropriate stdcell section
+if { $::env(DESIGN_IS_CORE) == 1 } {
+    # Used if the design is the core of the chip
+    define_pdn_grid -name stdcell_grid -starts_with POWER -voltage_domain CORE -pins [subst {$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)}]
+    add_pdn_stripe -grid stdcell_grid -layer $::env(FP_PDN_LOWER_LAYER) -width $::env(FP_PDN_VWIDTH) -pitch $::env(FP_PDN_VPITCH) -offset $::env(FP_PDN_VOFFSET) -starts_with POWER
+    add_pdn_stripe -grid stdcell_grid -layer $::env(FP_PDN_UPPER_LAYER) -width $::env(FP_PDN_HWIDTH) -pitch $::env(FP_PDN_HPITCH) -offset $::env(FP_PDN_HOFFSET) -starts_with POWER
+    add_pdn_connect -grid stdcell_grid -layers [subst {$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)}]
+} else {
+    # Used if the design is a macro in the core
+    define_pdn_grid -name stdcell_grid -starts_with POWER -voltage_domain CORE -pins $::env(FP_PDN_LOWER_LAYER)
+    add_pdn_stripe -grid stdcell_grid -layer $::env(FP_PDN_LOWER_LAYER) -width $::env(FP_PDN_VWIDTH) -pitch $::env(FP_PDN_VPITCH) -offset $::env(FP_PDN_VOFFSET) -starts_with POWER
+}
+
+# Adds the standard cell rails if enabled.
+if { $::env(FP_PDN_ENABLE_RAILS) == 1 } {
+    add_pdn_stripe -grid stdcell_grid -layer $::env(FP_PDN_RAILS_LAYER) -width $::env(FP_PDN_RAIL_WIDTH) -followpins -starts_with POWER
+    add_pdn_connect -grid stdcell_grid -layers [subst {$::env(FP_PDN_RAILS_LAYER) $::env(FP_PDN_LOWER_LAYER)}]
+} 
+
+
+# Adds the core ring if enabled.
+if { $::env(FP_PDN_CORE_RING) == 1 } {
+    add_pdn_ring -grid stdcell_grid -layer [subst {$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)}] \
+                 -widths [subst {$::env(FP_PDN_CORE_RING_VWIDTH) $::env(FP_PDN_CORE_RING_HWIDTH)}] \
+                 -spacings [subst {$::env(FP_PDN_CORE_RING_VSPACING) $::env(FP_PDN_CORE_RING_HSPACING)}] \
+                 -core_offset [subst {$::env(FP_PDN_CORE_RING_VOFFSET) $::env(FP_PDN_CORE_RING_HOFFSET)}]
+}
+
+# A general macro that follows the premise of the set heirarchy. You may want to modify this or add other macro configs
+# The macro power pin names are assumed to match the VDD and GND net names 
+# TODO: parameterize the power pin names 
+set macro {
+    orient {R0 R180 MX MY R90 R270 MXR90 MYR90}
+    power_pins $::env(VDD_NET)
+    ground_pins $::env(GND_NET)
+    blockages "li1 met1 met2 met3 met4"
+    straps {
+    }
+    connect {{$::env(FP_PDN_LOWER_LAYER)_PIN_ver $::env(FP_PDN_UPPER_LAYER)}}
+}
+
+if { $::env(FP_PDN_ENABLE_MACROS_GRID) == 1} {
+    if { [llength $::env(FP_PDN_MACROS)] > 0 } {
+        # generate automatically per instance:
+        foreach macro_instance $::env(FP_PDN_MACROS) {
+            set macro_instance_grid [subst $macro] 
+            dict append $macro_instance_grid instance $macro_instance
+            set ::halo [list $::env(FP_HORIZONTAL_HALO) $::env(FP_VERTICAL_HALO)]
+            pdngen::specify_grid macro [subst $macro_instance_grid]
+        }
+    } else {
+        set ::halo [list $::env(FP_HORIZONTAL_HALO) $::env(FP_VERTICAL_HALO)]
+        pdngen::specify_grid macro [subst $macro]
+    }
+    # CAN NOT ENABLE THE TCL COMMAND BECAUSE THERE IS NO ARGUMENT FOR SPECIFYING THE POWER AND GROUND PIN NAMES ON THE MACRO
+    # define_pdn_grid -macro -orient {R0 R180 MX MY R90 R270 MXR90 MYR90} -grid_over_pg_pins -starts_with POWER -pin_direction vertical -halo [subst {$::env(FP_HORIZONTAL_HALO) $::env(FP_VERTICAL_HALO)}]
+    # add_pdn_connect -layers [subst {$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)}]
+} else {
+    define_pdn_grid -macro -orient {R0 R180 MX MY R90 R270 MXR90 MYR90} -grid_over_pg_pins -starts_with POWER -halo [subst {$::env(FP_HORIZONTAL_HALO) $::env(FP_VERTICAL_HALO)}]
+}
+
+# POWER or GROUND #Std. cell rails starting with power or ground rails at the bottom of the core area
+set ::rails_start_with "POWER" ;
+
+# POWER or GROUND #Upper metal stripes starting with power or ground rails at the left/bottom of the core area
+set ::stripes_start_with "POWER" ;
+
diff --git a/openlane/sar_adc/pin_order.cfg b/openlane/sar_adc/pin_order.cfg
new file mode 100644
index 0000000..b68e105
--- /dev/null
+++ b/openlane/sar_adc/pin_order.cfg
@@ -0,0 +1,106 @@
+#BUS_SORT
+#MANUAL_PLACE
+
+#S
+reset_n          
+pulse1m_mclk             
+
+#W
+clk                      000 0 2
+reg_cs            
+reg_wr           
+reg_addr\[7\]    
+reg_addr\[6\]    
+reg_addr\[5\]    
+reg_addr\[4\]    
+reg_addr\[3\]    
+reg_addr\[2\]    
+reg_addr\[1\]    
+reg_addr\[0\]    
+reg_be\[3\]    
+reg_be\[2\]    
+reg_be\[1\]    
+reg_be\[0\]    
+reg_wdata\[31\]   
+reg_wdata\[30\]   
+reg_wdata\[29\]   
+reg_wdata\[28\]   
+reg_wdata\[27\]   
+reg_wdata\[26\]   
+reg_wdata\[25\]   
+reg_wdata\[24\]   
+reg_wdata\[23\]   
+reg_wdata\[22\]   
+reg_wdata\[21\]   
+reg_wdata\[20\]   
+reg_wdata\[19\]   
+reg_wdata\[18\]   
+reg_wdata\[17\]   
+reg_wdata\[16\]   
+reg_wdata\[15\]   
+reg_wdata\[14\]   
+reg_wdata\[13\]   
+reg_wdata\[12\]  
+reg_wdata\[11\]  
+reg_wdata\[10\]  
+reg_wdata\[9\]   
+reg_wdata\[8\]   
+reg_wdata\[7\]   
+reg_wdata\[6\]   
+reg_wdata\[5\]   
+reg_wdata\[4\]   
+reg_wdata\[3\]   
+reg_wdata\[2\]   
+reg_wdata\[1\]   
+reg_wdata\[0\]   
+reg_rdata\[31\]  
+reg_rdata\[30\]  
+reg_rdata\[29\]  
+reg_rdata\[28\]  
+reg_rdata\[27\]  
+reg_rdata\[26\]  
+reg_rdata\[25\]  
+reg_rdata\[24\]  
+reg_rdata\[23\]  
+reg_rdata\[22\]  
+reg_rdata\[21\]  
+reg_rdata\[20\]  
+reg_rdata\[19\]  
+reg_rdata\[18\]  
+reg_rdata\[17\]  
+reg_rdata\[16\]  
+reg_rdata\[15\]  
+reg_rdata\[14\]  
+reg_rdata\[13\]  
+reg_rdata\[12\]  
+reg_rdata\[11\]  
+reg_rdata\[10\]  
+reg_rdata\[9\]  
+reg_rdata\[8\]  
+reg_rdata\[7\]  
+reg_rdata\[6\]  
+reg_rdata\[5\]  
+reg_rdata\[4\]  
+reg_rdata\[3\]  
+reg_rdata\[2\]  
+reg_rdata\[1\]  
+reg_rdata\[0\]  
+reg_ack       
+
+
+#N
+sar2dac\[7\]
+sar2dac\[6\]
+sar2dac\[5\]
+sar2dac\[4\]
+sar2dac\[3\]
+sar2dac\[2\]
+sar2dac\[1\]
+sar2dac\[0\]
+analog_din\[5\]
+analog_din\[4\]
+analog_din\[3\]
+analog_din\[2\]
+analog_din\[1\]
+analog_din\[0\]
+analog_dac_out
diff --git a/openlane/uart_i2cm_usb_spi/base.sdc b/openlane/uart_i2cm_usb_spi/base.sdc
new file mode 100644
index 0000000..bee06d8
--- /dev/null
+++ b/openlane/uart_i2cm_usb_spi/base.sdc
@@ -0,0 +1,76 @@
+###############################################################################
+# Created by write_sdc
+# Wed Nov 10 17:08:57 2021
+###############################################################################
+current_design uart_i2c_usb_spi_top
+###############################################################################
+# Timing Constraints
+###############################################################################
+create_clock -name app_clk -period 10.0000 [get_ports {app_clk}]
+create_clock -name line_clk -period 100.0000 [get_pins {u_uart_core.u_lineclk_buf.u_mux/X}]
+create_clock -name usb_clk -period 100.0000 [get_ports {usb_clk}]
+
+set_clock_transition 0.1500 [all_clocks]
+set_clock_uncertainty -setup 0.2500 [all_clocks]
+set_clock_uncertainty -hold 0.2500 [all_clocks]
+
+
+
+set_clock_groups -name async_clock -asynchronous \
+ -group [get_clocks {app_clk}]\
+ -group [get_clocks {usb_clk}]\
+ -group [get_clocks {line_clk}] -comment {Async Clock group}
+
+### ClkSkew Adjust
+set_case_analysis 0 [get_ports {cfg_cska_uart[0]}]
+set_case_analysis 0 [get_ports {cfg_cska_uart[1]}]
+set_case_analysis 0 [get_ports {cfg_cska_uart[2]}]
+set_case_analysis 0 [get_ports {cfg_cska_uart[3]}]
+
+
+set_max_delay 5 -from [get_ports {wbd_clk_int}]
+set_max_delay 5 -to   [get_ports {wbd_clk_uart}]
+set_max_delay 5 -from wbd_clk_int -to wbd_clk_uart
+
+
+
+set_input_delay 3.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {i2c_rstn}]
+set_input_delay 3.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {uart_rstn}]
+set_input_delay 3.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {usb_rstn}]
+
+
+set_input_delay  -max 6.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_addr[*]}]
+set_input_delay  -max 6.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_be[*]}]
+set_input_delay  -max 6.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_cs}]
+set_input_delay  -max 6.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_wdata[*]}]
+set_input_delay  -max 6.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_wr}]
+
+set_input_delay  -min 2.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_addr[*]}]
+set_input_delay  -min 2.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_be[*]}]
+set_input_delay  -min 2.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_cs}]
+set_input_delay  -min 2.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_wdata[*]}]
+set_input_delay  -min 2.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_wr}]
+
+
+set_output_delay -max 6.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_ack}]
+set_output_delay -max 6.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_rdata[*]}]
+
+set_output_delay -min 1.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_ack}]
+set_output_delay -min 1.0000 -clock [get_clocks {app_clk}] -add_delay [get_ports {reg_rdata[*]}]
+
+###############################################################################
+# Environment
+###############################################################################
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin $::env(SYNTH_DRIVING_CELL_PIN) [all_inputs]
+set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0]
+puts "\[INFO\]: Setting load to: $cap_load"
+set_load  $cap_load [all_outputs]
+
+set ::env(SYNTH_TIMING_DERATE) 0.05
+puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %"
+set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
+set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}]
+
+###############################################################################
+# Design Rules
+###############################################################################
diff --git a/openlane/uart_i2cm_usb_spi/config.tcl b/openlane/uart_i2cm_usb_spi/config.tcl
new file mode 100644
index 0000000..fa19eff
--- /dev/null
+++ b/openlane/uart_i2cm_usb_spi/config.tcl
@@ -0,0 +1,124 @@
+# 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>
+
+# Global
+# ------
+
+set script_dir [file dirname [file normalize [info script]]]
+# Name
+set ::env(DESIGN_NAME) uart_i2c_usb_spi_top
+
+
+set ::env(DESIGN_IS_CORE) "0"
+set ::env(FP_PDN_CORE_RING) "0"
+
+# Timing configuration
+set ::env(CLOCK_PERIOD) "10"
+set ::env(CLOCK_PORT) "app_clk usb_clk u_uart_core.u_lineclk_buf.u_mux/X"
+
+set ::env(SYNTH_MAX_FANOUT) 4
+
+## CTS BUFFER
+set ::env(CTS_CLK_BUFFER_LIST) "sky130_fd_sc_hd__clkbuf_4 sky130_fd_sc_hd__clkbuf_8"
+set ::env(CTS_SINK_CLUSTERING_SIZE) "16"
+set ::env(CLOCK_BUFFER_FANOUT) "8"
+
+# Sources
+# -------
+
+# Local sources + no2usb sources
+set ::env(VERILOG_FILES) "\
+    $script_dir/../../verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv \
+    $script_dir/../../verilog/rtl/uart/src/uart_core.sv  \
+    $script_dir/../../verilog/rtl/uart/src/uart_cfg.sv   \
+    $script_dir/../../verilog/rtl/uart/src/uart_rxfsm.sv \
+    $script_dir/../../verilog/rtl/uart/src/uart_txfsm.sv \
+    $script_dir/../../verilog/rtl/lib/async_wb.sv   \
+    $script_dir/../../verilog/rtl/lib/async_fifo.sv      \
+    $script_dir/../../verilog/rtl/lib/async_fifo_th.sv   \
+    $script_dir/../../verilog/rtl/lib/reset_sync.sv      \
+    $script_dir/../../verilog/rtl/lib/double_sync_low.v  \
+    $script_dir/../../verilog/rtl/lib/clk_ctl.v          \
+    $script_dir/../../verilog/rtl/lib/registers.v        \
+    $script_dir/../../verilog/rtl/i2cm/src/core/i2cm_bit_ctrl.v      \
+    $script_dir/../../verilog/rtl/i2cm/src/core/i2cm_byte_ctrl.v     \
+    $script_dir/../../verilog/rtl/i2cm/src/core/i2cm_top.v           \
+    $script_dir/../../verilog/rtl/usb1_host/src/core/usbh_core.sv    \
+    $script_dir/../../verilog/rtl/usb1_host/src/core/usbh_crc16.sv   \
+    $script_dir/../../verilog/rtl/usb1_host/src/core/usbh_crc5.sv    \
+    $script_dir/../../verilog/rtl/usb1_host/src/core/usbh_fifo.sv    \  
+    $script_dir/../../verilog/rtl/usb1_host/src/core/usbh_sie.sv     \
+    $script_dir/../../verilog/rtl/usb1_host/src/phy/usb_fs_phy.v     \
+    $script_dir/../../verilog/rtl/usb1_host/src/phy/usb_transceiver.v\
+    $script_dir/../../verilog/rtl/usb1_host/src/top/usb1_host.sv     \
+    $script_dir/../../verilog/rtl/sspim/src/sspim_top.sv             \
+    $script_dir/../../verilog/rtl/sspim/src/sspim_ctl.sv             \
+    $script_dir/../../verilog/rtl/sspim/src/sspim_if.sv              \
+    $script_dir/../../verilog/rtl/sspim/src/sspim_cfg.sv             \
+    $script_dir/../../verilog/rtl/uart_i2c_usb_spi/src/uart_i2c_usb_spi.sv\
+    $script_dir/../../verilog/rtl/lib/ctech_cells.sv     \
+    "
+
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+set ::env(VERILOG_INCLUDE_DIRS) [glob $script_dir/../../verilog/rtl/i2cm/src/includes $script_dir/../../verilog/rtl/usb1_host/src/includes ]
+set ::env(SYNTH_DEFINES) [list SYNTHESIS ]
+
+set ::env(SDC_FILE) "$script_dir/base.sdc"
+set ::env(BASE_SDC_FILE) "$script_dir/base.sdc"
+
+set ::env(LEC_ENABLE) 0
+
+set ::env(VDD_PIN) [list {vccd1}]
+set ::env(GND_PIN) [list {vssd1}]
+
+
+# Floorplanning
+# -------------
+
+set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+set ::env(FP_SIZING) "absolute"
+set ::env(DIE_AREA) [list 0.0 0.0 500.0 700.0]
+
+
+
+# If you're going to use multiple power domains, then keep this disabled.
+set ::env(RUN_CVC) 0
+
+#set ::env(PDN_CFG) $script_dir/pdn.tcl
+
+
+set ::env(PL_TIME_DRIVEN) 1
+set ::env(PL_TARGET_DENSITY) "0.45"
+
+# helps in anteena fix
+set ::env(USE_ARC_ANTENNA_CHECK) "0"
+
+set ::env(FP_IO_VEXTEND) 4
+set ::env(FP_IO_HEXTEND) 4
+
+set ::env(FP_PDN_VPITCH) 100
+set ::env(FP_PDN_HPITCH) 100
+set ::env(FP_PDN_VWIDTH) 5
+set ::env(FP_PDN_HWIDTH) 5
+
+set ::env(GLB_RT_MAXLAYER) 5
+set ::env(GLB_RT_MAX_DIODE_INS_ITERS) 10
+set ::env(DIODE_INSERTION_STRATEGY) 4
+
+set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
+set ::env(QUIT_ON_MAGIC_DRC) "1"
+set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/uart_i2cm_usb_spi/interactive.tcl b/openlane/uart_i2cm_usb_spi/interactive.tcl
new file mode 100644
index 0000000..b44b517
--- /dev/null
+++ b/openlane/uart_i2cm_usb_spi/interactive.tcl
@@ -0,0 +1,219 @@
+#!/usr/bin/tclsh
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+# Copyright 2020 Efabless Corporation
+# Copyright 2020 Sylvain Munaut
+#
+# 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
+
+package require openlane;
+
+
+proc run_placement_step {args} {
+    # set pdndef_dirname [file dirname $::env(pdn_tmp_file_tag).def]
+    # set pdndef [lindex [glob $pdndef_dirname/*pdn*] 0]
+    # set_def $pdndef
+    if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
+        set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
+    }
+
+    run_placement
+}
+
+proc run_cts_step {args} {
+    # set_def $::env(opendp_result_file_tag).def
+    if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
+        set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
+    }
+
+    run_cts
+    run_resizer_timing
+}
+
+proc run_routing_step {args} {
+    # set resizerdef_dirname [file dirname $::env(resizer_tmp_file_tag)_timing.def]
+    # set resizerdef [lindex [glob $resizerdef_dirname/*resizer*] 0]
+    # set_def $resizerdef
+    if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
+        set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
+    }
+    run_routing
+}
+
+proc run_diode_insertion_2_5_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
+        set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
+    }
+	if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+		run_antenna_check
+		heal_antenna_violators; # modifies the routed DEF
+	}
+
+}
+
+proc run_power_pins_insertion_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(POWER_PINS_INSERTION_CURRENT_DEF) ] } {
+        set ::env(POWER_PINS_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(POWER_PINS_INSERTION_CURRENT_DEF)
+    }
+    if { $::env(LVS_INSERT_POWER_PINS) } {
+		write_powered_verilog
+		set_netlist $::env(lvs_result_file_tag).powered.v
+    }
+
+}
+
+proc run_lvs_step {{ lvs_enabled 1 }} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
+        set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
+    }
+	if { $lvs_enabled } {
+		run_magic_spice_export
+		run_lvs; # requires run_magic_spice_export
+	}
+
+}
+
+proc run_drc_step {{ drc_enabled 1 }} {
+    if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
+        set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
+    }
+	if { $drc_enabled } {
+		run_magic_drc
+		run_klayout_drc
+	}
+}
+
+proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
+    if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
+        set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
+    }
+	if { $antenna_check_enabled } {
+		run_antenna_check
+	}
+}
+
+proc run_flow {args} {
+       set script_dir [file dirname [file normalize [info script]]]
+
+		set options {
+		{-design required}
+		{-save_path optional}
+		{-no_lvs optional}
+	    {-no_drc optional}
+	    {-no_antennacheck optional}
+	}
+	set flags {-save}
+	parse_key_args "run_flow" args arg_values $options flags_map $flags -no_consume
+
+	prep {*}$args
+
+        set LVS_ENABLED 1
+        set DRC_ENABLED 0
+        set ANTENNACHECK_ENABLED 1
+
+        set steps [dict create "synthesis" {run_synthesis "" } \
+                "floorplan" {run_floorplan ""} \
+                "placement" {run_placement_step ""} \
+                "cts" {run_cts_step ""} \
+                "routing" {run_routing_step ""}\
+                "diode_insertion" {run_diode_insertion_2_5_step ""} \
+                "power_pins_insertion" {run_power_pins_insertion_step ""} \
+                "gds_magic" {run_magic ""} \
+                "gds_drc_klayout" {run_klayout ""} \
+                "gds_xor_klayout" {run_klayout_gds_xor ""} \
+                "lvs" "run_lvs_step $LVS_ENABLED" \
+                "drc" "run_drc_step $DRC_ENABLED" \
+                "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED" \
+                "cvc" {run_lef_cvc}
+        ]
+
+       set_if_unset arg_values(-to) "cvc";
+
+       if {  [info exists ::env(CURRENT_STEP) ] } {
+           puts "\[INFO\]:Picking up where last execution left off"
+           puts [format "\[INFO\]:Current stage is %s " $::env(CURRENT_STEP)]
+       } else {
+           set ::env(CURRENT_STEP) "synthesis";
+       }
+       set_if_unset arg_values(-from) $::env(CURRENT_STEP);
+       set exe 0;
+       dict for {step_name step_exe} $steps {
+           if { [ string equal $arg_values(-from) $step_name ] } {
+               set exe 1;
+           }
+
+           if { $exe } {
+               # For when it fails
+               set ::env(CURRENT_STEP) $step_name
+               [lindex $step_exe 0] [lindex $step_exe 1] ;
+           }
+
+           if { [ string equal $arg_values(-to) $step_name ] } {
+               set exe 0:
+               break;
+           }
+
+       }
+
+       # for when it resumes
+       set steps_as_list [dict keys $steps]
+       set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
+       set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
+
+	if {  [info exists flags_map(-save) ] } {
+		if { ! [info exists arg_values(-save_path)] } {
+			set arg_values(-save_path) ""
+		}
+		save_views 	-lef_path $::env(magic_result_file_tag).lef \
+			-def_path $::env(CURRENT_DEF) \
+			-gds_path $::env(magic_result_file_tag).gds \
+			-mag_path $::env(magic_result_file_tag).mag \
+			-maglef_path $::env(magic_result_file_tag).lef.mag \
+			-spice_path $::env(magic_result_file_tag).spice \
+			-spef_path $::env(CURRENT_SPEF) \
+			-verilog_path $::env(CURRENT_NETLIST) \
+			-save_path $arg_values(-save_path) \
+			-tag $::env(RUN_TAG)
+	}
+
+
+	calc_total_runtime
+	save_state
+	generate_final_summary_report
+	
+	check_timing_violations
+
+	puts_success "Flow Completed Without Fatal Errors."
+
+}
+
+run_flow {*}$argv
diff --git a/openlane/uart_i2cm_usb_spi/pdn.tcl b/openlane/uart_i2cm_usb_spi/pdn.tcl
new file mode 100644
index 0000000..1fe689b
--- /dev/null
+++ b/openlane/uart_i2cm_usb_spi/pdn.tcl
@@ -0,0 +1,49 @@
+# 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
+
+# Power nets
+set ::power_nets $::env(VDD_PIN)
+set ::ground_nets $::env(GND_PIN)
+
+set ::macro_blockage_layer_list "li1 met1 met2 met3 met4 met5"
+
+pdngen::specify_grid stdcell {
+    name grid
+    rails {
+	    met1 {width 0.48 pitch $::env(PLACE_SITE_HEIGHT) offset 0}
+    }
+    straps {
+	    met4 {width 1.6 pitch $::env(FP_PDN_VPITCH) offset $::env(FP_PDN_VOFFSET)}
+	    met5 {width 1.6 pitch $::env(FP_PDN_HPITCH) offset $::env(FP_PDN_HOFFSET)}
+    }
+    connect {{met1 met4} {met4 met5}}
+}
+
+pdngen::specify_grid macro {
+    power_pins "VPWR"
+    ground_pins "VGND"
+    blockages "li1 met1 met2 met3 met4"
+    straps { 
+    } 
+    connect {{met4_PIN_ver met5}}
+}
+
+set ::halo 5
+
+# POWER or GROUND #Std. cell rails starting with power or ground rails at the bottom of the core area
+set ::rails_start_with "POWER" ;
+
+# POWER or GROUND #Upper metal stripes starting with power or ground rails at the left/bottom of the core area
+set ::stripes_start_with "POWER" ;
diff --git a/openlane/uart_i2cm_usb_spi/pin_order.cfg b/openlane/uart_i2cm_usb_spi/pin_order.cfg
new file mode 100644
index 0000000..3fc5625
--- /dev/null
+++ b/openlane/uart_i2cm_usb_spi/pin_order.cfg
@@ -0,0 +1,128 @@
+#BUS_SORT
+#MANUAL_PLACE
+
+#W
+cfg_cska_uart\[3\]     0000 0  2
+cfg_cska_uart\[2\]
+cfg_cska_uart\[1\]
+cfg_cska_uart\[0\]
+wbd_clk_int
+wbd_clk_uart
+app_clk                
+
+reg_cs                 0100 0  2
+reg_wr                 
+reg_addr\[7\]          
+reg_addr\[6\]          
+reg_addr\[5\]          
+reg_addr\[4\]          
+reg_addr\[3\]          
+reg_addr\[2\]          
+reg_addr\[1\]          
+reg_addr\[0\]          
+reg_be\[3\]                 
+reg_be\[2\]                 
+reg_be\[1\]                 
+reg_be\[0\]                 
+reg_wdata\[31\]         
+reg_wdata\[30\]         
+reg_wdata\[29\]         
+reg_wdata\[28\]         
+reg_wdata\[27\]         
+reg_wdata\[26\]         
+reg_wdata\[25\]         
+reg_wdata\[24\]         
+reg_wdata\[23\]         
+reg_wdata\[22\]         
+reg_wdata\[21\]         
+reg_wdata\[20\]         
+reg_wdata\[19\]         
+reg_wdata\[18\]         
+reg_wdata\[17\]         
+reg_wdata\[16\]         
+reg_wdata\[15\]         
+reg_wdata\[14\]         
+reg_wdata\[13\]         
+reg_wdata\[12\]         
+reg_wdata\[11\]         
+reg_wdata\[10\]         
+reg_wdata\[9\]         
+reg_wdata\[8\]         
+reg_wdata\[7\]         
+reg_wdata\[6\]         
+reg_wdata\[5\]         
+reg_wdata\[4\]         
+reg_wdata\[3\]         
+reg_wdata\[2\]         
+reg_wdata\[1\]         
+reg_wdata\[0\]  
+       
+reg_rdata\[31\]         
+reg_rdata\[30\]         
+reg_rdata\[29\]         
+reg_rdata\[28\]         
+reg_rdata\[27\]         
+reg_rdata\[26\]         
+reg_rdata\[25\]         
+reg_rdata\[24\]         
+reg_rdata\[23\]         
+reg_rdata\[22\]         
+reg_rdata\[21\]         
+reg_rdata\[20\]         
+reg_rdata\[19\]         
+reg_rdata\[18\]         
+reg_rdata\[17\]         
+reg_rdata\[16\]         
+reg_rdata\[15\]         
+reg_rdata\[14\]         
+reg_rdata\[13\]         
+reg_rdata\[12\]         
+reg_rdata\[11\]         
+reg_rdata\[10\]         
+reg_rdata\[9\]         
+reg_rdata\[8\]         
+reg_rdata\[7\]         
+reg_rdata\[6\]         
+reg_rdata\[5\]         
+reg_rdata\[4\]         
+reg_rdata\[3\]         
+reg_rdata\[2\]         
+reg_rdata\[1\]         
+reg_rdata\[0\]         
+reg_ack                
+
+
+#S
+usb_clk
+uart_rstn    
+i2c_rstn 
+usb_rstn 
+
+
+#E
+scl_pad_i 
+scl_pad_o
+scl_pad_oen_o
+sda_pad_i
+sda_pad_o
+sda_padoen_o
+uart_rxd
+uart_txd
+usb_in_dp
+usb_in_dn
+usb_out_dp
+usb_out_dn
+usb_out_tx_oen
+
+i2cm_intr_o
+usb_intr_o
+
+spi_rstn 
+sspim_sck
+sspim_si
+sspim_so
+sspim_ssn
+
+
+         
+
diff --git a/openlane/uart_i2cm_usb_spi/sta.tcl b/openlane/uart_i2cm_usb_spi/sta.tcl
new file mode 100644
index 0000000..ef1ab52
--- /dev/null
+++ b/openlane/uart_i2cm_usb_spi/sta.tcl
@@ -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: Modified by Dinesh Annayya <dinesha@opencores.org>
+
+set ::env(LIB_FASTEST) "/home/dinesha/workarea/pdk/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ff_n40C_1v95.lib"
+set ::env(LIB_SLOWEST) "/home/dinesha/workarea/pdk/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ss_100C_1v60.lib"
+set ::env(CURRENT_NETLIST) /project/openlane/uart_i2cm/runs/uart_i2cm/results/lvs/uart_i2c_top.lvs.powered.v
+set ::env(DESIGN_NAME) "uart_i2c_top"
+set ::env(CURRENT_SPEF) /project/openlane/uart_i2cm/runs/uart_i2cm/results/routing/uart_i2c_top.spef
+set ::env(BASE_SDC_FILE) "/project/openlane/uart_i2cm/base.sdc"
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8"
+set ::env(SYNTH_DRIVING_CELL_PIN) "Y"
+set ::env(SYNTH_CAP_LOAD) "17.65"
+set ::env(WIRE_RC_LAYER) "met1"
+
+
+set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um
+read_liberty -min $::env(LIB_FASTEST)
+read_liberty -max $::env(LIB_SLOWEST)
+read_verilog $::env(CURRENT_NETLIST)
+link_design  $::env(DESIGN_NAME)
+
+read_spef  $::env(CURRENT_SPEF)
+
+read_sdc -echo $::env(BASE_SDC_FILE)
+
+# check for missing constraints
+#check_setup  -verbose > unconstraints.rpt
+
+set_operating_conditions -analysis_type bc_wc
+# Propgate the clock
+set_propagated_clock [all_clocks]
+
+report_tns
+report_wns
+report_power 
+report_checks -unique -slack_max -0.0 -group_count 100 
+report_checks -unique -slack_min -0.0 -group_count 100 
+report_checks -path_delay min_max 
+report_checks -group_count 100  -slack_max -0.01 
+
+
+
+
diff --git a/openlane/user_project_wrapper/base.sdc b/openlane/user_project_wrapper/base.sdc
new file mode 100644
index 0000000..4250d5e
--- /dev/null
+++ b/openlane/user_project_wrapper/base.sdc
@@ -0,0 +1,1008 @@
+###############################################################################
+# Created by write_sdc
+# Thu Nov 11 07:50:51 2021
+###############################################################################
+current_design user_project_wrapper
+###############################################################################
+# Timing Constraints
+###############################################################################
+create_clock -name user_clock2 -period 100.0000 [get_ports {user_clock2}]
+create_clock -name wbm_clk_i -period 10.0000 [get_ports {wb_clk_i}]
+set_propagated_clock [get_clocks {wbm_clk_i}]
+create_clock -name wbs_clk_i -period 10.0000  [get_pins {u_wb_host/wbs_clk_out}]
+create_clock -name cpu_clk -period 20.0000    [get_pins {u_wb_host/cpu_clk}]
+create_clock -name rtc_clk -period 50.0000    [get_pins {u_wb_host/rtc_clk}]
+create_clock -name usb_clk -period 20.0000    [get_pins {u_wb_host/usb_clk}]
+create_clock -name line_clk -period 100.0000  [get_pins {u_uart_i2c_usb_spi/u_uart_core.u_lineclk_buf/X}]
+
+set_clock_uncertainty -rise_from [get_clocks {user_clock2}] -rise_to [get_clocks {user_clock2}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {user_clock2}] -rise_to [get_clocks {user_clock2}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {user_clock2}] -fall_to [get_clocks {user_clock2}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {user_clock2}] -fall_to [get_clocks {user_clock2}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {user_clock2}] -rise_to [get_clocks {user_clock2}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {user_clock2}] -rise_to [get_clocks {user_clock2}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {user_clock2}] -fall_to [get_clocks {user_clock2}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {user_clock2}] -fall_to [get_clocks {user_clock2}]  -setup 0.2000
+
+set_clock_uncertainty -rise_from [get_clocks {wbm_clk_i}] -rise_to [get_clocks {wbm_clk_i}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {wbm_clk_i}] -rise_to [get_clocks {wbm_clk_i}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {wbm_clk_i}] -fall_to [get_clocks {wbm_clk_i}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {wbm_clk_i}] -fall_to [get_clocks {wbm_clk_i}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {wbm_clk_i}] -rise_to [get_clocks {wbm_clk_i}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {wbm_clk_i}] -rise_to [get_clocks {wbm_clk_i}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {wbm_clk_i}] -fall_to [get_clocks {wbm_clk_i}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {wbm_clk_i}] -fall_to [get_clocks {wbm_clk_i}]  -setup 0.2000
+
+set_clock_uncertainty -rise_from [get_clocks {wbs_clk_i}] -rise_to [get_clocks {wbs_clk_i}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {wbs_clk_i}] -rise_to [get_clocks {wbs_clk_i}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {wbs_clk_i}] -fall_to [get_clocks {wbs_clk_i}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {wbs_clk_i}] -fall_to [get_clocks {wbs_clk_i}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {wbs_clk_i}] -rise_to [get_clocks {wbs_clk_i}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {wbs_clk_i}] -rise_to [get_clocks {wbs_clk_i}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {wbs_clk_i}] -fall_to [get_clocks {wbs_clk_i}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {wbs_clk_i}] -fall_to [get_clocks {wbs_clk_i}]  -setup 0.2000
+
+set_clock_uncertainty -rise_from [get_clocks {cpu_clk}] -rise_to [get_clocks {cpu_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {cpu_clk}] -rise_to [get_clocks {cpu_clk}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {cpu_clk}] -fall_to [get_clocks {cpu_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {cpu_clk}] -fall_to [get_clocks {cpu_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {cpu_clk}] -rise_to [get_clocks {cpu_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {cpu_clk}] -rise_to [get_clocks {cpu_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {cpu_clk}] -fall_to [get_clocks {cpu_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {cpu_clk}] -fall_to [get_clocks {cpu_clk}]  -setup 0.2000
+
+set_clock_uncertainty -rise_from [get_clocks {usb_clk}] -rise_to [get_clocks {usb_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {usb_clk}] -rise_to [get_clocks {usb_clk}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {usb_clk}] -fall_to [get_clocks {usb_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {usb_clk}] -fall_to [get_clocks {usb_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {usb_clk}] -rise_to [get_clocks {usb_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {usb_clk}] -rise_to [get_clocks {usb_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {usb_clk}] -fall_to [get_clocks {usb_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {usb_clk}] -fall_to [get_clocks {usb_clk}]  -setup 0.2000
+
+set_clock_uncertainty -rise_from [get_clocks {rtc_clk}] -rise_to [get_clocks {rtc_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {rtc_clk}] -rise_to [get_clocks {rtc_clk}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {rtc_clk}] -fall_to [get_clocks {rtc_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {rtc_clk}] -fall_to [get_clocks {rtc_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {rtc_clk}] -rise_to [get_clocks {rtc_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {rtc_clk}] -rise_to [get_clocks {rtc_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {rtc_clk}] -fall_to [get_clocks {rtc_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {rtc_clk}] -fall_to [get_clocks {rtc_clk}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {line_clk}] -rise_to [get_clocks {line_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {line_clk}] -rise_to [get_clocks {line_clk}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {line_clk}] -fall_to [get_clocks {line_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {line_clk}] -fall_to [get_clocks {line_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {line_clk}] -rise_to [get_clocks {line_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {line_clk}] -rise_to [get_clocks {line_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {line_clk}] -fall_to [get_clocks {line_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {line_clk}] -fall_to [get_clocks {line_clk}]  -setup 0.2000
+set_clock_groups -name async_clock -asynchronous \
+ -group [get_clocks {cpu_clk}]\
+ -group [get_clocks {line_clk}]\
+ -group [get_clocks {usb_clk}]\
+ -group [get_clocks {rtc_clk}]\
+ -group [get_clocks {wbm_clk_i}]\
+ -group [get_clocks {wbs_clk_i}] -comment {Async Clock group}
+
+set_input_delay 2.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wb_rst_i}]
+
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[0]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[10]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[11]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[12]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[13]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[14]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[15]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[16]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[17]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[18]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[19]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[1]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[20]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[21]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[22]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[23]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[24]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[25]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[26]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[27]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[28]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[29]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[2]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[30]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[31]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[3]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[4]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[5]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[6]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[7]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[8]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[9]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_cyc_i}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[0]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[10]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[11]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[12]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[13]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[14]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[15]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[16]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[17]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[18]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[19]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[1]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[20]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[21]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[22]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[23]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[24]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[25]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[26]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[27]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[28]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[29]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[2]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[30]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[31]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[3]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[4]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[5]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[6]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[7]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[8]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[9]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[0]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[1]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[2]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[3]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_stb_i}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_we_i}]
+
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[0]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[10]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[11]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[12]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[13]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[14]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[15]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[16]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[17]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[18]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[19]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[1]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[20]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[21]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[22]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[23]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[24]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[25]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[26]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[27]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[28]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[29]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[2]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[30]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[31]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[3]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[4]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[5]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[6]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[7]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[8]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[9]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_cyc_i}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[0]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[10]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[11]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[12]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[13]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[14]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[15]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[16]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[17]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[18]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[19]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[1]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[20]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[21]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[22]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[23]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[24]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[25]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[26]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[27]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[28]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[29]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[2]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[30]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[31]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[3]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[4]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[5]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[6]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[7]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[8]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[9]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[0]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[1]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[2]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[3]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_stb_i}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_we_i}]
+
+
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_ack_o}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[0]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[10]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[11]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[12]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[13]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[14]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[15]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[16]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[17]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[18]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[19]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[1]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[20]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[21]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[22]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[23]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[24]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[25]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[26]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[27]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[28]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[29]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[2]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[30]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[31]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[3]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[4]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[5]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[6]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[7]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[8]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[9]}]
+
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_ack_o}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[0]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[10]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[11]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[12]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[13]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[14]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[15]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[16]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[17]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[18]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[19]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[1]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[20]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[21]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[22]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[23]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[24]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[25]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[26]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[27]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[28]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[29]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[2]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[30]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[31]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[3]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[4]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[5]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[6]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[7]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[8]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[9]}]
+###############################################################################
+# Environment
+###############################################################################
+set_load -pin_load 0.0334 [get_ports {wbs_ack_o}]
+set_load -pin_load 0.0334 [get_ports {analog_io[28]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[27]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[26]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[25]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[24]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[23]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[22]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[21]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[20]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[19]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[18]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[17]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[16]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[15]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[14]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[13]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[12]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[11]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[10]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[9]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[8]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[7]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[6]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[5]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[4]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[3]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[2]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[1]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[0]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[37]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[36]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[35]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[34]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[33]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[32]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[31]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[30]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[29]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[28]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[27]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[26]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[25]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[24]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[23]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[22]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[21]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[20]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[19]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[18]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[17]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[16]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[15]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[14]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[13]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[12]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[11]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[10]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[9]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[8]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[7]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[6]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[5]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[4]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[3]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[2]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[1]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[0]}]
+set_load -pin_load 0.0334 [get_ports {io_out[37]}]
+set_load -pin_load 0.0334 [get_ports {io_out[36]}]
+set_load -pin_load 0.0334 [get_ports {io_out[35]}]
+set_load -pin_load 0.0334 [get_ports {io_out[34]}]
+set_load -pin_load 0.0334 [get_ports {io_out[33]}]
+set_load -pin_load 0.0334 [get_ports {io_out[32]}]
+set_load -pin_load 0.0334 [get_ports {io_out[31]}]
+set_load -pin_load 0.0334 [get_ports {io_out[30]}]
+set_load -pin_load 0.0334 [get_ports {io_out[29]}]
+set_load -pin_load 0.0334 [get_ports {io_out[28]}]
+set_load -pin_load 0.0334 [get_ports {io_out[27]}]
+set_load -pin_load 0.0334 [get_ports {io_out[26]}]
+set_load -pin_load 0.0334 [get_ports {io_out[25]}]
+set_load -pin_load 0.0334 [get_ports {io_out[24]}]
+set_load -pin_load 0.0334 [get_ports {io_out[23]}]
+set_load -pin_load 0.0334 [get_ports {io_out[22]}]
+set_load -pin_load 0.0334 [get_ports {io_out[21]}]
+set_load -pin_load 0.0334 [get_ports {io_out[20]}]
+set_load -pin_load 0.0334 [get_ports {io_out[19]}]
+set_load -pin_load 0.0334 [get_ports {io_out[18]}]
+set_load -pin_load 0.0334 [get_ports {io_out[17]}]
+set_load -pin_load 0.0334 [get_ports {io_out[16]}]
+set_load -pin_load 0.0334 [get_ports {io_out[15]}]
+set_load -pin_load 0.0334 [get_ports {io_out[14]}]
+set_load -pin_load 0.0334 [get_ports {io_out[13]}]
+set_load -pin_load 0.0334 [get_ports {io_out[12]}]
+set_load -pin_load 0.0334 [get_ports {io_out[11]}]
+set_load -pin_load 0.0334 [get_ports {io_out[10]}]
+set_load -pin_load 0.0334 [get_ports {io_out[9]}]
+set_load -pin_load 0.0334 [get_ports {io_out[8]}]
+set_load -pin_load 0.0334 [get_ports {io_out[7]}]
+set_load -pin_load 0.0334 [get_ports {io_out[6]}]
+set_load -pin_load 0.0334 [get_ports {io_out[5]}]
+set_load -pin_load 0.0334 [get_ports {io_out[4]}]
+set_load -pin_load 0.0334 [get_ports {io_out[3]}]
+set_load -pin_load 0.0334 [get_ports {io_out[2]}]
+set_load -pin_load 0.0334 [get_ports {io_out[1]}]
+set_load -pin_load 0.0334 [get_ports {io_out[0]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[127]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[126]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[125]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[124]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[123]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[122]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[121]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[120]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[119]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[118]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[117]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[116]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[115]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[114]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[113]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[112]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[111]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[110]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[109]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[108]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[107]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[106]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[105]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[104]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[103]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[102]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[101]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[100]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[99]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[98]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[97]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[96]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[95]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[94]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[93]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[92]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[91]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[90]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[89]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[88]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[87]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[86]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[85]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[84]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[83]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[82]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[81]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[80]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[79]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[78]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[77]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[76]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[75]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[74]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[73]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[72]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[71]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[70]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[69]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[68]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[67]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[66]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[65]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[64]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[63]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[62]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[61]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[60]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[59]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[58]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[57]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[56]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[55]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[54]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[53]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[52]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[51]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[50]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[49]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[48]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[47]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[46]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[45]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[44]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[43]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[42]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[41]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[40]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[39]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[38]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[37]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[36]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[35]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[34]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[33]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[32]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[31]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[30]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[29]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[28]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[27]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[26]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[25]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[24]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[23]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[22]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[21]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[20]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[19]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[18]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[17]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[16]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[15]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[14]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[13]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[12]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[11]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[10]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[9]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[8]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[7]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[6]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[5]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[4]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[3]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[2]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[1]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[0]}]
+set_load -pin_load 0.0334 [get_ports {user_irq[2]}]
+set_load -pin_load 0.0334 [get_ports {user_irq[1]}]
+set_load -pin_load 0.0334 [get_ports {user_irq[0]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[31]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[30]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[29]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[28]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[27]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[26]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[25]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[24]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[23]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[22]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[21]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[20]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[19]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[18]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[17]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[16]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[15]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[14]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[13]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[12]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[11]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[10]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[9]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[8]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[7]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[6]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[5]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[4]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[3]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[2]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[1]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {user_clock2}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wb_clk_i}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wb_rst_i}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_cyc_i}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_stb_i}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_we_i}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[28]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[27]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[26]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[25]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[24]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[23]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[22]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[21]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[20]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[19]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[18]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[17]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[16]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[15]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[14]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[13]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[12]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[11]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[10]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[9]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[8]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[7]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[37]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[36]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[35]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[34]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[33]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[32]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[31]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[30]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[29]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[28]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[27]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[26]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[25]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[24]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[23]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[22]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[21]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[20]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[19]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[18]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[17]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[16]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[15]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[14]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[13]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[12]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[11]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[10]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[9]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[8]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[7]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[127]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[126]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[125]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[124]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[123]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[122]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[121]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[120]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[119]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[118]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[117]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[116]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[115]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[114]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[113]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[112]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[111]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[110]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[109]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[108]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[107]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[106]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[105]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[104]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[103]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[102]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[101]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[100]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[99]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[98]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[97]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[96]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[95]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[94]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[93]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[92]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[91]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[90]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[89]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[88]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[87]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[86]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[85]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[84]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[83]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[82]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[81]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[80]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[79]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[78]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[77]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[76]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[75]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[74]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[73]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[72]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[71]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[70]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[69]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[68]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[67]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[66]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[65]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[64]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[63]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[62]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[61]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[60]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[59]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[58]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[57]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[56]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[55]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[54]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[53]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[52]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[51]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[50]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[49]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[48]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[47]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[46]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[45]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[44]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[43]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[42]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[41]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[40]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[39]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[38]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[37]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[36]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[35]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[34]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[33]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[32]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[31]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[30]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[29]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[28]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[27]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[26]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[25]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[24]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[23]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[22]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[21]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[20]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[19]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[18]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[17]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[16]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[15]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[14]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[13]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[12]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[11]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[10]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[9]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[8]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[7]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[127]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[126]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[125]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[124]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[123]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[122]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[121]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[120]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[119]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[118]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[117]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[116]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[115]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[114]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[113]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[112]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[111]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[110]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[109]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[108]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[107]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[106]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[105]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[104]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[103]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[102]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[101]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[100]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[99]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[98]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[97]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[96]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[95]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[94]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[93]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[92]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[91]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[90]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[89]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[88]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[87]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[86]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[85]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[84]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[83]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[82]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[81]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[80]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[79]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[78]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[77]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[76]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[75]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[74]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[73]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[72]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[71]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[70]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[69]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[68]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[67]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[66]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[65]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[64]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[63]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[62]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[61]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[60]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[59]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[58]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[57]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[56]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[55]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[54]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[53]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[52]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[51]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[50]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[49]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[48]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[47]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[46]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[45]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[44]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[43]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[42]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[41]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[40]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[39]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[38]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[37]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[36]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[35]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[34]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[33]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[32]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[31]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[30]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[29]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[28]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[27]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[26]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[25]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[24]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[23]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[22]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[21]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[20]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[19]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[18]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[17]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[16]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[15]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[14]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[13]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[12]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[11]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[10]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[9]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[8]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[7]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[31]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[30]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[29]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[28]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[27]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[26]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[25]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[24]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[23]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[22]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[21]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[20]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[19]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[18]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[17]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[16]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[15]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[14]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[13]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[12]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[11]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[10]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[9]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[8]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[7]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[31]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[30]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[29]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[28]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[27]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[26]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[25]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[24]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[23]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[22]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[21]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[20]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[19]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[18]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[17]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[16]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[15]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[14]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[13]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[12]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[11]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[10]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[9]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[8]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[7]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_sel_i[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_sel_i[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_sel_i[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_sel_i[0]}]
+set_case_analysis 0 [get_pins {u_intercon/cfg_cska_wi[0]}]
+set_case_analysis 0 [get_pins {u_intercon/cfg_cska_wi[1]}]
+set_case_analysis 0 [get_pins {u_intercon/cfg_cska_wi[2]}]
+set_case_analysis 1 [get_pins {u_intercon/cfg_cska_wi[3]}]
+set_case_analysis 0 [get_pins {u_pinmux/cfg_cska_pinmux[0]}]
+set_case_analysis 1 [get_pins {u_pinmux/cfg_cska_pinmux[1]}]
+set_case_analysis 1 [get_pins {u_pinmux/cfg_cska_pinmux[2]}]
+set_case_analysis 0 [get_pins {u_pinmux/cfg_cska_pinmux[3]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_sp_co[0]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_sp_co[1]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_sp_co[2]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_sp_co[3]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_spi[0]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_spi[1]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_spi[2]}]
+set_case_analysis 1 [get_pins {u_qspi_master/cfg_cska_spi[3]}]
+set_case_analysis 1 [get_pins {u_riscv_top/cfg_cska_riscv[0]}]
+set_case_analysis 1 [get_pins {u_riscv_top/cfg_cska_riscv[1]}]
+set_case_analysis 1 [get_pins {u_riscv_top/cfg_cska_riscv[2]}]
+set_case_analysis 0 [get_pins {u_riscv_top/cfg_cska_riscv[3]}]
+set_case_analysis 0 [get_pins {u_wb_host/cfg_cska_wh[0]}]
+set_case_analysis 0 [get_pins {u_wb_host/cfg_cska_wh[1]}]
+set_case_analysis 0 [get_pins {u_wb_host/cfg_cska_wh[2]}]
+set_case_analysis 1 [get_pins {u_wb_host/cfg_cska_wh[3]}]
+
+set_case_analysis 1 [get_pins {u_uart_i2c_usb_spi/cfg_cska_uart[3]}]
+set_case_analysis 0 [get_pins {u_uart_i2c_usb_spi/cfg_cska_uart[2]}]
+set_case_analysis 0 [get_pins {u_uart_i2c_usb_spi/cfg_cska_uart[1]}]
+set_case_analysis 0 [get_pins {u_uart_i2c_usb_spi/cfg_cska_uart[0]}]
+###############################################################################
+# Design Rules
+###############################################################################
+
+#disable clock gating check at static clock select pins
+set_false_path -through [get_pins u_wb_host/u_cpu_ref_sel.u_mux/S]
+set_false_path -through [get_pins u_wb_host/u_cpu_clk_sel.u_mux/S]
+set_false_path -through [get_pins u_wb_host/u_wbs_clk_sel.u_mux/S]
+set_false_path -through [get_pins u_wb_host/u_usb_clk_sel.u_mux/S]
+
diff --git a/openlane/user_project_wrapper/config.tcl b/openlane/user_project_wrapper/config.tcl
new file mode 100644
index 0000000..2895ec4
--- /dev/null
+++ b/openlane/user_project_wrapper/config.tcl
@@ -0,0 +1,208 @@
+# 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
+
+# Base Configurations. Don't Touch
+# section begin
+
+set ::env(PDK) "sky130A"
+set ::env(STD_CELL_LIBRARY) "sky130_fd_sc_hd"
+
+# YOU ARE NOT ALLOWED TO CHANGE ANY VARIABLES DEFINED IN THE FIXED WRAPPER CFGS 
+source $::env(CARAVEL_ROOT)/openlane/user_project_wrapper_empty/fixed_wrapper_cfgs.tcl
+
+
+# YOU CAN CHANGE ANY VARIABLES DEFINED IN THE DEFAULT WRAPPER CFGS BY OVERRIDING THEM IN THIS CONFIG.TCL
+source $::env(CARAVEL_ROOT)/openlane/user_project_wrapper_empty/default_wrapper_cfgs.tcl
+
+
+set script_dir [file dirname [file normalize [info script]]]
+set proj_dir [file dirname [file normalize [info script]]]
+
+set ::env(DESIGN_NAME) user_project_wrapper
+set verilog_root $proj_dir/../../verilog/
+set lef_root $proj_dir/../../lef/
+set gds_root $proj_dir/../../gds/
+#section end
+
+# User Configurations
+#
+set ::env(DESIGN_IS_CORE) 1
+set ::env(FP_PDN_CORE_RING) 1
+
+
+## Source Verilog Files
+set ::env(VERILOG_FILES) "\
+	$proj_dir/../../verilog/rtl/user_project_wrapper.v"
+
+## Clock configurations
+set ::env(CLOCK_PORT) "user_clock2 wb_clk_i"
+#set ::env(CLOCK_NET) "mprj.clk"
+
+set ::env(CLOCK_PERIOD) "10"
+
+## Internal Macros
+### Macro Placement
+set ::env(FP_SIZING) "absolute"
+set ::env(MACRO_PLACEMENT_CFG) $proj_dir/macro.cfg
+
+set ::env(PDN_CFG) $proj_dir/pdn_cfg.tcl
+
+set ::env(SDC_FILE) "$proj_dir/base.sdc"
+set ::env(BASE_SDC_FILE) "$proj_dir/base.sdc"
+
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+
+### Black-box verilog and views
+set ::env(VERILOG_FILES_BLACKBOX) "\
+        $proj_dir/../../verilog/gl/qspim.v \
+        $proj_dir/../../verilog/gl/wb_interconnect.v \
+        $proj_dir/../../verilog/gl/pinmux.v     \
+        $proj_dir/../../verilog/gl/mbist_wrapper.v     \
+        $proj_dir/../../verilog/gl/uart_i2cm_usb_spi.v     \
+	$proj_dir/../../verilog/gl/wb_host.v \
+	$proj_dir/../../verilog/gl/yifive.v \
+	$proj_dir/../../verilog/rtl/sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v \
+	"
+
+set ::env(EXTRA_LEFS) "\
+	$lef_root/qspim.lef \
+	$lef_root/pinmux.lef \
+	$lef_root/wb_interconnect.lef \
+	$lef_root/uart_i2cm_usb_spi.lef \
+	$lef_root/wb_host.lef \
+	$lef_root/mbist_wrapper.lef \
+	$lef_root/yifive.lef \
+	$lef_root/sky130_sram_2kbyte_1rw1r_32x512_8.lef \
+	"
+
+set ::env(EXTRA_GDS_FILES) "\
+	$gds_root/qspim.gds \
+	$gds_root/pinmux.gds \
+	$gds_root/wb_interconnect.gds \
+	$gds_root/uart_i2cm_usb_spi.gds \
+	$gds_root/wb_host.gds \
+	$gds_root/mbist_wrapper.gds \
+	$gds_root/yifive.gds \
+	$gds_root/sky130_sram_2kbyte_1rw1r_32x512_8.gds \
+	"
+
+set ::env(SYNTH_DEFINES) [list SYNTHESIS ]
+
+#set ::env(VERILOG_INCLUDE_DIRS) [glob $proj_dir/../../verilog/rtl/yifive/ycr1c/src/includes ]
+
+set ::env(GLB_RT_MAXLAYER) 5
+
+set ::env(FP_PDN_CHECK_NODES) 0
+
+
+## Internal Macros
+### Macro PDN Connections
+set ::env(FP_PDN_ENABLE_MACROS_GRID) "1"
+set ::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS) "1"
+
+set ::env(VDD_NETS) "vccd1 vccd2 vdda1 vdda2"
+set ::env(GND_NETS) "vssd1 vssd2 vssa1 vssa2"
+#
+set ::env(VDD_PIN) "vccd1"
+set ::env(GND_PIN) "vssd1"
+
+set ::env(GLB_RT_OBS) " li1   150 2100  833.1  2516.54,\
+	                met1  150 2100  833.1  2516.54,\
+	                met2  150 2100  833.1  2516.54,\
+                        met3  150 2100  833.1  2516.54,\
+                        li1   950 2100 1633.1  2516.54,\
+                        met1  950 2100 1633.1  2516.54,\
+                        met2  950 2100 1633.1  2516.54,\
+                        met3  950 2100 1633.1  2516.54,\
+                        li1   150 3000  833.1 3416.54,\
+                        met1  150 3000  833.1 3416.54,\
+                        met2  150 3000  833.1 3416.54,\
+                        met3  150 3000  833.1 3416.54,\
+                        li1   950 3000 1633.1 3416.54,\
+                        met1  950 3000 1633.1 3416.54,\
+                        met2  950 3000 1633.1 3416.54,\
+                        met3  950 3000 1633.1 3416.54,\
+                        li1  150  1400  833.1  1816.54,\
+                        met1 150  1400  833.1  1816.54,\
+                        met2 150  1400  833.1  1816.54,\
+                        met3 150  1400  833.1  1816.54,\
+                        li1  150  800  833.1   1216.54,\
+                        met1 150  800  833.1   1216.54,\
+                        met2 150  800  833.1   1216.54,\
+                        met3 150  800  833.1   1216.54,\
+                        li1  150  200  833.1   616.54,\
+                        met1 150  200  833.1   616.54,\
+                        met2 150  200  833.1   616.54,\
+                        met3 150  200  833.1   616.54,\
+	                met5  0 0 2920 3520"
+
+set ::env(FP_PDN_POWER_STRAPS) "vccd1 vssd1 1, vccd2 vssd2 0, vdda1 vssa1 0, vdda2 vssa2 0"
+
+set ::env(FP_PDN_MACRO_HOOKS) " \
+	u_intercon vccd1 vssd1 \
+	u_pinmux vccd1 vssd1 \
+	u_qspi_master vccd1 vssd1 \
+	u_riscv_top vccd1 vssd1 \
+	u_tsram0_2kb vccd1 vssd1 \
+	u_icache_2kb vccd1 vssd1 \
+	u_dcache_2kb vccd1 vssd1 \
+	u_mbist vccd1 vssd1 \
+	u_sram0_2kb vccd1 vssd1 \
+	u_sram1_2kb vccd1 vssd1 \
+	u_sram2_2kb vccd1 vssd1 \
+	u_sram3_2kb vccd1 vssd1 \
+	u_uart_i2c_usb_spi vccd1 vssd1 \
+	u_wb_host vccd1 vssd1 "
+
+
+# The following is because there are no std cells in the example wrapper project.
+set ::env(SYNTH_TOP_LEVEL) 1
+set ::env(PL_RANDOM_GLB_PLACEMENT) 1
+
+set ::env(PL_RESIZER_DESIGN_OPTIMIZATIONS) 0
+set ::env(PL_RESIZER_TIMING_OPTIMIZATIONS) 0
+set ::env(PL_RESIZER_BUFFER_INPUT_PORTS) 0
+set ::env(PL_RESIZER_BUFFER_OUTPUT_PORTS) 0
+
+set ::env(FP_PDN_ENABLE_RAILS) 0
+
+set ::env(DIODE_INSERTION_STRATEGY) 0
+set ::env(FILL_INSERTION) 0
+set ::env(TAP_DECAP_INSERTION) 0
+set ::env(CLOCK_TREE_SYNTH) 0
+
+set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_MAGIC_DRC) "0"
+set ::env(QUIT_ON_NEGATIVE_WNS) "0"
+set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
+set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
+set ::env(QUIT_ON_TR_DRC) "0"
+
+set ::env(FP_PDN_IRDROP) "1"
+set ::env(FP_PDN_HORIZONTAL_HALO) "10"
+set ::env(FP_PDN_VERTICAL_HALO) "10"
+
+set ::env(FP_PDN_VOFFSET) "5"
+set ::env(FP_PDN_VPITCH) "80"
+set ::env(FP_PDN_VSPACING) "15.5"
+set ::env(FP_PDN_VWIDTH) "3.1"
+
+set ::env(FP_PDN_HOFFSET) "10"
+set ::env(FP_PDN_HPITCH) "120"
+set ::env(FP_PDN_HSPACING) "10"
+set ::env(FP_PDN_HWIDTH) "3.1"
+
+
+
diff --git a/openlane/user_project_wrapper/gen_pdn.tcl b/openlane/user_project_wrapper/gen_pdn.tcl
new file mode 100644
index 0000000..94bd008
--- /dev/null
+++ b/openlane/user_project_wrapper/gen_pdn.tcl
@@ -0,0 +1,50 @@
+# 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
+
+
+read_lef $::env(MERGED_LEF_UNPADDED)
+read_def $::env(CURRENT_DEF)
+
+set ::env(_SPACING) 1.7
+set ::env(_WIDTH) 3
+
+set power_domains [list {vccd1 vssd1 1} {vccd2 vssd2 0} {vdda1 vssa1 0} {vdda2 vssa2 0}]
+
+set ::env(_VDD_NET_NAME) vccd1
+set ::env(_GND_NET_NAME) vssd1
+set ::env(_WITH_STRAPS) 1
+set ::env(_V_OFFSET) 14
+set ::env(_H_OFFSET) $::env(_V_OFFSET)
+set ::env(_V_PITCH) 80
+set ::env(_H_PITCH) 80
+set ::env(_V_PDN_OFFSET) 0
+set ::env(_H_PDN_OFFSET) 0
+
+foreach domain $power_domains {
+	set ::env(_VDD_NET_NAME) [lindex $domain 0]
+	set ::env(_GND_NET_NAME) [lindex $domain 1]
+	set ::env(_WITH_STRAPS)  [lindex $domain 2]
+
+	pdngen $::env(PDN_CFG) -verbose
+
+	set ::env(_V_OFFSET) \
+		[expr $::env(_V_OFFSET) + 2*($::env(_WIDTH)+$::env(_SPACING))]
+	set ::env(_H_OFFSET) \
+		[expr $::env(_H_OFFSET) + 2*($::env(_WIDTH)+$::env(_SPACING))]
+	set ::env(_V_PDN_OFFSET) [expr $::env(_V_PDN_OFFSET)+6*$::env(_WIDTH)]
+	set ::env(_H_PDN_OFFSET) [expr $::env(_H_PDN_OFFSET)+6*$::env(_WIDTH)]
+}
+
+write_def $::env(SAVE_DEF)
diff --git a/openlane/user_project_wrapper/interactive.mpw4.tcl b/openlane/user_project_wrapper/interactive.mpw4.tcl
new file mode 100644
index 0000000..1c24305
--- /dev/null
+++ b/openlane/user_project_wrapper/interactive.mpw4.tcl
@@ -0,0 +1,394 @@
+#!/usr/bin/tclsh
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+# Copyright 2020 Efabless Corporation
+# Copyright 2020 Sylvain Munaut
+#
+# 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
+
+package require openlane;
+
+
+proc run_placement_step {args} {
+    if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
+        set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
+    }
+
+    run_placement
+}
+
+proc run_placement {args} {
+	puts_info "Running Placement..."
+# |----------------------------------------------------|
+# |----------------   3. PLACEMENT   ------------------|
+# |----------------------------------------------------|
+	set ::env(CURRENT_STAGE) placement
+
+    if { [info exists ::env(PL_TARGET_DENSITY_CELLS)] } {
+        set old_pl_target_density $::env(PL_TARGET_DENSITY)
+        set ::env(PL_TARGET_DENSITY) $::env(PL_TARGET_DENSITY_CELLS)
+    }
+
+    if { $::env(PL_RANDOM_GLB_PLACEMENT) } {
+        # useful for very tiny designs
+        random_global_placement
+    } else {
+        global_placement_or
+    }
+
+    if { [info exists ::env(PL_TARGET_DENSITY_CELLS)] } {
+        set ::env(PL_TARGET_DENSITY) $old_pl_target_density
+    }
+
+    run_resizer_design
+
+    if { [info exists ::env(DONT_BUFFER_PORTS) ]} {
+        remove_buffers
+    }
+    detailed_placement_or
+    scrot_klayout -layout $::env(CURRENT_DEF)
+}
+
+
+proc run_cts_step {args} {
+    if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
+        set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
+    }
+
+    run_cts
+    run_resizer_timing
+}
+
+proc run_routing_step {args} {
+    if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
+        set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
+    }
+    run_routing
+}
+
+proc run_diode_insertion_2_5_step {args} {
+    if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
+        set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
+    }
+	if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+		run_antenna_check
+		heal_antenna_violators; # modifies the routed DEF
+	}
+
+}
+
+proc run_power_pins_insertion_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(POWER_PINS_INSERTION_CURRENT_DEF) ] } {
+        set ::env(POWER_PINS_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(POWER_PINS_INSERTION_CURRENT_DEF)
+    }
+    if { $::env(LVS_INSERT_POWER_PINS) } {
+		write_powered_verilog
+		set_netlist $::env(lvs_result_file_tag).powered.v
+    }
+
+}
+
+
+proc run_lvs_step {{ lvs_enabled 1 }} {
+    if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
+        set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
+    }
+	if { $lvs_enabled } {
+		run_magic_spice_export
+		run_lvs; # requires run_magic_spice_export
+	}
+
+}
+
+proc run_drc_step {{ drc_enabled 1 }} {
+    if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
+        set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
+    }
+	if { $drc_enabled } {
+		run_magic_drc
+		run_klayout_drc
+	}
+}
+
+proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
+    if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
+        set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
+    }
+	if { $antenna_check_enabled } {
+		run_antenna_check
+	}
+}
+
+
+proc gen_pdn {args} {
+    puts_info "Generating PDN..."
+    TIMER::timer_start
+	
+    set ::env(SAVE_DEF) [index_file $::env(pdn_tmp_file_tag).def]
+    set ::env(PGA_RPT_FILE) [index_file $::env(pdn_report_file_tag).pga.rpt]
+
+    try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/pdn.tcl \
+	|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(pdn_log_file_tag).log 0]
+
+
+    TIMER::timer_stop
+    exec echo "[TIMER::get_runtime]" >> [index_file $::env(pdn_log_file_tag)_runtime.txt 0]
+
+    quit_on_unconnected_pdn_nodes
+
+    set_def $::env(SAVE_DEF)
+}
+
+proc run_power_grid_generation {args} {
+
+	if {[info exists ::env(FP_PDN_POWER_STRAPS)]} {
+	     set power_domains [split $::env(FP_PDN_POWER_STRAPS) ","]
+	}
+
+	# internal macros power connections 
+	if {[info exists ::env(FP_PDN_MACRO_HOOKS)]} {
+		set macro_hooks [dict create]
+		set pdn_hooks [split $::env(FP_PDN_MACRO_HOOKS) ","]
+		foreach pdn_hook $pdn_hooks {
+			set instance_name [lindex $pdn_hook 0]
+			set power_net [lindex $pdn_hook 1]
+			set ground_net [lindex $pdn_hook 2]
+			dict append macro_hooks $instance_name [subst {$power_net $ground_net}]
+		}
+		
+		set power_net_indx [lsearch $::env(VDD_NETS) $power_net]
+		set ground_net_indx [lsearch $::env(GND_NETS) $ground_net]
+
+		# make sure that the specified power domains exist.
+		if { $power_net_indx == -1  || $ground_net_indx == -1 || $power_net_indx != $ground_net_indx } {
+			puts_err "Can't find $power_net and $ground_net domain. \
+			Make sure that both exist in $::env(VDD_NETS) and $::env(GND_NETS)." 
+		} 
+	}
+	
+	# generate multiple power grids per pair of (VDD,GND)
+	# offseted by WIDTH + SPACING
+	foreach domain $power_domains {
+		set ::env(VDD_NET)       [lindex $domain 0]
+	        set ::env(GND_NET)       [lindex $domain 1]
+	        set ::env(_WITH_STRAPS)  [lindex $domain 2]
+
+	        puts_info "Connecting Power: $::env(VDD_NET) & $::env(GND_NET) to All internal macros."
+		# internal macros power connections
+		set ::env(FP_PDN_MACROS) ""
+		if { $::env(FP_PDN_ENABLE_MACROS_GRID) == 1 } {
+			# if macros connections to power are explicitly set
+			# default behavoir macro pins will be connected to the first power domain
+			if { [info exists ::env(FP_PDN_MACRO_HOOKS)] } {
+				set ::env(FP_PDN_ENABLE_MACROS_GRID) 0
+				foreach {instance_name hooks} $macro_hooks {
+					set power [lindex $hooks 0]
+					set ground [lindex $hooks 1]			 
+					if { $power == $::env(VDD_NET) && $ground == $::env(GND_NET) } {
+						set ::env(FP_PDN_ENABLE_MACROS_GRID) 1
+                                                set ::env(FP_PDN_IRDROP) "1"
+						puts_info "Connecting $instance_name to $power and $ground nets."
+						lappend ::env(FP_PDN_MACROS) $instance_name
+					}
+				}
+			} 
+		} else {
+			puts_warn "All internal macros will not be connected to power $::env(VDD_NET) & $::env(GND_NET)."
+		}
+		
+		gen_pdn
+
+		set ::env(FP_PDN_ENABLE_RAILS) 0
+		set ::env(FP_PDN_ENABLE_MACROS_GRID) 0
+                set ::env(FP_PDN_IRDROP) "0"
+
+		# allow failure until open_pdks is up to date...
+		catch {set ::env(FP_PDN_VOFFSET) [expr $::env(FP_PDN_VOFFSET)+$::env(FP_PDN_VWIDTH)+$::env(FP_PDN_VSPACING)]}
+		catch {set ::env(FP_PDN_HOFFSET) [expr $::env(FP_PDN_HOFFSET)+$::env(FP_PDN_HWIDTH)+$::env(FP_PDN_HSPACING)]}
+
+		catch {set ::env(FP_PDN_CORE_RING_VOFFSET) \
+			[expr $::env(FP_PDN_CORE_RING_VOFFSET)\
+			+2*($::env(FP_PDN_CORE_RING_VWIDTH)\
+			+max($::env(FP_PDN_CORE_RING_VSPACING), $::env(FP_PDN_CORE_RING_HSPACING)))]}
+		catch {set ::env(FP_PDN_CORE_RING_HOFFSET) [expr $::env(FP_PDN_CORE_RING_HOFFSET)\
+			+2*($::env(FP_PDN_CORE_RING_HWIDTH)+\
+			max($::env(FP_PDN_CORE_RING_VSPACING), $::env(FP_PDN_CORE_RING_HSPACING)))]}
+		puts "FP_PDN_VOFFSET: $::env(FP_PDN_VOFFSET)"
+		puts "FP_PDN_HOFFSET: $::env(FP_PDN_HOFFSET)"
+		puts "FP_PDN_CORE_RING_VOFFSET: $::env(FP_PDN_CORE_RING_VOFFSET)"
+		puts "FP_PDN_CORE_RING_HOFFSET: $::env(FP_PDN_CORE_RING_HOFFSET)"
+
+	}
+	set ::env(FP_PDN_ENABLE_RAILS) 1
+}
+
+
+proc run_floorplan {args} {
+		puts_info "Running Floorplanning..."
+		# |----------------------------------------------------|
+		# |----------------   2. FLOORPLAN   ------------------|
+		# |----------------------------------------------------|
+		#
+		# intial fp
+		init_floorplan
+
+
+		# place io
+		if { [info exists ::env(FP_PIN_ORDER_CFG)] } {
+				place_io_ol
+		} else {
+			if { [info exists ::env(FP_CONTEXT_DEF)] && [info exists ::env(FP_CONTEXT_LEF)] } {
+				place_io
+				global_placement_or
+				place_contextualized_io \
+					-lef $::env(FP_CONTEXT_LEF) \
+					-def $::env(FP_CONTEXT_DEF)
+			} else {
+				place_io
+			}
+		}
+
+		apply_def_template
+
+		if { [info exist ::env(EXTRA_LEFS)] } {
+			if { [info exist ::env(MACRO_PLACEMENT_CFG)] } {
+				file copy -force $::env(MACRO_PLACEMENT_CFG) $::env(TMP_DIR)/macro_placement.cfg
+				manual_macro_placement f
+			} else {
+				global_placement_or
+				basic_macro_placement
+			}
+		}
+
+		# tapcell
+		tap_decap_or
+		scrot_klayout -layout $::env(CURRENT_DEF)
+		# power grid generation
+		run_power_grid_generation
+}
+
+
+proc run_flow {args} {
+       set script_dir [file dirname [file normalize [info script]]]
+
+		set options {
+		{-design required}
+		{-save_path optional}
+		{-no_lvs optional}
+	    {-no_drc optional}
+	    {-no_antennacheck optional}
+	}
+	set flags {-save}
+	parse_key_args "run_flow" args arg_values $options flags_map $flags -no_consume
+
+	prep {*}$args
+
+        set LVS_ENABLED 1
+        set DRC_ENABLED 0
+        set ANTENNACHECK_ENABLED 1
+
+        set steps [dict create \
+		"synthesis" {run_synthesis "" } \
+                "floorplan" {run_floorplan ""} \
+                "placement" {run_placement_step ""} \
+                "cts" {run_cts_step ""} \
+                "routing" {run_routing_step ""} \
+                "diode_insertion" {run_diode_insertion_2_5_step ""} \
+                "power_pins_insertion" {run_power_pins_insertion_step ""} \
+                "gds_magic" {run_magic ""} \
+                "gds_drc_klayout" {run_klayout ""} \
+                "gds_xor_klayout" {run_klayout_gds_xor ""} \
+                "lvs" "run_lvs_step $LVS_ENABLED" \
+                "drc" "run_drc_step $DRC_ENABLED" \
+                "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED" \
+                "cvc" {run_lef_cvc}
+        ]
+
+       set_if_unset arg_values(-to) "cvc";
+
+       if {  [info exists ::env(CURRENT_STEP) ] } {
+           puts "\[INFO\]:Picking up where last execution left off"
+           puts [format "\[INFO\]:Current stage is %s " $::env(CURRENT_STEP)]
+       } else {
+           set ::env(CURRENT_STEP) "synthesis";
+       }
+       set_if_unset arg_values(-from) $::env(CURRENT_STEP);
+       set exe 0;
+       dict for {step_name step_exe} $steps {
+           if { [ string equal $arg_values(-from) $step_name ] } {
+               set exe 1;
+           }
+
+           if { $exe } {
+               # For when it fails
+               set ::env(CURRENT_STEP) $step_name
+               [lindex $step_exe 0] [lindex $step_exe 1] ;
+           }
+
+           if { [ string equal $arg_values(-to) $step_name ] } {
+               set exe 0:
+               break;
+           }
+
+       }
+
+       # for when it resumes
+       set steps_as_list [dict keys $steps]
+       set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
+       set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
+
+	if {  [info exists flags_map(-save) ] } {
+		if { ! [info exists arg_values(-save_path)] } {
+			set arg_values(-save_path) ""
+		}
+		save_views 	-lef_path $::env(magic_result_file_tag).lef \
+			-def_path $::env(CURRENT_DEF) \
+			-gds_path $::env(magic_result_file_tag).gds \
+			-mag_path $::env(magic_result_file_tag).mag \
+			-maglef_path $::env(magic_result_file_tag).lef.mag \
+			-spice_path $::env(magic_result_file_tag).spice \
+			-spef_path $::env(CURRENT_SPEF) \
+			-verilog_path $::env(CURRENT_NETLIST) \
+			-save_path $arg_values(-save_path) \
+			-tag $::env(RUN_TAG)
+	}
+
+
+	calc_total_runtime
+	save_state
+	generate_final_summary_report
+	
+	check_timing_violations
+
+	puts_success "Flow Completed Without Fatal Errors."
+
+}
+
+run_flow {*}$argv
diff --git a/openlane/user_project_wrapper/interactive.tcl b/openlane/user_project_wrapper/interactive.tcl
new file mode 100644
index 0000000..45668cd
--- /dev/null
+++ b/openlane/user_project_wrapper/interactive.tcl
@@ -0,0 +1,438 @@
+#!/usr/bin/tclsh
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+# Copyright 2020 Efabless Corporation
+# Copyright 2020 Sylvain Munaut
+#
+# 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
+
+package require openlane;
+
+proc run_placement_step {args} {
+    if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
+        set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
+    }
+
+    run_placement
+}
+
+proc run_cts_step {args} {
+    if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
+        set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
+    }
+
+    run_cts
+    run_resizer_timing
+}
+
+proc run_routing_step {args} {
+    if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
+        set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
+    }
+    run_routing
+}
+
+proc run_diode_insertion_2_5_step {args} {
+    if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
+        set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
+    }
+	if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+		run_antenna_check
+		heal_antenna_violators; # modifies the routed DEF
+	}
+
+}
+
+proc run_lvs_step {{ lvs_enabled 1 }} {
+    if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
+        set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
+    }
+	if { $lvs_enabled } {
+		run_magic_spice_export
+		run_lvs; # requires run_magic_spice_export
+	}
+
+}
+
+proc run_drc_step {{ drc_enabled 1 }} {
+    if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
+        set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
+    }
+	if { $drc_enabled } {
+		run_magic_drc
+		run_klayout_drc
+	}
+}
+
+proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
+    if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
+        set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
+    }
+	if { $antenna_check_enabled } {
+		run_antenna_check
+	}
+}
+
+proc run_eco_step {args} {
+	if {  $::env(ECO_ENABLE) == 1 } {
+        run_eco
+    }
+}
+
+proc save_final_views {args} {
+	set options {
+		{-save_path optional}
+	}
+	set flags {}
+	parse_key_args "save_final_views" args arg_values $options flags_map $flags
+
+	set arg_list [list]
+
+	# If they don't exist, save_views will simply not copy them
+	lappend arg_list -lef_path $::env(finishing_results)/$::env(DESIGN_NAME).lef
+	lappend arg_list -gds_path $::env(finishing_results)/$::env(DESIGN_NAME).gds
+	lappend arg_list -mag_path $::env(finishing_results)/$::env(DESIGN_NAME).mag
+	lappend arg_list -maglef_path $::env(finishing_results)/$::env(DESIGN_NAME).lef.mag
+	lappend arg_list -spice_path $::env(finishing_results)/$::env(DESIGN_NAME).spice
+	
+	# Guaranteed to have default values
+	lappend arg_list -def_path $::env(CURRENT_DEF)
+	lappend arg_list -verilog_path $::env(CURRENT_NETLIST)
+
+	# Not guaranteed to have default values
+	if { [info exists ::env(SPEF_TYPICAL)] } {
+		lappend arg_list -spef_path $::env(SPEF_TYPICAL)
+	}
+	if { [info exists ::env(CURRENT_SDF)] } {
+		lappend arg_list -sdf_path $::env(CURRENT_SDF)
+	}
+	if { [info exists ::env(CURRENT_SDC)] } {
+		lappend arg_list -sdc_path $::env(CURRENT_SDC)
+	}
+
+	# Add the path if it exists...
+	if { [info exists arg_values(-save_path) ] } {
+		lappend arg_list -save_path $arg_values(-save_path)
+	}
+
+	# Aaand fire!
+	save_views {*}$arg_list
+
+}
+
+proc run_post_run_hooks {} {
+	if { [file exists $::env(DESIGN_DIR)/hooks/post_run.py]} {
+		puts_info "Running post run hook"
+		set result [exec $::env(OPENROAD_BIN) -python $::env(DESIGN_DIR)/hooks/post_run.py]
+		puts_info "$result"
+	} else {
+		puts_info "hooks/post_run.py not found, skipping"
+	}
+}
+
+
+
+
+proc gen_pdn {args} {
+    puts_info "Generating PDN..."
+    TIMER::timer_start
+	
+    set ::env(SAVE_DEF) [index_file $::env(floorplan_tmpfiles).def]
+    set ::env(PGA_RPT_FILE) [index_file $::env(floorplan_tmpfiles).pga.rpt]
+
+    run_openroad_script $::env(SCRIPTS_DIR)/openroad/pdn.tcl \
+        |& -indexed_log [index_file $::env(floorplan_logs)/pdn.log]
+
+
+    TIMER::timer_stop
+    exec echo "[TIMER::get_runtime]" | python3 $::env(SCRIPTS_DIR)/write_runtime.py "pdn generation - openroad"
+
+    quit_on_unconnected_pdn_nodes
+
+    set_def $::env(SAVE_DEF)
+}
+
+proc run_power_grid_generation {args} {
+
+	if {[info exists ::env(FP_PDN_POWER_STRAPS)]} {
+	     set power_domains [split $::env(FP_PDN_POWER_STRAPS) ","]
+	}
+
+	# internal macros power connections 
+	if {[info exists ::env(FP_PDN_MACRO_HOOKS)]} {
+		set macro_hooks [dict create]
+		set pdn_hooks [split $::env(FP_PDN_MACRO_HOOKS) ","]
+		foreach pdn_hook $pdn_hooks {
+			set instance_name [lindex $pdn_hook 0]
+			set power_net [lindex $pdn_hook 1]
+			set ground_net [lindex $pdn_hook 2]
+			dict append macro_hooks $instance_name [subst {$power_net $ground_net}]
+		}
+		
+		set power_net_indx [lsearch $::env(VDD_NETS) $power_net]
+		set ground_net_indx [lsearch $::env(GND_NETS) $ground_net]
+
+		# make sure that the specified power domains exist.
+		if { $power_net_indx == -1  || $ground_net_indx == -1 || $power_net_indx != $ground_net_indx } {
+			puts_err "Can't find $power_net and $ground_net domain. \
+			Make sure that both exist in $::env(VDD_NETS) and $::env(GND_NETS)." 
+		} 
+	}
+	
+	# generate multiple power grids per pair of (VDD,GND)
+	# offseted by WIDTH + SPACING
+	foreach domain $power_domains {
+		set ::env(VDD_NET)       [lindex $domain 0]
+	        set ::env(GND_NET)       [lindex $domain 1]
+	        set ::env(_WITH_STRAPS)  [lindex $domain 2]
+
+	        puts_info "Connecting Power: $::env(VDD_NET) & $::env(GND_NET) to All internal macros."
+		# internal macros power connections
+		set ::env(FP_PDN_MACROS) ""
+		if { $::env(FP_PDN_ENABLE_MACROS_GRID) == 1 } {
+			# if macros connections to power are explicitly set
+			# default behavoir macro pins will be connected to the first power domain
+			if { [info exists ::env(FP_PDN_MACRO_HOOKS)] } {
+				set ::env(FP_PDN_ENABLE_MACROS_GRID) 0
+				foreach {instance_name hooks} $macro_hooks {
+					set power [lindex $hooks 0]
+					set ground [lindex $hooks 1]			 
+					if { $power == $::env(VDD_NET) && $ground == $::env(GND_NET) } {
+						set ::env(FP_PDN_ENABLE_MACROS_GRID) 1
+                                                set ::env(FP_PDN_IRDROP) "1"
+						puts_info "Connecting $instance_name to $power and $ground nets."
+						lappend ::env(FP_PDN_MACROS) $instance_name
+					}
+				}
+			} 
+		} else {
+			puts_warn "All internal macros will not be connected to power $::env(VDD_NET) & $::env(GND_NET)."
+		}
+		
+		gen_pdn
+
+		set ::env(FP_PDN_ENABLE_RAILS) 0
+		set ::env(FP_PDN_ENABLE_MACROS_GRID) 0
+                set ::env(FP_PDN_IRDROP) "0"
+
+		# allow failure until open_pdks is up to date...
+		catch {set ::env(FP_PDN_VOFFSET) [expr $::env(FP_PDN_VOFFSET)+$::env(FP_PDN_VWIDTH)+$::env(FP_PDN_VSPACING)]}
+		catch {set ::env(FP_PDN_HOFFSET) [expr $::env(FP_PDN_HOFFSET)+$::env(FP_PDN_HWIDTH)+$::env(FP_PDN_HSPACING)]}
+
+		catch {set ::env(FP_PDN_CORE_RING_VOFFSET) \
+			[expr $::env(FP_PDN_CORE_RING_VOFFSET)\
+			+2*($::env(FP_PDN_CORE_RING_VWIDTH)\
+			+max($::env(FP_PDN_CORE_RING_VSPACING), $::env(FP_PDN_CORE_RING_HSPACING)))]}
+		catch {set ::env(FP_PDN_CORE_RING_HOFFSET) [expr $::env(FP_PDN_CORE_RING_HOFFSET)\
+			+2*($::env(FP_PDN_CORE_RING_HWIDTH)+\
+			max($::env(FP_PDN_CORE_RING_VSPACING), $::env(FP_PDN_CORE_RING_HSPACING)))]}
+		puts "FP_PDN_VOFFSET: $::env(FP_PDN_VOFFSET)"
+		puts "FP_PDN_HOFFSET: $::env(FP_PDN_HOFFSET)"
+		puts "FP_PDN_CORE_RING_VOFFSET: $::env(FP_PDN_CORE_RING_VOFFSET)"
+		puts "FP_PDN_CORE_RING_HOFFSET: $::env(FP_PDN_CORE_RING_HOFFSET)"
+
+	}
+	set ::env(FP_PDN_ENABLE_RAILS) 1
+}
+
+
+proc run_floorplan {args} {
+	puts_info "Running Floorplanning..."
+	# |----------------------------------------------------|
+	# |----------------   2. FLOORPLAN   ------------------|
+	# |----------------------------------------------------|
+	#
+	# intial fp
+	init_floorplan
+
+	# check for deprecated io variables
+	if { [info exists ::env(FP_IO_HMETAL)]} {
+		set ::env(FP_IO_HLAYER) [lindex $::env(TECH_METAL_LAYERS) [expr {$::env(FP_IO_HMETAL) - 1}]]
+		puts_warn "You're using FP_IO_HMETAL in your configuration, which is a deprecated variable that will be removed in the future."
+		puts_warn "We recommend you update your configuration as follows:"
+		puts_warn "\tset ::env(FP_IO_HLAYER) {$::env(FP_IO_HLAYER)}"
+	}
+
+	if { [info exists ::env(FP_IO_VMETAL)]} {
+		set ::env(FP_IO_VLAYER) [lindex $::env(TECH_METAL_LAYERS) [expr {$::env(FP_IO_VMETAL) - 1}]]
+		puts_warn "You're using FP_IO_VMETAL in your configuration, which is a deprecated variable that will be removed in the future."
+		puts_warn "We recommend you update your configuration as follows:"
+		puts_warn "\tset ::env(FP_IO_VLAYER) {$::env(FP_IO_VLAYER)}"
+	}
+
+
+	# place io
+	if { [info exists ::env(FP_PIN_ORDER_CFG)] } {
+		place_io_ol
+	} else {
+		if { [info exists ::env(FP_CONTEXT_DEF)] && [info exists ::env(FP_CONTEXT_LEF)] } {
+			place_io
+			global_placement_or
+			place_contextualized_io \
+				-lef $::env(FP_CONTEXT_LEF) \
+				-def $::env(FP_CONTEXT_DEF)
+		} else {
+			place_io
+		}
+	}
+
+	apply_def_template
+
+	if { [info exist ::env(EXTRA_LEFS)] } {
+		if { [info exist ::env(MACRO_PLACEMENT_CFG)] } {
+			file copy -force $::env(MACRO_PLACEMENT_CFG) $::env(placement_tmpfiles)/macro_placement.cfg
+			manual_macro_placement f
+		} else {
+			global_placement_or
+			basic_macro_placement
+		}
+	}
+
+	tap_decap_or
+
+	scrot_klayout -layout $::env(CURRENT_DEF) $::env(floorplan_logs)/screenshot.log
+
+	run_power_grid_generation
+}
+
+
+proc run_flow {args} {
+	set options {
+		{-design required}
+		{-from optional}
+		{-to optional}
+		{-save_path optional}
+		{-override_env optional}
+	}
+	set flags {-save -run_hooks -no_lvs -no_drc -no_antennacheck }
+	parse_key_args "run_non_interactive_mode" args arg_values $options flags_map $flags -no_consume
+	prep {*}$args
+    # signal trap SIGINT save_state;
+
+	if { [info exists arg_values(-override_env)] } {
+		set env_overrides [split $arg_values(-override_env) ','] 
+		foreach override $env_overrides {
+			set kva [split $override '=']
+			set key [lindex $kva 0]
+			set value [lindex $kva 1]
+			set ::env(${key}) $value
+		}
+	}
+
+    set LVS_ENABLED 1
+    set DRC_ENABLED 0
+    set ANTENNACHECK_ENABLED 1
+
+    set steps [dict create \
+		"synthesis" {run_synthesis "" } \
+		"floorplan" {run_floorplan ""} \
+		"placement" {run_placement_step ""} \
+		"cts" {run_cts_step ""} \
+		"routing" {run_routing_step ""}\
+                "eco" {run_eco_step ""} \
+		"diode_insertion" {run_diode_insertion_2_5_step ""} \
+		"gds_magic" {run_magic ""} \
+		"gds_drc_klayout" {run_klayout ""} \
+		"gds_xor_klayout" {run_klayout_gds_xor ""} \
+		"lvs" "run_lvs_step $LVS_ENABLED" \
+		"drc" "run_drc_step $DRC_ENABLED" \
+		"antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED" \
+		"cvc" {run_lef_cvc}
+    ]
+
+    set_if_unset arg_values(-to) "cvc";
+
+	if {  [info exists ::env(CURRENT_STEP) ] } {
+        puts "\[INFO\]:Picking up where last execution left off"
+        puts [format "\[INFO\]:Current stage is %s " $::env(CURRENT_STEP)]
+    } else {
+        set ::env(CURRENT_STEP) "synthesis";
+    }
+
+    set_if_unset arg_values(-from) $::env(CURRENT_STEP);
+    set exe 0;
+    dict for {step_name step_exe} $steps {
+        if { [ string equal $arg_values(-from) $step_name ] } {
+            set exe 1;
+        }
+
+        if { $exe } {
+            # For when it fails
+            set ::env(CURRENT_STEP) $step_name
+            [lindex $step_exe 0] [lindex $step_exe 1] ;
+        }
+
+        if { [ string equal $arg_values(-to) $step_name ] } {
+            set exe 0:
+            break;
+        }
+
+    }
+
+    # for when it resumes
+    set steps_as_list [dict keys $steps]
+    set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
+    set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
+
+	# Saves to <RUN_DIR>/results/final
+	if { $::env(SAVE_FINAL_VIEWS) == "1" } {
+		save_final_views
+	}
+
+	# Saves to design directory or custom
+	if {  [info exists flags_map(-save) ] } {
+		if { ! [info exists arg_values(-save_path)] } {
+			set arg_values(-save_path) $::env(DESIGN_DIR)
+		}
+		save_final_views\
+			-save_path $arg_values(-save_path)\
+			-tag $::env(RUN_TAG)
+	}
+	calc_total_runtime
+	save_state
+	generate_final_summary_report
+	
+	check_timing_violations
+	
+	if { [info exists arg_values(-save_path)]\
+	    && $arg_values(-save_path) != "" } {
+	    set ::env(HOOK_OUTPUT_PATH) "[file normalize $arg_values(-save_path)]"
+	} else {
+	    set ::env(HOOK_OUTPUT_PATH) $::env(RESULTS_DIR)/final
+	}
+	
+	if {[info exists flags_map(-run_hooks)]} {
+		run_post_run_hooks
+	}
+	
+	puts_success "Flow complete."
+
+	show_warnings "Note that the following warnings have been generated:"
+
+}
+
+run_flow {*}$argv
diff --git a/openlane/user_project_wrapper/macro.cfg b/openlane/user_project_wrapper/macro.cfg
new file mode 100644
index 0000000..729781f
--- /dev/null
+++ b/openlane/user_project_wrapper/macro.cfg
@@ -0,0 +1,18 @@
+u_qspi_master           2225             700           N
+u_uart_i2c_usb_spi      2225            1400           N
+u_pinmux                2225            2300           N
+u_sram2_2kb             150             3000           N
+u_sram3_2kb             950             3000           N
+
+u_mbist                 150             2650           N
+u_sram0_2kb             150             2100           N
+u_sram1_2kb             950             2100           N
+
+u_riscv_top	        950	        450	       N
+u_dcache_2kb            150             1400           N
+u_icache_2kb            150             800            N
+u_tsram0_2kb            150             200            N
+
+
+u_intercon              1850            700            N
+u_wb_host               1450            100            N
diff --git a/openlane/user_project_wrapper/mod.tcl b/openlane/user_project_wrapper/mod.tcl
new file mode 100644
index 0000000..6eeebbe
--- /dev/null
+++ b/openlane/user_project_wrapper/mod.tcl
@@ -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: Modified by Dinesh Annayya <dinesha@opencores.org>
+
+
+set ::env(LIB_FASTEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ff_n40C_1v95.lib"
+set ::env(LIB_SLOWEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ss_100C_1v60.lib"
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8"
+set ::env(SYNTH_DRIVING_CELL_PIN) "Y"
+set ::env(SYNTH_CAP_LOAD) "17.65"
+set ::env(WIRE_RC_LAYER) "met1"
+
+#To disable empty filler cell black box get created
+#set link_make_black_boxes 0
+
+
+set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um
+define_corners wc bc
+read_liberty -corner bc $::env(LIB_FASTEST)
+read_liberty -corner wc $::env(LIB_SLOWEST)
+
+# Removing the decap and diode
+read_verilog ../../verilog/gl/clk_buf.v  
+link_design  clk_buf
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/clk_buf.v
+# Removing the decap and diode
+read_verilog  ../../verilog/gl/clk_skew_adjust.v  
+link_design  clk_skew_adjust
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/clk_skew_adjust.v
+
+# Removing the decap and diode
+read_verilog  ../../verilog/gl/glbl_cfg.v  
+link_design  glbl_cfg
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/glbl_cfg.v
+
+read_verilog  ../../verilog/gl/sdram.v  
+link_design  sdrc_top
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/sdram.v
+
+read_verilog  ../../verilog/gl/spi_master.v 
+link_design  spim_top 
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/spi_master.v
+
+read_verilog  ../../verilog/gl/syntacore.v  
+link_design  scr1_top_wb
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/syntacore.v
+
+read_verilog  ../../verilog/gl/uart_i2cm_usb.v  
+link_design  uart_i2c_usb_top
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/uart_i2cm_usb.v
+
+read_verilog  ../../verilog/gl/wb_host.v  
+link_design  wb_host
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/wb_host.v
+
+read_verilog  ../../verilog/gl/wb_interconnect.v
+link_design  wb_interconnect
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/wb_interconnect.v
+
+
+exit
diff --git a/openlane/user_project_wrapper/pdn_cfg.tcl b/openlane/user_project_wrapper/pdn_cfg.tcl
new file mode 100644
index 0000000..7813f95
--- /dev/null
+++ b/openlane/user_project_wrapper/pdn_cfg.tcl
@@ -0,0 +1,96 @@
+# Power nets
+
+if { ! [info exists ::env(VDD_NET)] } {
+	set ::env(VDD_NET) $::env(VDD_PIN)
+}
+
+if { ! [info exists ::env(GND_NET)] } {
+	set ::env(GND_NET) $::env(GND_PIN)
+}
+
+set ::power_nets $::env(VDD_NET)
+set ::ground_nets $::env(GND_NET)
+
+if { [info exists ::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS)] } {
+    if { $::env(FP_PDN_ENABLE_GLOBAL_CONNECTIONS) == 1 } {
+        foreach power_pin $::env(STD_CELL_POWER_PINS) {
+            add_global_connection -net $::env(VDD_NET) -inst_pattern .* -pin_pattern $power_pin -power
+        }
+        foreach ground_pin $::env(STD_CELL_GROUND_PINS) {
+            add_global_connection -net $::env(GND_NET) -inst_pattern .* -pin_pattern $ground_pin -ground
+        }
+    }
+}
+
+set_voltage_domain -name CORE -power $::env(VDD_NET) -ground $::env(GND_NET)
+
+# Assesses whether the deisgn is the core of the chip or not based on the 
+# value of $::env(DESIGN_IS_CORE) and uses the appropriate stdcell section
+if { $::env(DESIGN_IS_CORE) == 1 } {
+    # Used if the design is the core of the chip
+    define_pdn_grid -name stdcell_grid -starts_with POWER -voltage_domain CORE -pins [subst {$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)}]
+    if { $::env(_WITH_STRAPS) } {
+        add_pdn_stripe -grid stdcell_grid -layer $::env(FP_PDN_LOWER_LAYER) -width $::env(FP_PDN_VWIDTH) -pitch $::env(FP_PDN_VPITCH) -offset $::env(FP_PDN_VOFFSET) -starts_with POWER
+        add_pdn_stripe -grid stdcell_grid -layer $::env(FP_PDN_UPPER_LAYER) -width $::env(FP_PDN_HWIDTH) -pitch $::env(FP_PDN_HPITCH) -offset $::env(FP_PDN_HOFFSET) -starts_with POWER
+    } 
+    add_pdn_connect -grid stdcell_grid -layers [subst {$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)}]
+} else {
+    # Used if the design is a macro in the core
+    define_pdn_grid -name stdcell_grid -starts_with POWER -voltage_domain CORE -pins $::env(FP_PDN_LOWER_LAYER)
+    add_pdn_stripe -grid stdcell_grid -layer $::env(FP_PDN_LOWER_LAYER) -width $::env(FP_PDN_VWIDTH) -pitch $::env(FP_PDN_VPITCH) -offset $::env(FP_PDN_VOFFSET) -starts_with POWER
+}
+
+# Adds the standard cell rails if enabled.
+if { $::env(FP_PDN_ENABLE_RAILS) == 1 } {
+    add_pdn_stripe -grid stdcell_grid -layer $::env(FP_PDN_RAILS_LAYER) -width $::env(FP_PDN_RAIL_WIDTH) -followpins -starts_with POWER
+    add_pdn_connect -grid stdcell_grid -layers [subst {$::env(FP_PDN_RAILS_LAYER) $::env(FP_PDN_LOWER_LAYER)}]
+} 
+
+
+# Adds the core ring if enabled.
+if { $::env(FP_PDN_CORE_RING) == 1 } {
+    add_pdn_ring -grid stdcell_grid -layer [subst {$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)}]  \
+                     -widths [subst {$::env(FP_PDN_CORE_RING_VWIDTH) $::env(FP_PDN_CORE_RING_HWIDTH)}] \
+                     -spacings [subst {$::env(FP_PDN_CORE_RING_VSPACING) $::env(FP_PDN_CORE_RING_HSPACING)}] \
+                     -core_offset [subst {$::env(FP_PDN_CORE_RING_VOFFSET) $::env(FP_PDN_CORE_RING_HOFFSET)}]
+}
+
+# A general macro that follows the premise of the set heirarchy. You may want to modify this or add other macro configs
+# The macro power pin names are assumed to match the VDD and GND net names 
+# TODO: parameterize the power pin names 
+set macro {
+    orient {R0 R180 MX MY R90 R270 MXR90 MYR90}
+    power_pins $::env(VDD_NET)
+    ground_pins $::env(GND_NET)
+    blockages $::env(MACRO_BLOCKAGES_LAYER)
+    straps {
+    }
+    connect {{$::env(FP_PDN_LOWER_LAYER)_PIN_ver $::env(FP_PDN_UPPER_LAYER)}}
+}
+
+if { $::env(FP_PDN_ENABLE_MACROS_GRID) == 1} {
+    if { [llength $::env(FP_PDN_MACROS)] > 0 } {
+        # generate automatically per instance:
+        foreach macro_instance $::env(FP_PDN_MACROS) {
+            set macro_instance_grid [subst $macro] 
+            dict append $macro_instance_grid instance $macro_instance
+            set ::halo [list $::env(FP_PDN_HORIZONTAL_HALO) $::env(FP_PDN_VERTICAL_HALO)]
+            pdngen::specify_grid macro [subst $macro_instance_grid]
+        }
+    } else {
+        set ::halo [list $::env(FP_PDN_HORIZONTAL_HALO) $::env(FP_PDN_VERTICAL_HALO)]
+        pdngen::specify_grid macro [subst $macro]
+    }
+    # CAN NOT ENABLE THE TCL COMMAND BECAUSE THERE IS NO ARGUMENT FOR SPECIFYING THE POWER AND GROUND PIN NAMES ON THE MACRO
+    # define_pdn_grid -macro -orient {R0 R180 MX MY R90 R270 MXR90 MYR90} -grid_over_pg_pins -starts_with POWER -pin_direction vertical -halo [subst {$::env(FP_PDN_HORIZONTAL_HALO) $::env(FP_PDN_VERTICAL_HALO)}]
+    # add_pdn_connect -layers [subst {$::env(FP_PDN_LOWER_LAYER) $::env(FP_PDN_UPPER_LAYER)}]
+} else {
+    define_pdn_grid -macro -orient {R0 R180 MX MY R90 R270 MXR90 MYR90} -grid_over_pg_pins -starts_with POWER -halo [subst {$::env(FP_PDN_HORIZONTAL_HALO) $::env(FP_PDN_VERTICAL_HALO)}]
+}
+
+# POWER or GROUND #Std. cell rails starting with power or ground rails at the bottom of the core area
+set ::rails_start_with "POWER" ;
+
+# POWER or GROUND #Upper metal stripes starting with power or ground rails at the left/bottom of the core area
+set ::stripes_start_with "POWER" ;
+
diff --git a/openlane/user_project_wrapper/pin_order.cfg b/openlane/user_project_wrapper/pin_order.cfg
new file mode 100644
index 0000000..90cde69
--- /dev/null
+++ b/openlane/user_project_wrapper/pin_order.cfg
@@ -0,0 +1,156 @@
+#BUS_SORT
+#NR
+analog_io\[8\]
+io_in\[15\]
+io_out\[15\]
+io_oeb\[15\]
+analog_io\[9\]
+io_in\[16\]
+io_out\[16\]
+io_oeb\[16\]
+analog_io\[10\]
+io_in\[17\]
+io_out\[17\]
+io_oeb\[17\]
+analog_io\[11\]
+io_in\[18\]
+io_out\[18\]
+io_oeb\[18\]
+analog_io\[12\]
+io_in\[19\]
+io_out\[19\]
+io_oeb\[19\]
+analog_io\[13\]
+io_in\[20\]
+io_out\[20\]
+io_oeb\[20\]
+analog_io\[14\]
+io_in\[21\]
+io_out\[21\]
+io_oeb\[21\]
+analog_io\[15\]
+io_in\[22\]
+io_out\[22\]
+io_oeb\[22\]
+analog_io\[16\]
+io_in\[23\]
+io_out\[23\]
+io_oeb\[23\]
+
+#S
+wb_.*
+wbs_.*
+la_.*
+user_clock2
+user_irq.*
+
+#E
+io_in\[0\]
+io_out\[0\]
+io_oeb\[0\]
+io_in\[1\]
+io_out\[1\]
+io_oeb\[1\]
+io_in\[2\]
+io_out\[2\]
+io_oeb\[2\]
+io_in\[3\]
+io_out\[3\]
+io_oeb\[3\]
+io_in\[4\]
+io_out\[4\]
+io_oeb\[4\]
+io_in\[5\]
+io_out\[5\]
+io_oeb\[5\]
+io_in\[6\]
+io_out\[6\]
+io_oeb\[6\]
+analog_io\[0\]
+io_in\[7\]
+io_out\[7\]
+io_oeb\[7\]
+analog_io\[1\]
+io_in\[8\]
+io_out\[8\]
+io_oeb\[8\]
+analog_io\[2\]
+io_in\[9\]
+io_out\[9\]
+io_oeb\[9\]
+analog_io\[3\]
+io_in\[10\]
+io_out\[10\]
+io_oeb\[10\]
+analog_io\[4\]
+io_in\[11\]
+io_out\[11\]
+io_oeb\[11\]
+analog_io\[5\]
+io_in\[12\]
+io_out\[12\]
+io_oeb\[12\]
+analog_io\[6\]
+io_in\[13\]
+io_out\[13\]
+io_oeb\[13\]
+analog_io\[7\]
+io_in\[14\]
+io_out\[14\]
+io_oeb\[14\]
+
+#WR
+analog_io\[17\]
+io_in\[24\]
+io_out\[24\]
+io_oeb\[24\]
+analog_io\[18\]
+io_in\[25\]
+io_out\[25\]
+io_oeb\[25\]
+analog_io\[19\]
+io_in\[26\]
+io_out\[26\]
+io_oeb\[26\]
+analog_io\[20\]
+io_in\[27\]
+io_out\[27\]
+io_oeb\[27\]
+analog_io\[21\]
+io_in\[28\]
+io_out\[28\]
+io_oeb\[28\]
+analog_io\[22\]
+io_in\[29\]
+io_out\[29\]
+io_oeb\[29\]
+analog_io\[23\]
+io_in\[30\]
+io_out\[30\]
+io_oeb\[30\]
+analog_io\[24\]
+io_in\[31\]
+io_out\[31\]
+io_oeb\[31\]
+analog_io\[25\]
+io_in\[32\]
+io_out\[32\]
+io_oeb\[32\]
+analog_io\[26\]
+io_in\[33\]
+io_out\[33\]
+io_oeb\[33\]
+analog_io\[27\]
+io_in\[34\]
+io_out\[34\]
+io_oeb\[34\]
+analog_io\[28\]
+io_in\[35\]
+io_out\[35\]
+io_oeb\[35\]
+io_in\[36\]
+io_out\[36\]
+io_oeb\[36\]
+io_in\[37\]
+io_out\[37\]
+io_oeb\[37\]
diff --git a/openlane/user_project_wrapper/sta.tcl b/openlane/user_project_wrapper/sta.tcl
new file mode 100644
index 0000000..7d1086a
--- /dev/null
+++ b/openlane/user_project_wrapper/sta.tcl
@@ -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: Modified by Dinesh Annayya <dinesha@opencores.org>
+
+set ::env(LIB_FASTEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ff_n40C_1v95.lib"
+set ::env(LIB_TYPICAL) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib"
+set ::env(LIB_SLOWEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ss_100C_1v60.lib"
+set ::env(DESIGN_NAME) "user_project_wrapper"
+set ::env(BASE_SDC_FILE) "base.sdc"
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8"
+set ::env(SYNTH_DRIVING_CELL_PIN) "Y"
+set ::env(SYNTH_CAP_LOAD) "17.65"
+set ::env(WIRE_RC_LAYER) "met1"
+
+#To disable empty filler cell black box get created
+#set link_make_black_boxes 0
+
+
+set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um
+define_corners wc bc tt
+read_liberty -corner bc $::env(LIB_FASTEST)
+read_liberty -corner wc $::env(LIB_SLOWEST)
+read_liberty -corner tt $::env(LIB_TYPICAL)
+
+read_lib  -corner tt   ../../lib/sky130_sram_2kbyte_1rw1r_32x512_8_TT_1p8V_25C.lib
+
+read_verilog netlist/qspim.v
+read_verilog netlist/syntacore.v  
+read_verilog netlist/uart_i2cm_usb_spi.v
+read_verilog netlist/wb_host.v  
+read_verilog netlist/wb_interconnect.v
+read_verilog netlist/pinmux.v
+read_verilog netlist/sar_adc.v
+read_verilog netlist/user_project_wrapper.v  
+
+link_design  $::env(DESIGN_NAME)
+
+
+read_spef -path u_riscv_top  ../../spef/scr1_top_wb.spef
+read_spef -path u_pinmux ../../spef/pinmux.spef
+read_spef -path u_qspi_master ../../spef/qspim_top.spef
+read_spef -path u_uart_i2c_usb_spi  ../../spef/uart_i2c_usb_spi_top.spef
+read_spef -path u_wb_host    ../../spef/wb_host.spef
+read_spef -path u_intercon   ../../spef/wb_interconnect.spef
+read_spef ../../spef/user_project_wrapper.spef  
+
+
+read_sdc -echo $::env(BASE_SDC_FILE)
+
+# check for missing constraints
+check_setup  -verbose > unconstraints.rpt
+
+set_operating_conditions -analysis_type single
+# Propgate the clock
+set_propagated_clock [all_clocks]
+
+report_tns
+report_wns
+#report_power 
+#
+echo "################ CORNER : WC (MAX) TIMING Report ###################"                                              > timing_ss_max.rpt
+report_checks -unique -slack_max -0.0 -path_delay max -group_count 100          -corner wc  -format full_clock_expanded >> timing_ss_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  wbm_clk_i   -corner wc  -format full_clock_expanded >> timing_ss_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  wbs_clk_i   -corner wc  -format full_clock_expanded >> timing_ss_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  cpu_clk     -corner wc  -format full_clock_expanded >> timing_ss_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  rtc_clk     -corner wc  -format full_clock_expanded >> timing_ss_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  line_clk    -corner wc  -format full_clock_expanded >> timing_ss_max.rpt
+report_checks                         -path_delay max                           -corner wc                              >> timing_ss_max.rpt
+
+echo "################ CORNER : WC (MIN) TIMING Report ###################"                                              > timing_ss_min.rpt
+report_checks -unique -slack_max -0.0 -path_delay min -group_count 100          -corner wc  -format full_clock_expanded >> timing_ss_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  wbm_clk_i   -corner wc  -format full_clock_expanded >> timing_ss_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  wbs_clk_i   -corner wc  -format full_clock_expanded >> timing_ss_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  cpu_clk     -corner wc  -format full_clock_expanded >> timing_ss_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  rtc_clk     -corner wc  -format full_clock_expanded >> timing_ss_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  line_clk    -corner wc  -format full_clock_expanded >> timing_ss_min.rpt
+report_checks                         -path_delay min                           -corner wc                              >> timing_ss_min.rpt
+
+echo "################ CORNER : BC (MAX) TIMING Report ###################"                                              > timing_ff_max.rpt
+report_checks -unique -slack_max -0.0 -path_delay max -group_count 100          -corner bc  -format full_clock_expanded >> timing_ff_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  wbm_clk_i   -corner bc  -format full_clock_expanded >> timing_ff_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  wbs_clk_i   -corner bc  -format full_clock_expanded >> timing_ff_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  cpu_clk     -corner bc  -format full_clock_expanded >> timing_ff_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  rtc_clk     -corner bc  -format full_clock_expanded >> timing_ff_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  line_clk    -corner bc  -format full_clock_expanded >> timing_ff_max.rpt
+report_checks                         -path_delay max                           -corner bc                              >> timing_ff_max.rpt
+
+echo "################ CORNER : BC (MIN) TIMING Report ###################"                                              > timing_ff_min.rpt
+report_checks -unique -slack_max -0.0 -path_delay min -group_count 100          -corner bc  -format full_clock_expanded >> timing_ff_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  wbm_clk_i   -corner bc  -format full_clock_expanded >> timing_ff_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  wbs_clk_i   -corner bc  -format full_clock_expanded >> timing_ff_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  cpu_clk     -corner bc  -format full_clock_expanded >> timing_ff_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  rtc_clk     -corner bc  -format full_clock_expanded >> timing_ff_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  line_clk    -corner bc  -format full_clock_expanded >> timing_ff_min.rpt
+report_checks                         -path_delay min                           -corner bc                              >> timing_ff_min.rpt
+
+
+echo "################ CORNER : TT (MAX) TIMING Report ###################"                                              > timing_tt_max.rpt
+report_checks -unique -slack_max -0.0 -path_delay max -group_count 100          -corner tt  -format full_clock_expanded >> timing_tt_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  wbm_clk_i   -corner tt  -format full_clock_expanded >> timing_tt_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  wbs_clk_i   -corner tt  -format full_clock_expanded >> timing_tt_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  cpu_clk     -corner tt  -format full_clock_expanded >> timing_tt_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  rtc_clk     -corner tt  -format full_clock_expanded >> timing_tt_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  line_clk    -corner tt  -format full_clock_expanded >> timing_tt_max.rpt
+report_checks                         -path_delay max                           -corner tt                              >> timing_tt_max.rpt
+
+echo "################ CORNER : TT (MIN) TIMING Report ###################"                                              > timing_tt_min.rpt
+report_checks -unique -slack_max -0.0 -path_delay min -group_count 100          -corner tt  -format full_clock_expanded >> timing_tt_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  wbm_clk_i   -corner tt  -format full_clock_expanded >> timing_tt_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  wbs_clk_i   -corner tt  -format full_clock_expanded >> timing_tt_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  cpu_clk     -corner tt  -format full_clock_expanded >> timing_tt_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  rtc_clk     -corner tt  -format full_clock_expanded >> timing_tt_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  line_clk    -corner tt  -format full_clock_expanded >> timing_tt_min.rpt
+report_checks                         -path_delay min                           -corner tt                              >> timing_tt_min.rpt
+
+
+report_checks -path_delay min_max 
+
+#exit
diff --git a/openlane/wb_host/base.sdc b/openlane/wb_host/base.sdc
new file mode 100644
index 0000000..ee8410c
--- /dev/null
+++ b/openlane/wb_host/base.sdc
@@ -0,0 +1,103 @@
+###############################################################################
+# Created by write_sdc
+# Wed Nov 10 16:52:52 2021
+###############################################################################
+current_design wb_host
+###############################################################################
+# Timing Constraints
+###############################################################################
+create_clock -name wbm_clk_i -period 10.0000 [get_ports {wbm_clk_i}]
+create_clock -name wbs_clk_i -period 10.0000 [get_ports {wbs_clk_i}]
+create_clock -name uart_clk -period 100.0000 [get_pins {u_uart2wb.u_core.u_uart_clk.u_mux/X}]
+
+set_clock_transition 0.1500 [all_clocks]
+set_clock_uncertainty -setup 0.2500 [all_clocks]
+set_clock_uncertainty -hold 0.2500 [all_clocks]
+
+set ::env(SYNTH_TIMING_DERATE) 0.05
+puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %"
+set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
+set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}]
+
+set_clock_groups -name async_clock -asynchronous \
+ -group [get_clocks {uart_clk}]  \
+ -group [get_clocks {wbs_clk_i}] \
+ -group [get_clocks {wbm_clk_i}] -comment {Async Clock group}
+
+### ClkSkew Adjust
+set_case_analysis 0 [get_ports {cfg_cska_wh[0]}]
+set_case_analysis 0 [get_ports {cfg_cska_wh[1]}]
+set_case_analysis 0 [get_ports {cfg_cska_wh[2]}]
+set_case_analysis 0 [get_ports {cfg_cska_wh[3]}]
+
+
+set_max_delay   3.5 -from [get_ports {wbd_clk_int}]
+set_max_delay   2 -to   [get_ports {wbd_clk_wh}]
+set_max_delay 3.5 -from wbd_clk_int -to wbd_clk_wh
+
+### WBM I/F
+#Strobe is registered inside the wb_host before generating chip select
+# So wbm_adr_i  wbm_we_i wbm_sel_i wbm_dat_i are having 2 cycle setup
+set_multicycle_path -setup  -from [get_ports {wbm_adr_i[*]}] 2
+set_multicycle_path -setup  -from [get_ports {wbm_cyc_i}]  2
+set_multicycle_path -setup  -from [get_ports {wbm_dat_i[*]}] 2
+set_multicycle_path -setup  -from [get_ports {wbm_sel_i[*]}] 2
+set_multicycle_path -setup  -from [get_ports {wbm_we_i}] 2
+
+set_multicycle_path -hold  -from [get_ports {wbm_adr_i[*]}] 2
+set_multicycle_path -hold  -from [get_ports {wbm_cyc_i}]  2
+set_multicycle_path -hold  -from [get_ports {wbm_dat_i[*]}] 2
+set_multicycle_path -hold  -from [get_ports {wbm_sel_i[*]}] 2
+set_multicycle_path -hold  -from [get_ports {wbm_we_i}] 2
+
+#
+set_input_delay 5.0000 -clock [get_clocks {wbm_clk_i}] -max -add_delay [get_ports {wbm_rst_i}]
+set_input_delay 5.0000 -clock [get_clocks {wbm_clk_i}] -max -add_delay [get_ports {wbm_stb_i}]
+
+set_input_delay 1.0000 -clock [get_clocks {wbm_clk_i}] -min -add_delay [get_ports {wbm_rst_i}]
+set_input_delay 1.0000 -clock [get_clocks {wbm_clk_i}] -min -add_delay [get_ports {wbm_stb_i}]
+
+set_output_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbm_ack_o}]
+set_output_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbm_dat_o[*]}]
+set_output_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbm_err_o}]
+
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbm_ack_o}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbm_dat_o[*]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbm_err_o}]
+# WBS I/F
+set_input_delay -max 6.0000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_ack_i}]
+set_input_delay -max 6.0000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_dat_i[*]}]
+
+set_input_delay -min 2.0000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_ack_i}]
+set_input_delay -min 2.0000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_dat_i[*]}]
+
+set_output_delay -max 4.5000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_adr_o[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_cyc_o}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_dat_o[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_sel_o[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_stb_o}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_we_o}]
+
+set_output_delay -min -1.0000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_adr_o[*]}]
+set_output_delay -min -1.0000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_cyc_o}]
+set_output_delay -min -1.0000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_dat_o[*]}]
+set_output_delay -min -1.0000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_sel_o[*]}]
+set_output_delay -min -1.0000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_stb_o}]
+set_output_delay -min -1.0000 -clock [get_clocks {wbs_clk_i}] -add_delay [get_ports {wbs_we_o}]
+
+###############################################################################
+# Environment
+###############################################################################
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin $::env(SYNTH_DRIVING_CELL_PIN) [all_inputs]
+set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0]
+puts "\[INFO\]: Setting load to: $cap_load"
+set_load  $cap_load [all_outputs]
+###############################################################################
+# Design Rules
+###############################################################################
+
+#disable clock gating check at static clock select pins
+set_false_path -through [get_pins u_cpu_ref_sel.u_mux/S]
+set_false_path -through [get_pins u_cpu_clk_sel.u_mux/S]
+set_false_path -through [get_pins u_wbs_clk_sel.u_mux/S]
+set_false_path -through [get_pins u_usb_clk_sel.u_mux/S]
diff --git a/openlane/wb_host/config.tcl b/openlane/wb_host/config.tcl
new file mode 100755
index 0000000..fcd1da4
--- /dev/null
+++ b/openlane/wb_host/config.tcl
@@ -0,0 +1,112 @@
+# 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>
+
+# Global
+# ------
+
+set script_dir [file dirname [file normalize [info script]]]
+# Name
+
+set ::env(DESIGN_NAME) wb_host
+
+set ::env(DESIGN_IS_CORE) "0"
+
+# Timing configuration
+set ::env(CLOCK_PERIOD) "10"
+set ::env(CLOCK_PORT) "wbm_clk_i wbs_clk_i u_uart2wb.u_core.u_uart_clk.u_mux/X"
+
+set ::env(SYNTH_MAX_FANOUT) 4
+
+## CTS BUFFER
+set ::env(CTS_CLK_BUFFER_LIST) "sky130_fd_sc_hd__clkbuf_4 sky130_fd_sc_hd__clkbuf_8"
+set ::env(CTS_SINK_CLUSTERING_SIZE) "16"
+set ::env(CLOCK_BUFFER_FANOUT) "8"
+
+# Sources
+# -------
+
+# Local sources + no2usb sources
+set ::env(VERILOG_FILES) "\
+     $script_dir/../../verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv \
+     $script_dir/../../verilog/rtl/wb_host/src/wb_host.sv \
+     $script_dir/../../verilog/rtl/lib/async_fifo.sv      \
+     $script_dir/../../verilog/rtl/lib/async_wb.sv        \
+     $script_dir/../../verilog/rtl/lib/clk_ctl.v          \
+     $script_dir/../../verilog/rtl/lib/ctech_cells.sv     \
+     $script_dir/../../verilog/rtl/lib/registers.v        \
+     $script_dir/../../verilog/rtl/lib/reset_sync.sv      \
+     $script_dir/../../verilog/rtl/lib/async_reg_bus.sv   \
+     $script_dir/../../verilog/rtl/uart/src/uart_txfsm.sv \
+     $script_dir/../../verilog/rtl/uart/src/uart_rxfsm.sv \
+     $script_dir/../../verilog/rtl/lib/double_sync_low.v  \
+     $script_dir/../../verilog/rtl/wb_interconnect/src/wb_arb.sv     \
+     $script_dir/../../verilog/rtl/uart2wb/src/uart2wb.sv \
+     $script_dir/../../verilog/rtl/uart2wb/src/uart2_core.sv \
+     $script_dir/../../verilog/rtl/uart2wb/src/uart_msg_handler.v \
+     "
+
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+set ::env(SYNTH_DEFINES) [list SYNTHESIS ]
+set ::env(SDC_FILE) "$script_dir/base.sdc"
+set ::env(BASE_SDC_FILE) "$script_dir/base.sdc"
+
+set ::env(LEC_ENABLE) 0
+
+set ::env(VDD_PIN) [list {vccd1}]
+set ::env(GND_PIN) [list {vssd1}]
+
+
+# Floorplanning
+# -------------
+
+set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+
+set ::env(FP_SIZING) absolute
+set ::env(DIE_AREA) "0 0 800 200"
+
+
+# If you're going to use multiple power domains, then keep this disabled.
+set ::env(RUN_CVC) 1
+
+#set ::env(PDN_CFG) $script_dir/pdn.tcl
+
+
+set ::env(PL_TIME_DRIVEN) 1
+set ::env(PL_TARGET_DENSITY) "0.35"
+
+
+
+set ::env(FP_IO_VEXTEND) 4
+set ::env(FP_IO_HEXTEND) 4
+
+set ::env(FP_PDN_VPITCH) 100
+set ::env(FP_PDN_HPITCH) 100
+set ::env(FP_PDN_VWIDTH) 5
+set ::env(FP_PDN_HWIDTH) 5
+
+set ::env(GLB_RT_MAXLAYER) 5
+set ::env(GLB_RT_MAX_DIODE_INS_ITERS) 10
+
+set ::env(DIODE_INSERTION_STRATEGY) 4
+
+set ::env(PL_RESIZER_BUFFER_INPUT_PORTS) "0"
+set ::env(PL_RESIZER_BUFFER_OUTPUT_PORTS) "1"
+set ::env(GLB_RESIZER_TIMING_OPTIMIZATIONS) "1"
+set ::env(PL_RESIZER_DESIGN_OPTIMIZATIONS) "1"
+set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
+set ::env(QUIT_ON_MAGIC_DRC) "1"
+set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/wb_host/interactive.tcl b/openlane/wb_host/interactive.tcl
new file mode 100644
index 0000000..f59586f
--- /dev/null
+++ b/openlane/wb_host/interactive.tcl
@@ -0,0 +1,219 @@
+#!/usr/bin/tclsh
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+# Copyright 2020 Efabless Corporation
+# Copyright 2020 Sylvain Munaut
+#
+# 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
+
+package require openlane;
+
+
+proc run_placement_step {args} {
+    # set pdndef_dirname [file dirname $::env(pdn_tmp_file_tag).def]
+    # set pdndef [lindex [glob $pdndef_dirname/*pdn*] 0]
+    # set_def $pdndef
+    if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
+        set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
+    }
+
+    run_placement
+}
+
+proc run_cts_step {args} {
+    # set_def $::env(opendp_result_file_tag).def
+    if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
+        set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
+    }
+
+    run_cts
+    run_resizer_timing
+}
+
+proc run_routing_step {args} {
+    # set resizerdef_dirname [file dirname $::env(resizer_tmp_file_tag)_timing.def]
+    # set resizerdef [lindex [glob $resizerdef_dirname/*resizer*] 0]
+    # set_def $resizerdef
+    if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
+        set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
+    }
+    run_routing
+}
+
+proc run_diode_insertion_2_5_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
+        set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
+    }
+	if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+		run_antenna_check
+		heal_antenna_violators; # modifies the routed DEF
+	}
+
+}
+
+proc run_power_pins_insertion_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(POWER_PINS_INSERTION_CURRENT_DEF) ] } {
+        set ::env(POWER_PINS_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(POWER_PINS_INSERTION_CURRENT_DEF)
+    }
+    if { $::env(LVS_INSERT_POWER_PINS) } {
+		write_powered_verilog
+		set_netlist $::env(lvs_result_file_tag).powered.v
+    }
+
+}
+
+proc run_lvs_step {{ lvs_enabled 1 }} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
+        set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
+    }
+	if { $lvs_enabled } {
+		run_magic_spice_export
+		run_lvs; # requires run_magic_spice_export
+	}
+
+}
+
+proc run_drc_step {{ drc_enabled 1 }} {
+    if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
+        set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
+    }
+	if { $drc_enabled } {
+		run_magic_drc
+		run_klayout_drc
+	}
+}
+
+proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
+    if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
+        set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
+    }
+	if { $antenna_check_enabled } {
+		run_antenna_check
+	}
+}
+
+proc run_flow {args} {
+       set script_dir [file dirname [file normalize [info script]]]
+
+		set options {
+		{-design required}
+		{-save_path optional}
+		{-no_lvs optional}
+	    {-no_drc optional}
+	    {-no_antennacheck optional}
+	}
+	set flags {-save}
+	parse_key_args "run_flow" args arg_values $options flags_map $flags -no_consume
+
+	prep {*}$args
+
+        set LVS_ENABLED 1
+        set DRC_ENABLED 1
+        set ANTENNACHECK_ENABLED 1
+
+        set steps [dict create "synthesis" {run_synthesis "" } \
+                "floorplan" {run_floorplan ""} \
+                "placement" {run_placement_step ""} \
+                "cts" {run_cts_step ""} \
+                "routing" {run_routing_step ""}\
+                "diode_insertion" {run_diode_insertion_2_5_step ""} \
+                "power_pins_insertion" {run_power_pins_insertion_step ""} \
+                "gds_magic" {run_magic ""} \
+                "gds_drc_klayout" {run_klayout ""} \
+                "gds_xor_klayout" {run_klayout_gds_xor ""} \
+                "lvs" "run_lvs_step $LVS_ENABLED" \
+                "drc" "run_drc_step $DRC_ENABLED" \
+                "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED" \
+                "cvc" {run_lef_cvc}
+        ]
+
+       set_if_unset arg_values(-to) "cvc";
+
+       if {  [info exists ::env(CURRENT_STEP) ] } {
+           puts "\[INFO\]:Picking up where last execution left off"
+           puts [format "\[INFO\]:Current stage is %s " $::env(CURRENT_STEP)]
+       } else {
+           set ::env(CURRENT_STEP) "synthesis";
+       }
+       set_if_unset arg_values(-from) $::env(CURRENT_STEP);
+       set exe 0;
+       dict for {step_name step_exe} $steps {
+           if { [ string equal $arg_values(-from) $step_name ] } {
+               set exe 1;
+           }
+
+           if { $exe } {
+               # For when it fails
+               set ::env(CURRENT_STEP) $step_name
+               [lindex $step_exe 0] [lindex $step_exe 1] ;
+           }
+
+           if { [ string equal $arg_values(-to) $step_name ] } {
+               set exe 0:
+               break;
+           }
+
+       }
+
+       # for when it resumes
+       set steps_as_list [dict keys $steps]
+       set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
+       set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
+
+	if {  [info exists flags_map(-save) ] } {
+		if { ! [info exists arg_values(-save_path)] } {
+			set arg_values(-save_path) ""
+		}
+		save_views 	-lef_path $::env(magic_result_file_tag).lef \
+			-def_path $::env(CURRENT_DEF) \
+			-gds_path $::env(magic_result_file_tag).gds \
+			-mag_path $::env(magic_result_file_tag).mag \
+			-maglef_path $::env(magic_result_file_tag).lef.mag \
+			-spice_path $::env(magic_result_file_tag).spice \
+			-spef_path $::env(CURRENT_SPEF) \
+			-verilog_path $::env(CURRENT_NETLIST) \
+			-save_path $arg_values(-save_path) \
+			-tag $::env(RUN_TAG)
+	}
+
+
+	calc_total_runtime
+	save_state
+	generate_final_summary_report
+	
+	check_timing_violations
+
+	puts_success "Flow Completed Without Fatal Errors."
+
+}
+
+run_flow {*}$argv
diff --git a/openlane/wb_host/pin_order.cfg b/openlane/wb_host/pin_order.cfg
new file mode 100644
index 0000000..a29f24b
--- /dev/null
+++ b/openlane/wb_host/pin_order.cfg
@@ -0,0 +1,341 @@
+#BUS_SORT
+
+#MANUAL_PLACE
+
+
+#W
+sspim_rst_n      0000 0 4
+qspim_rst_n
+uart_rst_n
+i2cm_rst_n
+usb_rst_n
+bist_rst_n
+usb_clk
+cfg_clk_ctrl1\[31\]
+cfg_clk_ctrl1\[30\]
+cfg_clk_ctrl1\[29\]
+cfg_clk_ctrl1\[28\]
+cfg_clk_ctrl2\[27\]
+cfg_clk_ctrl2\[26\]
+cfg_clk_ctrl2\[25\]
+cfg_clk_ctrl2\[24\]
+cfg_clk_ctrl2\[23\]
+cfg_clk_ctrl2\[22\]
+cfg_clk_ctrl2\[21\]
+cfg_clk_ctrl2\[20\]
+cfg_clk_ctrl2\[19\]
+cfg_clk_ctrl2\[18\]
+cfg_clk_ctrl2\[17\]
+cfg_clk_ctrl2\[16\]
+
+cpu_clk               0100 0 2
+rtc_clk
+cpu_rst_n
+
+
+
+#S
+user_clock2         0000 0  2
+user_clock1     
+wbm_clk_i       
+wbm_rst_i       
+wbm_ack_o       
+wbm_cyc_i       
+wbm_stb_i       
+wbm_we_i        
+wbm_adr_i\[0\]  
+wbm_dat_i\[0\]  
+wbm_dat_o\[0\]  
+wbm_sel_i\[0\]  
+wbm_adr_i\[1\]  
+wbm_dat_i\[1\]  
+wbm_dat_o\[1\]  
+wbm_sel_i\[1\]  
+wbm_adr_i\[2\]  
+wbm_dat_i\[2\]  
+wbm_dat_o\[2\]  
+wbm_sel_i\[2\]  
+wbm_adr_i\[3\]  
+wbm_dat_i\[3\]  
+wbm_dat_o\[3\]  
+wbm_sel_i\[3\]  
+wbm_adr_i\[4\]  
+wbm_dat_i\[4\]  
+wbm_dat_o\[4\]  
+wbm_adr_i\[5\]  
+wbm_dat_i\[5\]  
+wbm_dat_o\[5\]  
+wbm_adr_i\[6\]  
+wbm_dat_i\[6\]  
+wbm_dat_o\[6\]  
+wbm_adr_i\[7\]  
+wbm_dat_i\[7\]  
+wbm_dat_o\[7\]  
+wbm_adr_i\[8\]  
+wbm_dat_i\[8\]  
+wbm_dat_o\[8\]  
+wbm_adr_i\[9\]  
+wbm_dat_i\[9\]  
+wbm_dat_o\[9\]  
+wbm_adr_i\[10\] 
+wbm_dat_i\[10\] 
+wbm_dat_o\[10\] 
+wbm_adr_i\[11\] 
+wbm_dat_i\[11\] 
+wbm_dat_o\[11\] 
+wbm_adr_i\[12\] 
+wbm_dat_i\[12\] 
+wbm_dat_o\[12\] 
+wbm_adr_i\[13\] 
+wbm_dat_i\[13\] 
+wbm_dat_o\[13\] 
+wbm_adr_i\[14\] 
+wbm_dat_i\[14\] 
+wbm_dat_o\[14\] 
+wbm_adr_i\[15\] 
+wbm_dat_i\[15\] 
+wbm_dat_o\[15\] 
+wbm_adr_i\[16\] 
+wbm_dat_i\[16\] 
+wbm_dat_o\[16\] 
+wbm_adr_i\[17\] 
+
+wbm_dat_i\[17\] 
+wbm_dat_o\[17\] 
+wbm_adr_i\[18\] 
+wbm_dat_i\[18\] 
+wbm_dat_o\[18\] 
+wbm_adr_i\[19\] 
+wbm_dat_i\[19\] 
+wbm_dat_o\[19\] 
+wbm_adr_i\[20\] 
+wbm_dat_i\[20\] 
+wbm_dat_o\[20\] 
+wbm_adr_i\[21\] 
+wbm_dat_i\[21\] 
+wbm_dat_o\[21\]  
+wbm_adr_i\[22\]  
+wbm_dat_i\[22\]  
+wbm_dat_o\[22\]  
+wbm_adr_i\[23\]  
+wbm_dat_i\[23\]  
+wbm_dat_o\[23\]  
+wbm_adr_i\[24\]  
+wbm_dat_i\[24\]  
+wbm_dat_o\[24\]  
+wbm_adr_i\[25\]  
+wbm_dat_i\[25\]  
+wbm_dat_o\[25\]  
+wbm_adr_i\[26\]  
+wbm_dat_i\[26\]  
+wbm_dat_o\[26\]  
+wbm_adr_i\[27\]  
+wbm_dat_i\[27\]  
+wbm_dat_o\[27\]  
+wbm_adr_i\[28\]  
+wbm_dat_i\[28\]  
+wbm_dat_o\[28\]  
+wbm_adr_i\[29\]  
+wbm_dat_i\[29\]  
+wbm_dat_o\[29\]  
+wbm_adr_i\[30\]  
+wbm_dat_i\[30\]  
+wbm_dat_o\[30\]  
+wbm_adr_i\[31\]  
+wbm_dat_i\[31\]  
+wbm_dat_o\[31\]  
+wbm_err_o        
+
+la_data_in\[0\]    300 0 2
+la_data_in\[1\]    
+la_data_in\[2\]    
+la_data_in\[3\]    
+la_data_in\[4\]    
+la_data_in\[5\]    
+la_data_in\[6\]    
+la_data_in\[7\]    
+la_data_in\[8\]    
+la_data_in\[9\]    
+la_data_in\[10\]    
+la_data_in\[11\]    
+la_data_in\[12\]    
+la_data_in\[13\]    
+la_data_in\[14\]    
+la_data_in\[15\]    
+la_data_in\[16\]    
+la_data_in\[17\]    
+
+#E
+
+uartm_rxd           100 0 2
+uartm_txd
+
+
+#N
+wbd_int_rst_n         0400 0 2
+cfg_clk_ctrl2\[31\]
+cfg_clk_ctrl2\[30\]
+cfg_clk_ctrl2\[29\]
+cfg_clk_ctrl2\[28\]
+cfg_clk_ctrl2\[15\]
+cfg_clk_ctrl2\[14\]
+cfg_clk_ctrl2\[13\]
+cfg_clk_ctrl2\[12\]
+cfg_clk_ctrl2\[11\]
+cfg_clk_ctrl2\[10\]
+cfg_clk_ctrl2\[9\]
+cfg_clk_ctrl2\[8\]
+cfg_clk_ctrl2\[7\]
+cfg_clk_ctrl2\[6\]
+cfg_clk_ctrl2\[5\]
+cfg_clk_ctrl2\[4\]
+cfg_clk_ctrl2\[3\]
+cfg_clk_ctrl2\[2\]
+cfg_clk_ctrl2\[1\]
+cfg_clk_ctrl2\[0\]
+cfg_clk_ctrl1\[27\]
+cfg_clk_ctrl1\[26\]
+cfg_clk_ctrl1\[25\]
+cfg_clk_ctrl1\[24\]
+cfg_clk_ctrl1\[23\]
+cfg_clk_ctrl1\[22\]
+cfg_clk_ctrl1\[21\]
+cfg_clk_ctrl1\[20\]
+cfg_clk_ctrl1\[19\]
+cfg_clk_ctrl1\[18\]
+cfg_clk_ctrl1\[17\]
+cfg_clk_ctrl1\[16\]
+cfg_clk_ctrl1\[15\]
+cfg_clk_ctrl1\[14\]
+cfg_clk_ctrl1\[13\]
+cfg_clk_ctrl1\[12\]
+cfg_clk_ctrl1\[11\]
+cfg_clk_ctrl1\[10\]
+cfg_clk_ctrl1\[9\]
+cfg_clk_ctrl1\[8\]
+cfg_clk_ctrl1\[3\]
+cfg_clk_ctrl1\[2\]
+cfg_clk_ctrl1\[1\]
+cfg_clk_ctrl1\[0\]
+wbd_clk_int
+wbs_clk_out   
+wbs_clk_i            
+wbd_clk_wh
+cfg_clk_ctrl1\[7\]
+cfg_cska_wh\[3\]
+cfg_clk_ctrl1\[6\]
+cfg_cska_wh\[2\]
+cfg_clk_ctrl1\[5\]
+cfg_cska_wh\[1\]
+cfg_clk_ctrl1\[4\]
+cfg_cska_wh\[0\]
+
+
+
+wbs_stb_o       460 0 2 
+wbs_we_o         
+wbs_adr_o\[31\]  
+wbs_adr_o\[30\]  
+wbs_adr_o\[29\]  
+wbs_adr_o\[28\]  
+wbs_adr_o\[27\]  
+wbs_adr_o\[26\]  
+wbs_adr_o\[25\]  
+wbs_adr_o\[24\]  
+wbs_adr_o\[23\]  
+wbs_adr_o\[22\]  
+wbs_adr_o\[21\]  
+wbs_adr_o\[20\]  
+wbs_adr_o\[19\]  
+wbs_adr_o\[18\]  
+wbs_adr_o\[17\]  
+wbs_adr_o\[16\]  
+wbs_adr_o\[15\]  
+wbs_adr_o\[14\]  
+wbs_adr_o\[13\]  
+wbs_adr_o\[12\]  
+wbs_adr_o\[11\]  
+wbs_adr_o\[10\]  
+wbs_adr_o\[9\]   
+wbs_adr_o\[8\]   
+wbs_adr_o\[7\]   
+wbs_adr_o\[6\]   
+wbs_adr_o\[5\]   
+wbs_adr_o\[4\]   
+wbs_adr_o\[3\]   
+wbs_adr_o\[2\]   
+wbs_adr_o\[1\]   
+wbs_adr_o\[0\]   
+wbs_sel_o\[3\]   
+wbs_sel_o\[2\]   
+wbs_sel_o\[1\]   
+wbs_sel_o\[0\]   
+wbs_dat_o\[31\]  
+wbs_dat_o\[30\]  
+wbs_dat_o\[29\]  
+wbs_dat_o\[28\]  
+wbs_dat_o\[27\]  
+wbs_dat_o\[26\]  
+wbs_dat_o\[25\]  
+wbs_dat_o\[24\]  
+wbs_dat_o\[23\]  
+wbs_dat_o\[22\]  
+wbs_dat_o\[21\]  
+wbs_dat_o\[20\]  
+wbs_dat_o\[19\]  
+wbs_dat_o\[18\]  
+wbs_dat_o\[17\]  
+wbs_dat_o\[16\]  
+wbs_dat_o\[15\]  
+wbs_dat_o\[14\]  
+wbs_dat_o\[13\]  
+wbs_dat_o\[12\]  
+wbs_dat_o\[11\]  
+wbs_dat_o\[10\]  
+wbs_dat_o\[9\]   
+wbs_dat_o\[8\]   
+wbs_dat_o\[7\]   
+wbs_dat_o\[6\]   
+wbs_dat_o\[5\]   
+wbs_dat_o\[4\]   
+wbs_dat_o\[3\]   
+wbs_dat_o\[2\]   
+wbs_dat_o\[1\]   
+wbs_dat_o\[0\]   
+wbs_dat_i\[31\]  
+wbs_dat_i\[30\]  
+wbs_dat_i\[29\]  
+wbs_dat_i\[28\]  
+wbs_dat_i\[27\]  
+wbs_dat_i\[26\]  
+wbs_dat_i\[25\]  
+wbs_dat_i\[24\]  
+wbs_dat_i\[23\]  
+wbs_dat_i\[22\]  
+wbs_dat_i\[21\]  
+wbs_dat_i\[20\]  
+wbs_dat_i\[19\]  
+wbs_dat_i\[18\]  
+wbs_dat_i\[17\]  
+wbs_dat_i\[16\]  
+wbs_dat_i\[15\]  
+wbs_dat_i\[14\]  
+wbs_dat_i\[13\]  
+wbs_dat_i\[12\]  
+wbs_dat_i\[11\]  
+wbs_dat_i\[10\]  
+wbs_dat_i\[9\]   
+wbs_dat_i\[8\]   
+wbs_dat_i\[7\]   
+wbs_dat_i\[6\]   
+wbs_dat_i\[5\]   
+wbs_dat_i\[4\]   
+wbs_dat_i\[3\]   
+wbs_dat_i\[2\]   
+wbs_dat_i\[1\]   
+wbs_dat_i\[0\]   
+wbs_ack_i        
+wbs_err_i        
+wbs_cyc_o      
+
+
diff --git a/openlane/wb_interconnect/base.sdc b/openlane/wb_interconnect/base.sdc
new file mode 100644
index 0000000..d815c04
--- /dev/null
+++ b/openlane/wb_interconnect/base.sdc
@@ -0,0 +1,142 @@
+###############################################################################
+# Created by write_sdc
+# Fri Nov 12 05:00:05 2021
+###############################################################################
+current_design wb_interconnect
+###############################################################################
+# Timing Constraints
+###############################################################################
+create_clock -name clk_i -period 10.0000 [get_ports {clk_i}]
+
+set_clock_transition 0.1500 [all_clocks]
+set_clock_uncertainty -setup 0.2500 [all_clocks]
+set_clock_uncertainty -hold 0.2500 [all_clocks]
+
+#Clock Skew adjustment
+set_case_analysis 0 [get_ports {cfg_cska_wi[0]}]
+set_case_analysis 0 [get_ports {cfg_cska_wi[1]}]
+set_case_analysis 0 [get_ports {cfg_cska_wi[2]}]
+set_case_analysis 0 [get_ports {cfg_cska_wi[3]}]
+
+
+# Set max delay for clock skew
+set_max_delay 4.0 -from [get_ports {wbd_clk_int}]
+set_max_delay   2 -to   [get_ports {wbd_clk_wi}]
+set_max_delay 4.0 -from wbd_clk_int -to wbd_clk_wi
+##
+set_input_delay -max 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {rst_n}]
+
+set_input_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m0_wbd_adr_i[*]}]
+set_input_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m0_wbd_dat_i[*]}]
+set_input_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m1_wbd_adr_i[*]}]
+set_input_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m2_wbd_adr_i[*]}]
+set_input_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_ack_i}]
+set_input_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_dat_i[*]}]
+set_input_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_ack_i}]
+set_input_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_dat_i[*]}]
+set_input_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_ack_i}]
+set_input_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_dat_i[*]}]
+set_input_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_ack_i}]
+set_input_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_dat_i[*]}]
+
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m0_wbd_adr_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m0_wbd_dat_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m0_wbd_sel_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m1_wbd_adr_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m1_wbd_dat_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m1_wbd_sel_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m2_wbd_adr_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m2_wbd_dat_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m2_wbd_sel_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_ack_i}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_dat_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_ack_i}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_dat_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_ack_i}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_dat_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_ack_i}]
+set_input_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_dat_i[*]}]
+
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m0_wbd_ack_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m0_wbd_dat_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m0_wbd_err_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m1_wbd_ack_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m1_wbd_dat_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m1_wbd_err_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m2_wbd_ack_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m2_wbd_dat_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m2_wbd_err_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_adr_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_cyc_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_dat_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_sel_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_stb_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_we_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_adr_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_cyc_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_dat_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_sel_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_stb_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_we_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_adr_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_cyc_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_dat_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_sel_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_stb_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_we_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_adr_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_cyc_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_dat_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_sel_o[*]}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_stb_o}]
+set_output_delay -max 4.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_we_o}]
+
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m0_wbd_ack_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m0_wbd_dat_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m0_wbd_err_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m1_wbd_ack_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m1_wbd_dat_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m1_wbd_err_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m2_wbd_ack_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m2_wbd_dat_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {m2_wbd_err_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_adr_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_cyc_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_dat_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_sel_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_stb_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s0_wbd_we_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_adr_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_cyc_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_dat_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_sel_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_stb_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s1_wbd_we_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_adr_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_cyc_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_dat_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_sel_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_stb_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s2_wbd_we_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_adr_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_cyc_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_dat_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_sel_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_stb_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {clk_i}] -add_delay [get_ports {s3_wbd_we_o}]
+
+###############################################################################
+# Environment
+###############################################################################
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin $::env(SYNTH_DRIVING_CELL_PIN) [all_inputs]
+set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0]
+puts "\[INFO\]: Setting load to: $cap_load"
+set_load  $cap_load [all_outputs]
+
+set ::env(SYNTH_TIMING_DERATE) 0.05
+puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %"
+set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
+set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}]
+###############################################################################
+# Design Rules
+###############################################################################
diff --git a/openlane/wb_interconnect/config.tcl b/openlane/wb_interconnect/config.tcl
new file mode 100755
index 0000000..85fe0e5
--- /dev/null
+++ b/openlane/wb_interconnect/config.tcl
@@ -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: Modified by Dinesh Annayya <dinesha@opencores.org>
+
+# Global
+# ------
+
+set script_dir [file dirname [file normalize [info script]]]
+# Name
+set ::env(DESIGN_NAME) wb_interconnect
+
+
+set ::env(DESIGN_IS_CORE) "0"
+set ::env(FP_PDN_CORE_RING) "0"
+
+# Timing configuration
+set ::env(CLOCK_PERIOD) "10"
+set ::env(CLOCK_PORT) "clk_i"
+
+set ::env(SYNTH_MAX_FANOUT) 4
+
+## CTS BUFFER
+set ::env(CTS_CLK_BUFFER_LIST) "sky130_fd_sc_hd__clkbuf_4 sky130_fd_sc_hd__clkbuf_8"
+set ::env(CTS_SINK_CLUSTERING_SIZE) "16"
+set ::env(CLOCK_BUFFER_FANOUT) "8"
+
+# Sources
+# -------
+
+# Local sources + no2usb sources
+set ::env(VERILOG_FILES) "\
+        $script_dir/../../verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv \
+        $script_dir/../../verilog/rtl/lib/sync_wbb.sv                \
+        $script_dir/../../verilog/rtl/lib/sync_fifo2.sv                \
+        $script_dir/../../verilog/rtl/wb_interconnect/src/wb_arb.sv     \
+        $script_dir/../../verilog/rtl/wb_interconnect/src/wb_interconnect.sv  \
+	"
+
+set ::env(SYNTH_DEFINES) [list SYNTHESIS ]
+
+set ::env(SYNTH_PARAMS) "CH_CLK_WD 8,\
+	                 CH_DATA_WD 116 \
+			 "
+
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+set ::env(SDC_FILE) "$script_dir/base.sdc"
+set ::env(BASE_SDC_FILE) "$script_dir/base.sdc"
+
+set ::env(LEC_ENABLE) 0
+
+set ::env(VDD_PIN) [list {vccd1}]
+set ::env(GND_PIN) [list {vssd1}]
+
+
+# Floorplanning
+# -------------
+
+set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+
+set ::env(FP_SIZING) absolute
+set ::env(DIE_AREA) "0 0 200 2300"
+
+
+# If you're going to use multiple power domains, then keep this disabled.
+set ::env(RUN_CVC) 0
+
+#set ::env(PDN_CFG) $script_dir/pdn.tcl
+
+
+set ::env(PL_TIME_DRIVEN) 1
+set ::env(PL_TARGET_DENSITY) "0.30"
+
+# helps in anteena fix
+set ::env(USE_ARC_ANTENNA_CHECK) "0"
+
+
+set ::env(GLB_RT_MAX_DIODE_INS_ITERS) 10
+set ::env(DIODE_INSERTION_STRATEGY) 4
+
+## CTS
+set ::env(CTS_CLK_BUFFER_LIST) "sky130_fd_sc_hd__clkbuf_4 sky130_fd_sc_hd__clkbuf_8 sky130_fd_sc_hd__clkbuf_16"
+set ::env(CTS_SINK_CLUSTERING_MAX_DIAMETER) 50
+set ::env(CTS_SINK_CLUSTERING_SIZE) 20
+
+## Placement
+set ::env(PL_RESIZER_DESIGN_OPTIMIZATIONS) 1
+set ::env(PL_RESIZER_TIMING_OPTIMIZATIONS) 0
+
+set ::env(PL_RESIZER_MAX_SLEW_MARGIN) 2
+set ::env(PL_RESIZER_MAX_CAP_MARGIN) 2
+
+## Routing
+set ::env(GLB_RT_ADJUSTMENT) 0
+set ::env(GLB_RT_L2_ADJUSTMENT) 0.21
+set ::env(GLB_RT_L3_ADJUSTMENT) 0.21
+set ::env(GLB_RT_L4_ADJUSTMENT) 0.1
+set ::env(GLB_RT_L5_ADJUSTMENT) 0.1
+set ::env(GLB_RT_L6_ADJUSTMENT) 0.1
+set ::env(GLB_RT_ALLOW_CONGESTION) 0
+set ::env(GLB_RT_OVERFLOW_ITERS) 200
+
+set ::env(GLB_RT_MINLAYER) 2
+set ::env(GLB_RT_MAXLAYER) 6
+
+
+set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
+set ::env(QUIT_ON_MAGIC_DRC) "1"
+set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
+
+set ::env(GLB_RESIZER_TIMING_OPTIMIZATIONS) "0"
+set ::env(PL_RESIZER_BUFFER_INPUT_PORTS) "0"
+set ::env(PL_RESIZER_BUFFER_OUTPUT_PORTS) "1"
+set ::env(PL_RESIZER_MAX_WIRE_LENGTH) "2000"
+set ::env(PL_RESIZER_MAX_SLEW_MARGIN) "2.0"
+set ::env(PL_RESIZER_MAX_CAP_MARGIN) "5"
+
+## FANOUT Reduced to take care of long routes
+set ::env(SYNTH_MAX_FANOUT) "2"
+
diff --git a/openlane/wb_interconnect/interactive.tcl b/openlane/wb_interconnect/interactive.tcl
new file mode 100644
index 0000000..a180a5c
--- /dev/null
+++ b/openlane/wb_interconnect/interactive.tcl
@@ -0,0 +1,403 @@
+#!/usr/bin/tclsh
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+# Copyright 2020 Efabless Corporation
+# Copyright 2020 Sylvain Munaut
+#
+# 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
+
+package require openlane;
+
+
+proc run_placement_step {args} {
+    # set pdndef_dirname [file dirname $::env(pdn_tmp_file_tag).def]
+    # set pdndef [lindex [glob $pdndef_dirname/*pdn*] 0]
+    # set_def $pdndef
+    if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
+        set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
+    }
+
+    run_placement
+}
+
+proc run_cts_step {args} {
+    # set_def $::env(opendp_result_file_tag).def
+    if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
+        set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
+    }
+
+    run_cts
+    run_resizer_timing
+}
+
+proc run_routing_step {args} {
+    # set resizerdef_dirname [file dirname $::env(resizer_tmp_file_tag)_timing.def]
+    # set resizerdef [lindex [glob $resizerdef_dirname/*resizer*] 0]
+    # set_def $resizerdef
+    if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
+        set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
+    }
+    run_routing
+}
+
+proc run_diode_insertion_2_5_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
+        set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
+    }
+	if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+		run_antenna_check
+		heal_antenna_violators; # modifies the routed DEF
+	}
+
+}
+
+proc run_power_pins_insertion_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(POWER_PINS_INSERTION_CURRENT_DEF) ] } {
+        set ::env(POWER_PINS_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(POWER_PINS_INSERTION_CURRENT_DEF)
+    }
+    if { $::env(LVS_INSERT_POWER_PINS) } {
+		write_powered_verilog
+		set_netlist $::env(lvs_result_file_tag).powered.v
+    }
+
+}
+
+proc run_lvs_step {{ lvs_enabled 1 }} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
+        set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
+    }
+	if { $lvs_enabled } {
+		run_magic_spice_export
+		run_lvs; # requires run_magic_spice_export
+	}
+
+}
+
+proc run_drc_step {{ drc_enabled 1 }} {
+    if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
+        set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
+    }
+	if { $drc_enabled } {
+		run_magic_drc
+		run_klayout_drc
+	}
+}
+
+proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
+    if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
+        set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
+    }
+	if { $antenna_check_enabled } {
+		run_antenna_check
+	}
+}
+
+proc gen_pdn {args} {
+    puts_info "Generating PDN..."
+    TIMER::timer_start
+	
+    set ::env(SAVE_DEF) [index_file $::env(pdn_tmp_file_tag).def]
+    set ::env(PGA_RPT_FILE) [index_file $::env(pdn_report_file_tag).pga.rpt]
+
+    try_catch $::env(OPENROAD_BIN) -exit $::env(SCRIPTS_DIR)/openroad/pdn.tcl \
+	|& tee $::env(TERMINAL_OUTPUT) [index_file $::env(pdn_log_file_tag).log 0]
+
+
+    TIMER::timer_stop
+    exec echo "[TIMER::get_runtime]" >> [index_file $::env(pdn_log_file_tag)_runtime.txt 0]
+
+	quit_on_unconnected_pdn_nodes
+
+    set_def $::env(SAVE_DEF)
+}
+
+proc run_power_grid_generation {args} {
+	if { [info exists ::env(VDD_NETS)] || [info exists ::env(GND_NETS)] } {
+		# they both must exist and be equal in length
+		# current assumption: they cannot have a common ground
+		if { ! [info exists ::env(VDD_NETS)] || ! [info exists ::env(GND_NETS)] } {
+			puts_err "VDD_NETS and GND_NETS must *both* either be defined or undefined"
+			return -code error
+		}
+		# standard cell power and ground nets are assumed to be the first net 
+		set ::env(VDD_PIN) [lindex $::env(VDD_NETS) 0]
+		set ::env(GND_PIN) [lindex $::env(GND_NETS) 0]
+	} elseif { [info exists ::env(SYNTH_USE_PG_PINS_DEFINES)] } {
+		set ::env(VDD_NETS) [list]
+		set ::env(GND_NETS) [list]
+		# get the pins that are in $yosys_tmp_file_tag.pg_define.v
+		# that are not in $yosys_result_file_tag.v
+		#
+		set full_pins {*}[extract_pins_from_yosys_netlist $::env(yosys_tmp_file_tag).pg_define.v]
+		puts_info $full_pins
+
+		set non_pg_pins {*}[extract_pins_from_yosys_netlist $::env(yosys_result_file_tag).v]
+		puts_info $non_pg_pins
+
+		# assumes the pins are ordered correctly (e.g., vdd1, vss1, vcc1, vss1, ...)
+		foreach {vdd gnd} $full_pins {
+			if { $vdd ne "" && $vdd ni $non_pg_pins } {
+				lappend ::env(VDD_NETS) $vdd
+			}
+			if { $gnd ne "" && $gnd ni $non_pg_pins } {
+				lappend ::env(GND_NETS) $gnd
+			}
+		}
+	} else {
+		set ::env(VDD_NETS) $::env(VDD_PIN)
+		set ::env(GND_NETS) $::env(GND_PIN)
+	}
+
+	puts_info "Power planning the following nets"
+	puts_info "Power: $::env(VDD_NETS)"
+	puts_info "Ground: $::env(GND_NETS)"
+
+	if { [llength $::env(VDD_NETS)] != [llength $::env(GND_NETS)] } {
+		puts_err "VDD_NETS and GND_NETS must be of equal lengths"
+		return -code error
+	}
+
+	# internal macros power connections 
+	if {[info exists ::env(FP_PDN_MACRO_HOOKS)]} {
+		set macro_hooks [dict create]
+		set pdn_hooks [split $::env(FP_PDN_MACRO_HOOKS) ","]
+		foreach pdn_hook $pdn_hooks {
+			set instance_name [lindex $pdn_hook 0]
+			set power_net [lindex $pdn_hook 1]
+			set ground_net [lindex $pdn_hook 2]
+			dict append macro_hooks $instance_name [subst {$power_net $ground_net}]
+		        set power_net_indx [lsearch $::env(VDD_NETS) $power_net]
+		        set ground_net_indx [lsearch $::env(GND_NETS) $ground_net]
+
+		        # make sure that the specified power domains exist.
+		        if { $power_net_indx == -1  || $ground_net_indx == -1 || $power_net_indx != $ground_net_indx } {
+		        	puts_err "Can't find $power_net and $ground_net domain. \
+		        	Make sure that both exist in $::env(VDD_NETS) and $::env(GND_NETS)." 
+		        } 
+		}
+		
+	}
+	
+	# generate multiple power grids per pair of (VDD,GND)
+	# offseted by WIDTH + SPACING
+	foreach vdd $::env(VDD_NETS) gnd $::env(GND_NETS) {
+		set ::env(VDD_NET) $vdd
+		set ::env(GND_NET) $gnd
+	        puts_info "Connecting Power: $vdd & gnd to All internal macros."
+
+		# internal macros power connections
+		set ::env(FP_PDN_MACROS) ""
+		if { $::env(FP_PDN_ENABLE_MACROS_GRID) == 1 } {
+			# if macros connections to power are explicitly set
+			# default behavoir macro pins will be connected to the first power domain
+			if { [info exists ::env(FP_PDN_MACRO_HOOKS)] } {
+				set ::env(FP_PDN_ENABLE_MACROS_GRID) 0
+				foreach {instance_name hooks} $macro_hooks {
+					set power [lindex $hooks 0]
+					set ground [lindex $hooks 1]			 
+					if { $power == $::env(VDD_NET) && $ground == $::env(GND_NET) } {
+						set ::env(FP_PDN_ENABLE_MACROS_GRID) 1
+						puts_info "Connecting $instance_name to $power and $ground nets."
+						lappend ::env(FP_PDN_MACROS) $instance_name
+					}
+				}
+			} 
+		} else {
+			puts_warn "All internal macros will not be connected to power $vdd & $gnd."
+		}
+		
+		gen_pdn
+
+		set ::env(FP_PDN_ENABLE_RAILS) 0
+		set ::env(FP_PDN_ENABLE_MACROS_GRID) 0
+
+		# allow failure until open_pdks is up to date...
+		catch {set ::env(FP_PDN_VOFFSET) [expr $::env(FP_PDN_VOFFSET)+$::env(FP_PDN_VWIDTH)+$::env(FP_PDN_VSPACING)]}
+		catch {set ::env(FP_PDN_HOFFSET) [expr $::env(FP_PDN_HOFFSET)+$::env(FP_PDN_HWIDTH)+$::env(FP_PDN_HSPACING)]}
+
+		catch {set ::env(FP_PDN_CORE_RING_VOFFSET) \
+			[expr $::env(FP_PDN_CORE_RING_VOFFSET)\
+			+2*($::env(FP_PDN_CORE_RING_VWIDTH)\
+			+max($::env(FP_PDN_CORE_RING_VSPACING), $::env(FP_PDN_CORE_RING_HSPACING)))]}
+		catch {set ::env(FP_PDN_CORE_RING_HOFFSET) [expr $::env(FP_PDN_CORE_RING_HOFFSET)\
+			+2*($::env(FP_PDN_CORE_RING_HWIDTH)+\
+			max($::env(FP_PDN_CORE_RING_VSPACING), $::env(FP_PDN_CORE_RING_HSPACING)))]}
+
+		puts "FP_PDN_VOFFSET: $::env(FP_PDN_VOFFSET)"
+		puts "FP_PDN_HOFFSET: $::env(FP_PDN_VOFFSET)"
+		puts "FP_PDN_CORE_RING_VOFFSET: $::env(FP_PDN_CORE_RING_VOFFSET)"
+		puts "FP_PDN_CORE_RING_HOFFSET: $::env(FP_PDN_CORE_RING_HOFFSET)"
+	}
+	set ::env(FP_PDN_ENABLE_RAILS) 1
+}
+
+
+proc run_floorplan {args} {
+		puts_info "Running Floorplanning..."
+		# |----------------------------------------------------|
+		# |----------------   2. FLOORPLAN   ------------------|
+		# |----------------------------------------------------|
+		#
+		# intial fp
+		init_floorplan
+
+
+		# place io
+		if { [info exists ::env(FP_PIN_ORDER_CFG)] } {
+				place_io_ol
+		} else {
+			if { [info exists ::env(FP_CONTEXT_DEF)] && [info exists ::env(FP_CONTEXT_LEF)] } {
+				place_io
+				global_placement_or
+				place_contextualized_io \
+					-lef $::env(FP_CONTEXT_LEF) \
+					-def $::env(FP_CONTEXT_DEF)
+			} else {
+				place_io
+			}
+		}
+
+		apply_def_template
+
+		if { [info exist ::env(EXTRA_LEFS)] } {
+			if { [info exist ::env(MACRO_PLACEMENT_CFG)] } {
+				file copy -force $::env(MACRO_PLACEMENT_CFG) $::env(TMP_DIR)/macro_placement.cfg
+				manual_macro_placement f
+			} else {
+				global_placement_or
+				basic_macro_placement
+			}
+		}
+
+		# tapcell
+		tap_decap_or
+		scrot_klayout -layout $::env(CURRENT_DEF)
+		# power grid generation
+		run_power_grid_generation
+}
+
+proc run_flow {args} {
+       set script_dir [file dirname [file normalize [info script]]]
+
+		set options {
+		{-design required}
+		{-save_path optional}
+		{-no_lvs optional}
+	    {-no_drc optional}
+	    {-no_antennacheck optional}
+	}
+	set flags {-save}
+	parse_key_args "run_flow" args arg_values $options flags_map $flags -no_consume
+
+	prep {*}$args
+
+        set LVS_ENABLED 1
+        set DRC_ENABLED 0
+        set ANTENNACHECK_ENABLED 1
+
+        set steps [dict create "synthesis" {run_synthesis "" } \
+                "floorplan" {run_floorplan ""} \
+                "placement" {run_placement_step ""} \
+                "cts" {run_cts_step ""} \
+                "routing" {run_routing_step ""}\
+                "diode_insertion" {run_diode_insertion_2_5_step ""} \
+                "power_pins_insertion" {run_power_pins_insertion_step ""} \
+                "gds_magic" {run_magic ""} \
+                "gds_drc_klayout" {run_klayout ""} \
+                "gds_xor_klayout" {run_klayout_gds_xor ""} \
+                "lvs" "run_lvs_step $LVS_ENABLED" \
+                "drc" "run_drc_step $DRC_ENABLED" \
+                "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED" \
+                "cvc" {run_lef_cvc}
+        ]
+
+       set_if_unset arg_values(-to) "cvc";
+
+       if {  [info exists ::env(CURRENT_STEP) ] } {
+           puts "\[INFO\]:Picking up where last execution left off"
+           puts [format "\[INFO\]:Current stage is %s " $::env(CURRENT_STEP)]
+       } else {
+           set ::env(CURRENT_STEP) "synthesis";
+       }
+       set_if_unset arg_values(-from) $::env(CURRENT_STEP);
+       set exe 0;
+       dict for {step_name step_exe} $steps {
+           if { [ string equal $arg_values(-from) $step_name ] } {
+               set exe 1;
+           }
+
+           if { $exe } {
+               # For when it fails
+               set ::env(CURRENT_STEP) $step_name
+               [lindex $step_exe 0] [lindex $step_exe 1] ;
+           }
+
+           if { [ string equal $arg_values(-to) $step_name ] } {
+               set exe 0:
+               break;
+           }
+
+       }
+
+       # for when it resumes
+       set steps_as_list [dict keys $steps]
+       set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
+       set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
+
+	if {  [info exists flags_map(-save) ] } {
+		if { ! [info exists arg_values(-save_path)] } {
+			set arg_values(-save_path) ""
+		}
+		save_views 	-lef_path $::env(magic_result_file_tag).lef \
+			-def_path $::env(CURRENT_DEF) \
+			-gds_path $::env(magic_result_file_tag).gds \
+			-mag_path $::env(magic_result_file_tag).mag \
+			-maglef_path $::env(magic_result_file_tag).lef.mag \
+			-spice_path $::env(magic_result_file_tag).spice \
+			-spef_path $::env(CURRENT_SPEF) \
+			-verilog_path $::env(CURRENT_NETLIST) \
+			-save_path $arg_values(-save_path) \
+			-tag $::env(RUN_TAG)
+	}
+
+
+	calc_total_runtime
+	save_state
+	generate_final_summary_report
+	
+	check_timing_violations
+
+	puts_success "Flow Completed Without Fatal Errors."
+
+}
+
+run_flow {*}$argv
diff --git a/openlane/wb_interconnect/pdn.tcl b/openlane/wb_interconnect/pdn.tcl
new file mode 100644
index 0000000..1fe689b
--- /dev/null
+++ b/openlane/wb_interconnect/pdn.tcl
@@ -0,0 +1,49 @@
+# 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
+
+# Power nets
+set ::power_nets $::env(VDD_PIN)
+set ::ground_nets $::env(GND_PIN)
+
+set ::macro_blockage_layer_list "li1 met1 met2 met3 met4 met5"
+
+pdngen::specify_grid stdcell {
+    name grid
+    rails {
+	    met1 {width 0.48 pitch $::env(PLACE_SITE_HEIGHT) offset 0}
+    }
+    straps {
+	    met4 {width 1.6 pitch $::env(FP_PDN_VPITCH) offset $::env(FP_PDN_VOFFSET)}
+	    met5 {width 1.6 pitch $::env(FP_PDN_HPITCH) offset $::env(FP_PDN_HOFFSET)}
+    }
+    connect {{met1 met4} {met4 met5}}
+}
+
+pdngen::specify_grid macro {
+    power_pins "VPWR"
+    ground_pins "VGND"
+    blockages "li1 met1 met2 met3 met4"
+    straps { 
+    } 
+    connect {{met4_PIN_ver met5}}
+}
+
+set ::halo 5
+
+# POWER or GROUND #Std. cell rails starting with power or ground rails at the bottom of the core area
+set ::rails_start_with "POWER" ;
+
+# POWER or GROUND #Upper metal stripes starting with power or ground rails at the left/bottom of the core area
+set ::stripes_start_with "POWER" ;
diff --git a/openlane/wb_interconnect/pin_order.cfg b/openlane/wb_interconnect/pin_order.cfg
new file mode 100644
index 0000000..9f2007f
--- /dev/null
+++ b/openlane/wb_interconnect/pin_order.cfg
@@ -0,0 +1,1084 @@
+#BUS_SORT
+
+#MANUAL_PLACE
+
+#S
+rst_n                000  0 2
+dcache_remap\[3\]
+dcache_remap\[2\]
+dcache_remap\[1\]
+dcache_remap\[0\]
+boot_remap\[3\]
+boot_remap\[2\]
+boot_remap\[1\]
+boot_remap\[0\]
+ch_data_in\[35\]
+ch_data_in\[34\]
+ch_data_in\[33\]
+ch_data_in\[32\]
+ch_data_in\[31\]
+ch_data_in\[30\]
+ch_data_in\[29\]
+ch_data_in\[28\]
+ch_data_in\[27\]
+ch_data_in\[26\]
+ch_data_in\[25\]
+ch_data_in\[24\]
+ch_data_in\[23\]
+ch_data_in\[22\]
+ch_data_in\[21\]
+ch_data_in\[20\]
+ch_data_in\[19\]
+ch_data_in\[18\]
+ch_data_in\[17\]
+ch_data_in\[16\]
+ch_data_in\[15\]
+ch_data_in\[14\]
+ch_data_in\[13\]
+ch_data_in\[12\]
+ch_data_in\[11\]
+ch_data_in\[10\]
+ch_data_in\[9\]
+ch_data_in\[8\]
+ch_data_in\[7\]
+ch_data_in\[6\]
+ch_data_in\[5\]
+ch_data_in\[4\]
+ch_data_in\[3\]
+ch_data_in\[2\]
+ch_data_in\[1\]
+ch_data_in\[0\]
+cfg_cska_wi\[3\]     
+cfg_cska_wi\[2\]     
+cfg_cska_wi\[1\]     
+cfg_cska_wi\[0\] 
+ch_clk_in\[7\]
+ch_clk_in\[6\]
+ch_clk_in\[5\]
+ch_clk_in\[4\]
+ch_clk_in\[3\]
+ch_clk_in\[2\]
+ch_clk_in\[1\]
+ch_clk_in\[0\]
+wbd_clk_int
+wbd_clk_wi    
+clk_i               
+
+
+m0_wbd_stb_i         060 0 2
+m0_wbd_we_i         
+m0_wbd_adr_i\[31\]  
+m0_wbd_adr_i\[30\]  
+m0_wbd_adr_i\[29\]  
+m0_wbd_adr_i\[28\]  
+m0_wbd_adr_i\[27\]  
+m0_wbd_adr_i\[26\]  
+m0_wbd_adr_i\[25\]  
+m0_wbd_adr_i\[24\]  
+m0_wbd_adr_i\[23\]  
+m0_wbd_adr_i\[22\]  
+m0_wbd_adr_i\[21\]  
+m0_wbd_adr_i\[20\]  
+m0_wbd_adr_i\[19\]  
+m0_wbd_adr_i\[18\]  
+m0_wbd_adr_i\[17\]  
+m0_wbd_adr_i\[16\]  
+m0_wbd_adr_i\[15\]  
+m0_wbd_adr_i\[14\]  
+m0_wbd_adr_i\[13\]  
+m0_wbd_adr_i\[12\]  
+m0_wbd_adr_i\[11\]  
+m0_wbd_adr_i\[10\]  
+m0_wbd_adr_i\[9\]   
+m0_wbd_adr_i\[8\]   
+m0_wbd_adr_i\[7\]   
+m0_wbd_adr_i\[6\]   
+m0_wbd_adr_i\[5\]   
+m0_wbd_adr_i\[4\]   
+m0_wbd_adr_i\[3\]   
+m0_wbd_adr_i\[2\]   
+m0_wbd_adr_i\[1\]   
+m0_wbd_adr_i\[0\]   
+m0_wbd_sel_i\[3\]   
+m0_wbd_sel_i\[2\]   
+m0_wbd_sel_i\[1\]   
+m0_wbd_sel_i\[0\]   
+m0_wbd_dat_i\[31\]  
+m0_wbd_dat_i\[30\]  
+m0_wbd_dat_i\[29\]  
+m0_wbd_dat_i\[28\]  
+m0_wbd_dat_i\[27\]  
+m0_wbd_dat_i\[26\]  
+m0_wbd_dat_i\[25\]  
+m0_wbd_dat_i\[24\]  
+m0_wbd_dat_i\[23\]  
+m0_wbd_dat_i\[22\]  
+m0_wbd_dat_i\[21\]  
+m0_wbd_dat_i\[20\]  
+m0_wbd_dat_i\[19\]  
+m0_wbd_dat_i\[18\]  
+m0_wbd_dat_i\[17\]  
+m0_wbd_dat_i\[16\]  
+m0_wbd_dat_i\[15\]  
+m0_wbd_dat_i\[14\]  
+m0_wbd_dat_i\[13\]  
+m0_wbd_dat_i\[12\]  
+m0_wbd_dat_i\[11\]  
+m0_wbd_dat_i\[10\]  
+m0_wbd_dat_i\[9\]   
+m0_wbd_dat_i\[8\]   
+m0_wbd_dat_i\[7\]   
+m0_wbd_dat_i\[6\]   
+m0_wbd_dat_i\[5\]   
+m0_wbd_dat_i\[4\]   
+m0_wbd_dat_i\[3\]   
+m0_wbd_dat_i\[2\]   
+m0_wbd_dat_i\[1\]   
+m0_wbd_dat_i\[0\]   
+m0_wbd_dat_o\[31\]  
+m0_wbd_dat_o\[30\]  
+m0_wbd_dat_o\[29\]  
+m0_wbd_dat_o\[28\]  
+m0_wbd_dat_o\[27\]  
+m0_wbd_dat_o\[26\]  
+m0_wbd_dat_o\[25\]  
+m0_wbd_dat_o\[24\]  
+m0_wbd_dat_o\[23\]  
+m0_wbd_dat_o\[22\]  
+m0_wbd_dat_o\[21\]  
+m0_wbd_dat_o\[20\]  
+m0_wbd_dat_o\[19\]  
+m0_wbd_dat_o\[18\]  
+m0_wbd_dat_o\[17\]  
+m0_wbd_dat_o\[16\]  
+m0_wbd_dat_o\[15\]  
+m0_wbd_dat_o\[14\]  
+m0_wbd_dat_o\[13\]  
+m0_wbd_dat_o\[12\]  
+m0_wbd_dat_o\[11\]  
+m0_wbd_dat_o\[10\]  
+m0_wbd_dat_o\[9\]   
+m0_wbd_dat_o\[8\]   
+m0_wbd_dat_o\[7\]   
+m0_wbd_dat_o\[6\]   
+m0_wbd_dat_o\[5\]   
+m0_wbd_dat_o\[4\]   
+m0_wbd_dat_o\[3\]   
+m0_wbd_dat_o\[2\]   
+m0_wbd_dat_o\[1\]   
+m0_wbd_dat_o\[0\]   
+m0_wbd_ack_o        
+m0_wbd_lack_o        
+m0_wbd_err_o        
+m0_wbd_cyc_i        
+
+
+
+#W
+ch_data_out\[84\]   0250 0 2
+ch_data_out\[83\]   
+ch_data_out\[82\]   
+ch_data_out\[81\]   
+ch_data_out\[80\]   
+ch_data_out\[79\]   
+ch_data_out\[78\]   
+ch_data_out\[77\]   
+ch_data_out\[76\]   
+ch_data_out\[75\]   
+ch_data_out\[74\]   
+ch_data_out\[73\]   
+ch_data_out\[72\]   
+ch_data_out\[71\]   
+ch_data_out\[70\]   
+ch_data_out\[69\]   
+ch_data_out\[68\]   
+ch_data_out\[67\]   
+ch_data_out\[66\]   
+ch_data_out\[65\]   
+ch_data_out\[64\]   
+ch_data_out\[63\]   
+ch_data_out\[62\]   
+ch_data_out\[61\]   
+ch_data_out\[60\]   
+ch_data_out\[59\]   
+ch_data_out\[58\]   
+ch_data_out\[57\]   
+ch_data_out\[56\]   
+ch_data_out\[55\]   
+ch_data_out\[54\]   
+ch_data_out\[53\]   
+ch_data_out\[52\]   
+ch_data_out\[51\]   
+ch_data_out\[50\]   
+ch_data_out\[49\]   
+ch_data_out\[48\]   
+ch_data_out\[47\]   
+ch_data_out\[46\]   
+ch_data_out\[45\]   
+ch_data_out\[44\]   
+ch_data_out\[43\]   
+ch_data_out\[42\]   
+ch_data_out\[41\]   
+ch_data_out\[40\]   
+ch_data_out\[39\]   
+ch_data_out\[38\]   
+ch_data_out\[37\]   
+ch_data_out\[36\]   
+
+ch_data_out\[3\]   
+ch_data_out\[2\]
+ch_data_out\[1\]
+ch_data_out\[0\]
+
+ch_clk_out\[0\]
+
+m1_wbd_stb_i         0450 0 2 
+m1_wbd_we_i         
+m1_wbd_adr_i\[31\]  
+m1_wbd_adr_i\[30\]  
+m1_wbd_adr_i\[29\]  
+m1_wbd_adr_i\[28\]  
+m1_wbd_adr_i\[27\]  
+m1_wbd_adr_i\[26\]  
+m1_wbd_adr_i\[25\]  
+m1_wbd_adr_i\[24\]  
+m1_wbd_adr_i\[23\]  
+m1_wbd_adr_i\[22\]  
+m1_wbd_adr_i\[21\]  
+m1_wbd_adr_i\[20\]  
+m1_wbd_adr_i\[19\]  
+m1_wbd_adr_i\[18\]  
+m1_wbd_adr_i\[17\]  
+m1_wbd_adr_i\[16\]  
+m1_wbd_adr_i\[15\]  
+m1_wbd_adr_i\[14\]  
+m1_wbd_adr_i\[13\]  
+m1_wbd_adr_i\[12\]  
+m1_wbd_adr_i\[11\]  
+m1_wbd_adr_i\[10\]  
+m1_wbd_adr_i\[9\]   
+m1_wbd_adr_i\[8\]   
+m1_wbd_adr_i\[7\]   
+m1_wbd_adr_i\[6\]   
+m1_wbd_adr_i\[5\]   
+m1_wbd_adr_i\[4\]   
+m1_wbd_adr_i\[3\]   
+m1_wbd_adr_i\[2\]   
+m1_wbd_adr_i\[1\]   
+m1_wbd_adr_i\[0\]   
+m1_wbd_sel_i\[3\]   
+m1_wbd_sel_i\[2\]   
+m1_wbd_sel_i\[1\]   
+m1_wbd_sel_i\[0\]   
+m1_wbd_dat_i\[31\]  
+m1_wbd_dat_i\[30\]  
+m1_wbd_dat_i\[29\]  
+m1_wbd_dat_i\[28\]  
+m1_wbd_dat_i\[27\]  
+m1_wbd_dat_i\[26\]  
+m1_wbd_dat_i\[25\]  
+m1_wbd_dat_i\[24\]  
+m1_wbd_dat_i\[23\]  
+m1_wbd_dat_i\[22\]  
+m1_wbd_dat_i\[21\]  
+m1_wbd_dat_i\[20\]  
+m1_wbd_dat_i\[19\]  
+m1_wbd_dat_i\[18\]  
+m1_wbd_dat_i\[17\]  
+m1_wbd_dat_i\[16\]  
+m1_wbd_dat_i\[15\]  
+m1_wbd_dat_i\[14\]  
+m1_wbd_dat_i\[13\]  
+m1_wbd_dat_i\[12\]  
+m1_wbd_dat_i\[11\]  
+m1_wbd_dat_i\[10\]  
+m1_wbd_dat_i\[9\]   
+m1_wbd_dat_i\[8\]   
+m1_wbd_dat_i\[7\]   
+m1_wbd_dat_i\[6\]   
+m1_wbd_dat_i\[5\]   
+m1_wbd_dat_i\[4\]   
+m1_wbd_dat_i\[3\]   
+m1_wbd_dat_i\[2\]   
+m1_wbd_dat_i\[1\]   
+m1_wbd_dat_i\[0\]   
+m1_wbd_dat_o\[31\]  
+m1_wbd_dat_o\[30\]  
+m1_wbd_dat_o\[29\]  
+m1_wbd_dat_o\[28\]  
+m1_wbd_dat_o\[27\]  
+m1_wbd_dat_o\[26\]  
+m1_wbd_dat_o\[25\]  
+m1_wbd_dat_o\[24\]  
+m1_wbd_dat_o\[23\]  
+m1_wbd_dat_o\[22\]  
+m1_wbd_dat_o\[21\]  
+m1_wbd_dat_o\[20\]  
+m1_wbd_dat_o\[19\]  
+m1_wbd_dat_o\[18\]  
+m1_wbd_dat_o\[17\]  
+m1_wbd_dat_o\[16\]  
+m1_wbd_dat_o\[15\]  
+m1_wbd_dat_o\[14\]  
+m1_wbd_dat_o\[13\]  
+m1_wbd_dat_o\[12\]  
+m1_wbd_dat_o\[11\]  
+m1_wbd_dat_o\[10\]  
+m1_wbd_dat_o\[9\]   
+m1_wbd_dat_o\[8\]   
+m1_wbd_dat_o\[7\]   
+m1_wbd_dat_o\[6\]   
+m1_wbd_dat_o\[5\]   
+m1_wbd_dat_o\[4\]   
+m1_wbd_dat_o\[3\]   
+m1_wbd_dat_o\[2\]   
+m1_wbd_dat_o\[1\]   
+m1_wbd_dat_o\[0\]   
+m1_wbd_ack_o        
+m1_wbd_lack_o        
+m1_wbd_err_o        
+m1_wbd_cyc_i        
+
+m2_wbd_stb_i        0650 0 2
+m2_wbd_we_i         
+m2_wbd_adr_i\[31\]  
+m2_wbd_adr_i\[30\]  
+m2_wbd_adr_i\[29\]  
+m2_wbd_adr_i\[28\]  
+m2_wbd_adr_i\[27\]  
+m2_wbd_adr_i\[26\]  
+m2_wbd_adr_i\[25\]  
+m2_wbd_adr_i\[24\]  
+m2_wbd_adr_i\[23\]  
+m2_wbd_adr_i\[22\]  
+m2_wbd_adr_i\[21\]  
+m2_wbd_adr_i\[20\]  
+m2_wbd_adr_i\[19\]  
+m2_wbd_adr_i\[18\]  
+m2_wbd_adr_i\[17\]  
+m2_wbd_adr_i\[16\]  
+m2_wbd_adr_i\[15\]  
+m2_wbd_adr_i\[14\]  
+m2_wbd_adr_i\[13\]  
+m2_wbd_adr_i\[12\]  
+m2_wbd_adr_i\[11\]  
+m2_wbd_adr_i\[10\]  
+m2_wbd_adr_i\[9\]   
+m2_wbd_adr_i\[8\]   
+m2_wbd_adr_i\[7\]   
+m2_wbd_adr_i\[6\]   
+m2_wbd_adr_i\[5\]   
+m2_wbd_adr_i\[4\]   
+m2_wbd_adr_i\[3\]   
+m2_wbd_adr_i\[2\]   
+m2_wbd_adr_i\[1\]   
+m2_wbd_adr_i\[0\]   
+m2_wbd_sel_i\[3\]   
+m2_wbd_sel_i\[2\]   
+m2_wbd_sel_i\[1\]   
+m2_wbd_sel_i\[0\]   
+m2_wbd_bl_i\[9\]   
+m2_wbd_bl_i\[8\]   
+m2_wbd_bl_i\[7\]   
+m2_wbd_bl_i\[6\]   
+m2_wbd_bl_i\[5\]   
+m2_wbd_bl_i\[4\]   
+m2_wbd_bl_i\[3\]   
+m2_wbd_bl_i\[2\]   
+m2_wbd_bl_i\[1\]   
+m2_wbd_bl_i\[0\]   
+m2_wbd_bry_i
+m2_wbd_dat_i\[31\]  
+m2_wbd_dat_i\[30\]  
+m2_wbd_dat_i\[29\]  
+m2_wbd_dat_i\[28\]  
+m2_wbd_dat_i\[27\]  
+m2_wbd_dat_i\[26\]  
+m2_wbd_dat_i\[25\]  
+m2_wbd_dat_i\[24\]  
+m2_wbd_dat_i\[23\]  
+m2_wbd_dat_i\[22\]  
+m2_wbd_dat_i\[21\]  
+m2_wbd_dat_i\[20\]  
+m2_wbd_dat_i\[19\]  
+m2_wbd_dat_i\[18\]  
+m2_wbd_dat_i\[17\]  
+m2_wbd_dat_i\[16\]  
+m2_wbd_dat_i\[15\]  
+m2_wbd_dat_i\[14\]  
+m2_wbd_dat_i\[13\]  
+m2_wbd_dat_i\[12\]  
+m2_wbd_dat_i\[11\]  
+m2_wbd_dat_i\[10\]  
+m2_wbd_dat_i\[9\]   
+m2_wbd_dat_i\[8\]   
+m2_wbd_dat_i\[7\]   
+m2_wbd_dat_i\[6\]   
+m2_wbd_dat_i\[5\]   
+m2_wbd_dat_i\[4\]   
+m2_wbd_dat_i\[3\]   
+m2_wbd_dat_i\[2\]   
+m2_wbd_dat_i\[1\]   
+m2_wbd_dat_i\[0\]   
+m2_wbd_dat_o\[31\]  
+m2_wbd_dat_o\[30\]  
+m2_wbd_dat_o\[29\]  
+m2_wbd_dat_o\[28\]  
+m2_wbd_dat_o\[27\]  
+m2_wbd_dat_o\[26\]  
+m2_wbd_dat_o\[25\]  
+m2_wbd_dat_o\[24\]  
+m2_wbd_dat_o\[23\]  
+m2_wbd_dat_o\[22\]  
+m2_wbd_dat_o\[21\]  
+m2_wbd_dat_o\[20\]  
+m2_wbd_dat_o\[19\]  
+m2_wbd_dat_o\[18\]  
+m2_wbd_dat_o\[17\]  
+m2_wbd_dat_o\[16\]  
+m2_wbd_dat_o\[15\]  
+m2_wbd_dat_o\[14\]  
+m2_wbd_dat_o\[13\]  
+m2_wbd_dat_o\[12\]  
+m2_wbd_dat_o\[11\]  
+m2_wbd_dat_o\[10\]  
+m2_wbd_dat_o\[9\]   
+m2_wbd_dat_o\[8\]   
+m2_wbd_dat_o\[7\]   
+m2_wbd_dat_o\[6\]   
+m2_wbd_dat_o\[5\]   
+m2_wbd_dat_o\[4\]   
+m2_wbd_dat_o\[3\]   
+m2_wbd_dat_o\[2\]   
+m2_wbd_dat_o\[1\]   
+m2_wbd_dat_o\[0\]   
+m2_wbd_ack_o        
+m2_wbd_lack_o        
+m2_wbd_err_o        
+m2_wbd_cyc_i       
+
+m3_wbd_stb_i        0850 0 2
+m3_wbd_we_i         
+m3_wbd_adr_i\[31\]  
+m3_wbd_adr_i\[30\]  
+m3_wbd_adr_i\[29\]  
+m3_wbd_adr_i\[28\]  
+m3_wbd_adr_i\[27\]  
+m3_wbd_adr_i\[26\]  
+m3_wbd_adr_i\[25\]  
+m3_wbd_adr_i\[24\]  
+m3_wbd_adr_i\[23\]  
+m3_wbd_adr_i\[22\]  
+m3_wbd_adr_i\[21\]  
+m3_wbd_adr_i\[20\]  
+m3_wbd_adr_i\[19\]  
+m3_wbd_adr_i\[18\]  
+m3_wbd_adr_i\[17\]  
+m3_wbd_adr_i\[16\]  
+m3_wbd_adr_i\[15\]  
+m3_wbd_adr_i\[14\]  
+m3_wbd_adr_i\[13\]  
+m3_wbd_adr_i\[12\]  
+m3_wbd_adr_i\[11\]  
+m3_wbd_adr_i\[10\]  
+m3_wbd_adr_i\[9\]   
+m3_wbd_adr_i\[8\]   
+m3_wbd_adr_i\[7\]   
+m3_wbd_adr_i\[6\]   
+m3_wbd_adr_i\[5\]   
+m3_wbd_adr_i\[4\]   
+m3_wbd_adr_i\[3\]   
+m3_wbd_adr_i\[2\]   
+m3_wbd_adr_i\[1\]   
+m3_wbd_adr_i\[0\]   
+m3_wbd_sel_i\[3\]   
+m3_wbd_sel_i\[2\]   
+m3_wbd_sel_i\[1\]   
+m3_wbd_sel_i\[0\]   
+m3_wbd_bl_i\[9\]   
+m3_wbd_bl_i\[8\]   
+m3_wbd_bl_i\[7\]   
+m3_wbd_bl_i\[6\]   
+m3_wbd_bl_i\[5\]   
+m3_wbd_bl_i\[4\]   
+m3_wbd_bl_i\[3\]   
+m3_wbd_bl_i\[2\]   
+m3_wbd_bl_i\[1\]   
+m3_wbd_bl_i\[0\]   
+m3_wbd_bry_i
+m3_wbd_dat_o\[31\]  
+m3_wbd_dat_o\[30\]  
+m3_wbd_dat_o\[29\]  
+m3_wbd_dat_o\[28\]  
+m3_wbd_dat_o\[27\]  
+m3_wbd_dat_o\[26\]  
+m3_wbd_dat_o\[25\]  
+m3_wbd_dat_o\[24\]  
+m3_wbd_dat_o\[23\]  
+m3_wbd_dat_o\[22\]  
+m3_wbd_dat_o\[21\]  
+m3_wbd_dat_o\[20\]  
+m3_wbd_dat_o\[19\]  
+m3_wbd_dat_o\[18\]  
+m3_wbd_dat_o\[17\]  
+m3_wbd_dat_o\[16\]  
+m3_wbd_dat_o\[15\]  
+m3_wbd_dat_o\[14\]  
+m3_wbd_dat_o\[13\]  
+m3_wbd_dat_o\[12\]  
+m3_wbd_dat_o\[11\]  
+m3_wbd_dat_o\[10\]  
+m3_wbd_dat_o\[9\]   
+m3_wbd_dat_o\[8\]   
+m3_wbd_dat_o\[7\]   
+m3_wbd_dat_o\[6\]   
+m3_wbd_dat_o\[5\]   
+m3_wbd_dat_o\[4\]   
+m3_wbd_dat_o\[3\]   
+m3_wbd_dat_o\[2\]   
+m3_wbd_dat_o\[1\]   
+m3_wbd_dat_o\[0\]   
+m3_wbd_ack_o        
+m3_wbd_lack_o        
+m3_wbd_err_o        
+m3_wbd_cyc_i       
+
+ch_data_out\[23\]   1950 0 2
+ch_data_out\[22\]
+ch_data_out\[21\]
+ch_data_out\[20\]
+ch_clk_out\[4\]     
+
+s3_wbd_cyc_o        1975 0 2
+s3_wbd_stb_o        
+s3_wbd_we_o         
+s3_wbd_adr_o\[12\]   
+s3_wbd_adr_o\[11\]   
+s3_wbd_adr_o\[10\]   
+s3_wbd_adr_o\[9\]   
+s3_wbd_adr_o\[8\]   
+s3_wbd_adr_o\[7\]   
+s3_wbd_adr_o\[6\]   
+s3_wbd_adr_o\[5\]   
+s3_wbd_adr_o\[4\]   
+s3_wbd_adr_o\[3\]   
+s3_wbd_adr_o\[2\]   
+s3_wbd_adr_o\[1\]   
+s3_wbd_adr_o\[0\]   
+s3_wbd_dat_o\[31\]  
+s3_wbd_dat_o\[30\]  
+s3_wbd_dat_o\[29\]  
+s3_wbd_dat_o\[28\]  
+s3_wbd_dat_o\[27\]  
+s3_wbd_dat_o\[26\]  
+s3_wbd_dat_o\[25\]  
+s3_wbd_dat_o\[24\]  
+s3_wbd_dat_o\[23\]  
+s3_wbd_dat_o\[22\]  
+s3_wbd_dat_o\[21\]  
+s3_wbd_dat_o\[20\]  
+s3_wbd_dat_o\[19\]  
+s3_wbd_dat_o\[18\]  
+s3_wbd_dat_o\[17\]  
+s3_wbd_dat_o\[16\]  
+s3_wbd_dat_o\[15\]  
+s3_wbd_dat_o\[14\]  
+s3_wbd_dat_o\[13\]  
+s3_wbd_dat_o\[12\]  
+s3_wbd_dat_o\[11\]  
+s3_wbd_dat_o\[10\]  
+s3_wbd_dat_o\[9\]   
+s3_wbd_dat_o\[8\]   
+s3_wbd_dat_o\[7\]   
+s3_wbd_dat_o\[6\]   
+s3_wbd_dat_o\[5\]   
+s3_wbd_dat_o\[4\]   
+s3_wbd_dat_o\[3\]   
+s3_wbd_dat_o\[2\]   
+s3_wbd_dat_o\[1\]   
+s3_wbd_dat_o\[0\]   
+s3_wbd_sel_o\[3\]   
+s3_wbd_sel_o\[2\]   
+s3_wbd_sel_o\[1\]   
+s3_wbd_sel_o\[0\]   
+s3_wbd_bl_o\[9\]   
+s3_wbd_bl_o\[8\]   
+s3_wbd_bl_o\[7\]   
+s3_wbd_bl_o\[6\]   
+s3_wbd_bl_o\[5\]   
+s3_wbd_bl_o\[4\]   
+s3_wbd_bl_o\[3\]   
+s3_wbd_bl_o\[2\]   
+s3_wbd_bl_o\[1\]   
+s3_wbd_bl_o\[0\]   
+s3_wbd_bry_o
+s3_wbd_dat_i\[31\]  
+s3_wbd_dat_i\[30\]  
+s3_wbd_dat_i\[29\]  
+s3_wbd_dat_i\[28\]  
+s3_wbd_dat_i\[27\]  
+s3_wbd_dat_i\[26\]  
+s3_wbd_dat_i\[25\]  
+s3_wbd_dat_i\[24\]  
+s3_wbd_dat_i\[23\]  
+s3_wbd_dat_i\[22\] 
+s3_wbd_dat_i\[21\]  
+s3_wbd_dat_i\[20\]  
+s3_wbd_dat_i\[19\]  
+s3_wbd_dat_i\[18\]  
+s3_wbd_dat_i\[17\]  
+s3_wbd_dat_i\[16\]  
+s3_wbd_dat_i\[15\]  
+s3_wbd_dat_i\[14\]  
+s3_wbd_dat_i\[13\]  
+s3_wbd_dat_i\[12\]  
+s3_wbd_dat_i\[11\]  
+s3_wbd_dat_i\[10\]  
+s3_wbd_dat_i\[9\]   
+s3_wbd_dat_i\[8\]   
+s3_wbd_dat_i\[7\]   
+s3_wbd_dat_i\[6\]   
+s3_wbd_dat_i\[5\]   
+s3_wbd_dat_i\[4\]   
+s3_wbd_dat_i\[3\]   
+s3_wbd_dat_i\[2\]   
+s3_wbd_dat_i\[1\]   
+s3_wbd_dat_i\[0\]   
+s3_wbd_ack_i        
+s3_wbd_lack_i        
+
+ch_data_in\[115\]   2110 0 2
+ch_data_in\[114\] 
+ch_data_in\[113\] 
+ch_data_in\[112\] 
+ch_data_in\[111\] 
+ch_data_in\[110\] 
+ch_data_in\[109\] 
+ch_data_in\[108\] 
+ch_data_in\[107\] 
+ch_data_in\[106\] 
+ch_data_in\[105\] 
+ch_data_in\[104\] 
+ch_data_in\[103\] 
+ch_data_in\[102\] 
+ch_data_in\[101\] 
+ch_data_in\[100\] 
+ch_data_in\[99\] 
+ch_data_in\[98\] 
+ch_data_in\[97\] 
+ch_data_in\[96\] 
+ch_data_in\[95\] 
+ch_data_in\[94\] 
+ch_data_in\[93\] 
+ch_data_in\[92\] 
+ch_data_in\[91\] 
+ch_data_in\[90\] 
+ch_data_out\[89\] 
+ch_data_out\[88\] 
+ch_data_out\[87\] 
+ch_data_out\[86\] 
+ch_data_out\[85\] 
+
+
+
+ch_clk_out\[5\]    2200 0 2
+ch_clk_out\[6\]
+ch_clk_out\[7\]
+ch_data_out\[24\]
+ch_data_out\[25\]
+ch_data_out\[26\]
+ch_data_out\[27\]
+ch_data_out\[28\]
+ch_data_out\[29\]
+ch_data_out\[30\]
+ch_data_out\[31\]
+ch_data_out\[32\]
+ch_data_out\[33\]
+ch_data_out\[34\]
+ch_data_out\[35\]
+
+#E
+ch_data_out\[19\]   0000 0  2  
+ch_data_out\[18\]
+ch_data_out\[17\]
+ch_data_out\[16\]
+ch_data_out\[7\]    
+ch_data_out\[6\]
+ch_data_out\[5\]
+ch_data_out\[4\]
+ch_clk_out\[1\]
+
+s0_wbd_stb_o         0100 0 2
+s0_wbd_we_o         
+s0_wbd_adr_o\[31\]  
+s0_wbd_adr_o\[30\]  
+s0_wbd_adr_o\[29\]  
+s0_wbd_adr_o\[28\]  
+s0_wbd_adr_o\[27\]  
+s0_wbd_adr_o\[26\]  
+s0_wbd_adr_o\[25\]  
+s0_wbd_adr_o\[24\]  
+s0_wbd_adr_o\[23\]  
+s0_wbd_adr_o\[22\]  
+s0_wbd_adr_o\[21\]  
+s0_wbd_adr_o\[20\]  
+s0_wbd_adr_o\[19\]  
+s0_wbd_adr_o\[18\]  
+s0_wbd_adr_o\[17\]  
+s0_wbd_adr_o\[16\]  
+s0_wbd_adr_o\[15\]  
+s0_wbd_adr_o\[14\]  
+s0_wbd_adr_o\[13\]  
+s0_wbd_adr_o\[12\]  
+s0_wbd_adr_o\[11\]  
+s0_wbd_adr_o\[10\]  
+s0_wbd_adr_o\[9\]   
+s0_wbd_adr_o\[8\]   
+s0_wbd_adr_o\[7\]   
+s0_wbd_adr_o\[6\]   
+s0_wbd_adr_o\[5\]   
+s0_wbd_adr_o\[4\]   
+s0_wbd_adr_o\[3\]   
+s0_wbd_adr_o\[2\]   
+s0_wbd_adr_o\[1\]   
+s0_wbd_adr_o\[0\]   
+s0_wbd_sel_o\[3\]   
+s0_wbd_sel_o\[2\]   
+s0_wbd_sel_o\[1\]   
+s0_wbd_sel_o\[0\]   
+s0_wbd_bl_o\[9\]   
+s0_wbd_bl_o\[8\]   
+s0_wbd_bl_o\[7\]   
+s0_wbd_bl_o\[6\]   
+s0_wbd_bl_o\[5\]   
+s0_wbd_bl_o\[4\]   
+s0_wbd_bl_o\[3\]   
+s0_wbd_bl_o\[2\]   
+s0_wbd_bl_o\[1\]   
+s0_wbd_bl_o\[0\]   
+s0_wbd_bry_o
+s0_wbd_dat_o\[31\]  
+s0_wbd_dat_o\[30\]  
+s0_wbd_dat_o\[29\]  
+s0_wbd_dat_o\[28\]  
+s0_wbd_dat_o\[27\]  
+s0_wbd_dat_o\[26\]  
+s0_wbd_dat_o\[25\]  
+s0_wbd_dat_o\[24\]  
+s0_wbd_dat_o\[23\]  
+s0_wbd_dat_o\[22\]  
+s0_wbd_dat_o\[21\]  
+s0_wbd_dat_o\[20\]  
+s0_wbd_dat_o\[19\]  
+s0_wbd_dat_o\[18\]  
+s0_wbd_dat_o\[17\]  
+s0_wbd_dat_o\[16\]  
+s0_wbd_dat_o\[15\]  
+s0_wbd_dat_o\[14\]  
+s0_wbd_dat_o\[13\]  
+s0_wbd_dat_o\[12\]  
+s0_wbd_dat_o\[11\]  
+s0_wbd_dat_o\[10\]  
+s0_wbd_dat_o\[9\]   
+s0_wbd_dat_o\[8\]   
+s0_wbd_dat_o\[7\]   
+s0_wbd_dat_o\[6\]   
+s0_wbd_dat_o\[5\]   
+s0_wbd_dat_o\[4\]   
+s0_wbd_dat_o\[3\]   
+s0_wbd_dat_o\[2\]   
+s0_wbd_dat_o\[1\]   
+s0_wbd_dat_o\[0\]   
+s0_wbd_dat_i\[31\]  
+s0_wbd_dat_i\[30\]  
+s0_wbd_dat_i\[29\]  
+s0_wbd_dat_i\[28\]  
+s0_wbd_dat_i\[27\]  
+s0_wbd_dat_i\[26\]  
+s0_wbd_dat_i\[25\]  
+s0_wbd_dat_i\[24\]  
+s0_wbd_dat_i\[23\]  
+s0_wbd_dat_i\[22\]  
+s0_wbd_dat_i\[21\]  
+s0_wbd_dat_i\[20\]  
+s0_wbd_dat_i\[19\]  
+s0_wbd_dat_i\[18\]  
+s0_wbd_dat_i\[17\]  
+s0_wbd_dat_i\[16\]  
+s0_wbd_dat_i\[15\]  
+s0_wbd_dat_i\[14\]  
+s0_wbd_dat_i\[13\]  
+s0_wbd_dat_i\[12\]  
+s0_wbd_dat_i\[11\]  
+s0_wbd_dat_i\[10\]  
+s0_wbd_dat_i\[9\]   
+s0_wbd_dat_i\[8\]   
+s0_wbd_dat_i\[7\]   
+s0_wbd_dat_i\[6\]   
+s0_wbd_dat_i\[5\]   
+s0_wbd_dat_i\[4\]   
+s0_wbd_dat_i\[3\]   
+s0_wbd_dat_i\[2\]   
+s0_wbd_dat_i\[1\]   
+s0_wbd_dat_i\[0\]   
+s0_wbd_ack_i        
+s0_wbd_lack_i        
+s0_wbd_cyc_o        
+
+
+ch_data_out\[11\]    0700 0  2  
+ch_data_out\[10\]
+ch_data_out\[9\]
+ch_data_out\[8\]
+ch_clk_out\[2\]
+
+s1_wbd_stb_o          0800 0 2
+s1_wbd_we_o         
+s1_wbd_adr_o\[7\]   
+s1_wbd_adr_o\[6\]   
+s1_wbd_adr_o\[5\]   
+s1_wbd_adr_o\[4\]   
+s1_wbd_adr_o\[3\]   
+s1_wbd_adr_o\[2\]   
+s1_wbd_adr_o\[1\]   
+s1_wbd_adr_o\[0\]   
+s1_wbd_sel_o\[3\]   
+s1_wbd_sel_o\[2\]   
+s1_wbd_sel_o\[1\]   
+s1_wbd_sel_o\[0\]   
+s1_wbd_dat_o\[31\]  
+s1_wbd_dat_o\[30\]  
+s1_wbd_dat_o\[29\]  
+s1_wbd_dat_o\[28\]  
+s1_wbd_dat_o\[27\]  
+s1_wbd_dat_o\[26\]  
+s1_wbd_dat_o\[25\]  
+s1_wbd_dat_o\[24\]  
+s1_wbd_dat_o\[23\]  
+s1_wbd_dat_o\[22\]  
+s1_wbd_dat_o\[21\]  
+s1_wbd_dat_o\[20\]  
+s1_wbd_dat_o\[19\]  
+s1_wbd_dat_o\[18\]  
+s1_wbd_dat_o\[17\]  
+s1_wbd_dat_o\[16\]  
+s1_wbd_dat_o\[15\]  
+s1_wbd_dat_o\[14\]  
+s1_wbd_dat_o\[13\]  
+s1_wbd_dat_o\[12\]  
+s1_wbd_dat_o\[11\]  
+s1_wbd_dat_o\[10\]  
+s1_wbd_dat_o\[9\]   
+s1_wbd_dat_o\[8\]   
+s1_wbd_dat_o\[7\]   
+s1_wbd_dat_o\[6\]   
+s1_wbd_dat_o\[5\]   
+s1_wbd_dat_o\[4\]   
+s1_wbd_dat_o\[3\]   
+s1_wbd_dat_o\[2\]   
+s1_wbd_dat_o\[1\]   
+s1_wbd_dat_o\[0\]   
+s1_wbd_dat_i\[31\]  
+s1_wbd_dat_i\[30\]  
+s1_wbd_dat_i\[29\]  
+s1_wbd_dat_i\[28\]  
+s1_wbd_dat_i\[27\]  
+s1_wbd_dat_i\[26\]  
+s1_wbd_dat_i\[25\]  
+s1_wbd_dat_i\[24\]  
+s1_wbd_dat_i\[23\]  
+s1_wbd_dat_i\[22\]  
+s1_wbd_dat_i\[21\]  
+s1_wbd_dat_i\[20\]  
+s1_wbd_dat_i\[19\]  
+s1_wbd_dat_i\[18\]  
+s1_wbd_dat_i\[17\]  
+s1_wbd_dat_i\[16\]  
+s1_wbd_dat_i\[15\]  
+s1_wbd_dat_i\[14\]  
+s1_wbd_dat_i\[13\]  
+s1_wbd_dat_i\[12\]  
+s1_wbd_dat_i\[11\]  
+s1_wbd_dat_i\[10\]  
+s1_wbd_dat_i\[9\]   
+s1_wbd_dat_i\[8\]   
+s1_wbd_dat_i\[7\]   
+s1_wbd_dat_i\[6\]   
+s1_wbd_dat_i\[5\]   
+s1_wbd_dat_i\[4\]   
+s1_wbd_dat_i\[3\]   
+s1_wbd_dat_i\[2\]   
+s1_wbd_dat_i\[1\]   
+s1_wbd_dat_i\[0\]   
+s1_wbd_ack_i        
+s1_wbd_cyc_o  
+
+ch_data_out\[115\]  1600 0 2  
+ch_data_out\[114\]
+ch_data_out\[113\]
+ch_data_out\[112\]
+ch_data_out\[111\]
+ch_data_out\[110\]
+ch_data_out\[109\]
+ch_data_out\[108\]
+ch_data_out\[107\]
+ch_data_out\[106\]
+ch_data_out\[105\]
+ch_data_out\[104\]
+ch_data_out\[103\]
+ch_data_out\[102\]
+ch_data_out\[101\]
+ch_data_out\[100\]
+ch_data_out\[99\]
+ch_data_out\[98\]
+ch_data_out\[97\]
+ch_data_out\[96\]
+ch_data_out\[95\]
+ch_data_out\[94\]
+ch_data_out\[93\]
+ch_data_out\[92\]
+ch_data_out\[91\]
+ch_data_out\[90\]
+ch_data_in\[89\]
+ch_data_in\[88\]
+ch_data_in\[87\]
+ch_data_in\[86\]
+ch_data_in\[85\]
+
+ch_data_in\[84\]
+ch_data_in\[83\]
+ch_data_in\[82\]
+ch_data_in\[81\]
+ch_data_in\[80\]
+ch_data_in\[79\]
+ch_data_in\[78\]
+ch_data_in\[77\]
+ch_data_in\[76\]  
+ch_data_in\[75\]
+ch_data_in\[74\]
+ch_data_in\[73\]
+ch_data_in\[72\]
+ch_data_in\[71\]
+ch_data_in\[70\]
+ch_data_in\[69\]
+ch_data_in\[68\]
+ch_data_in\[67\]
+ch_data_in\[66\]
+ch_data_in\[65\]
+ch_data_in\[64\]
+ch_data_in\[63\]
+ch_data_in\[62\]
+ch_data_in\[61\]
+ch_data_in\[60\]
+ch_data_in\[59\]
+ch_data_in\[58\]
+ch_data_in\[57\]
+ch_data_in\[56\]
+ch_data_in\[55\]
+ch_data_in\[54\]
+ch_data_in\[53\]
+ch_data_in\[52\]
+ch_data_in\[51\]
+ch_data_in\[50\]
+ch_data_in\[49\]
+ch_data_in\[48\]
+ch_data_in\[47\]
+ch_data_in\[46\]
+ch_data_in\[45\]
+ch_data_in\[44\]
+ch_data_in\[43\]
+ch_data_in\[42\]
+ch_data_in\[41\]
+ch_data_in\[40\]
+ch_data_in\[39\]
+ch_data_in\[38\]
+ch_data_in\[37\]
+ch_data_in\[36\]
+
+ch_data_out\[15\]    
+ch_data_out\[14\]
+ch_data_out\[13\]
+ch_data_out\[12\]
+ch_clk_out\[3\]
+
+s2_wbd_stb_o         1800 0 2
+s2_wbd_we_o         
+s2_wbd_adr_o\[7\]   
+s2_wbd_adr_o\[6\]   
+s2_wbd_adr_o\[5\]   
+s2_wbd_adr_o\[4\]   
+s2_wbd_adr_o\[3\]   
+s2_wbd_adr_o\[2\]   
+s2_wbd_adr_o\[1\]   
+s2_wbd_adr_o\[0\]   
+s2_wbd_sel_o\[3\]        
+s2_wbd_sel_o\[2\]        
+s2_wbd_sel_o\[1\]        
+s2_wbd_sel_o\[0\]        
+s2_wbd_dat_o\[31\]   
+s2_wbd_dat_o\[30\]   
+s2_wbd_dat_o\[29\]   
+s2_wbd_dat_o\[28\]   
+s2_wbd_dat_o\[27\]   
+s2_wbd_dat_o\[26\]   
+s2_wbd_dat_o\[25\]   
+s2_wbd_dat_o\[24\]   
+s2_wbd_dat_o\[23\]   
+s2_wbd_dat_o\[22\]   
+s2_wbd_dat_o\[21\]   
+s2_wbd_dat_o\[20\]   
+s2_wbd_dat_o\[19\]   
+s2_wbd_dat_o\[18\]   
+s2_wbd_dat_o\[17\]   
+s2_wbd_dat_o\[16\]   
+s2_wbd_dat_o\[15\]   
+s2_wbd_dat_o\[14\]   
+s2_wbd_dat_o\[13\]   
+s2_wbd_dat_o\[12\]   
+s2_wbd_dat_o\[11\]   
+s2_wbd_dat_o\[10\]   
+s2_wbd_dat_o\[9\]   
+s2_wbd_dat_o\[8\]   
+s2_wbd_dat_o\[7\]   
+s2_wbd_dat_o\[6\]   
+s2_wbd_dat_o\[5\]   
+s2_wbd_dat_o\[4\]   
+s2_wbd_dat_o\[3\]   
+s2_wbd_dat_o\[2\]   
+s2_wbd_dat_o\[1\]   
+s2_wbd_dat_o\[0\]   
+s2_wbd_dat_i\[31\]   
+s2_wbd_dat_i\[30\]   
+s2_wbd_dat_i\[29\]   
+s2_wbd_dat_i\[28\]   
+s2_wbd_dat_i\[27\]   
+s2_wbd_dat_i\[26\]   
+s2_wbd_dat_i\[25\]   
+s2_wbd_dat_i\[24\]   
+s2_wbd_dat_i\[23\]   
+s2_wbd_dat_i\[22\]   
+s2_wbd_dat_i\[21\]   
+s2_wbd_dat_i\[20\]   
+s2_wbd_dat_i\[19\]   
+s2_wbd_dat_i\[18\]   
+s2_wbd_dat_i\[17\]   
+s2_wbd_dat_i\[16\]   
+s2_wbd_dat_i\[15\]   
+s2_wbd_dat_i\[14\]   
+s2_wbd_dat_i\[13\]   
+s2_wbd_dat_i\[12\]   
+s2_wbd_dat_i\[11\]   
+s2_wbd_dat_i\[10\]   
+s2_wbd_dat_i\[9\]   
+s2_wbd_dat_i\[8\]   
+s2_wbd_dat_i\[7\]   
+s2_wbd_dat_i\[6\]   
+s2_wbd_dat_i\[5\]   
+s2_wbd_dat_i\[4\]   
+s2_wbd_dat_i\[3\]   
+s2_wbd_dat_i\[2\]   
+s2_wbd_dat_i\[1\]   
+s2_wbd_dat_i\[0\]   
+s2_wbd_ack_i        
+s2_wbd_cyc_o        
+
diff --git a/openlane/wb_interconnect/sta.tcl b/openlane/wb_interconnect/sta.tcl
new file mode 100644
index 0000000..cb809a5
--- /dev/null
+++ b/openlane/wb_interconnect/sta.tcl
@@ -0,0 +1,57 @@
+# 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>
+
+
+set ::env(LIB_FASTEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ff_n40C_1v95.lib"
+set ::env(LIB_SLOWEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ss_100C_1v60.lib"
+set ::env(CURRENT_NETLIST) runs/wb_interconnect/results/synthesis/wb_interconnect.synthesis_preroute.v
+set ::env(DESIGN_NAME) "wb_interconnect"
+set ::env(CURRENT_SPEF) ../../spef/wb_interconnect.spef
+set ::env(BASE_SDC_FILE) "base.sdc"
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8"
+set ::env(SYNTH_DRIVING_CELL_PIN) "Y"
+set ::env(SYNTH_CAP_LOAD) "17.65"
+set ::env(WIRE_RC_LAYER) "met1"
+
+
+set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um
+read_liberty -min $::env(LIB_FASTEST)
+read_liberty -max $::env(LIB_SLOWEST)
+read_verilog $::env(CURRENT_NETLIST)
+link_design  $::env(DESIGN_NAME)
+
+read_spef  $::env(CURRENT_SPEF)
+
+read_sdc -echo $::env(BASE_SDC_FILE)
+
+# check for missing constraints
+check_setup  -verbose > unconstraints.rpt
+
+set_operating_conditions -analysis_type single
+# Propgate the clock
+set_propagated_clock [all_clocks]
+
+report_tns
+report_wns
+report_power 
+report_checks -unique -slack_max -0.0 -group_count 100 
+report_checks -unique -slack_min -0.0 -group_count 100 
+report_checks -path_delay min_max 
+report_checks -group_count 100  -slack_max -0.01  > timing.rpt
+
+report_checks -group_count 100  -slack_min -0.01 >> timing.rpt
+
+
diff --git a/openlane/yifive/base.sdc b/openlane/yifive/base.sdc
new file mode 100644
index 0000000..375538d
--- /dev/null
+++ b/openlane/yifive/base.sdc
@@ -0,0 +1,321 @@
+###############################################################################
+# Timing Constraints
+###############################################################################
+create_clock -name core_clk -period 20.0000 [get_ports {core_clk}]
+create_clock -name rtc_clk -period 40.0000 [get_ports {rtc_clk}]
+create_clock -name wb_clk -period 10.0000 [get_ports {wb_clk}]
+
+create_generated_clock -name sram0_clk0 -add -source [get_ports {core_clk}] -master_clock [get_clocks core_clk] -divide_by 1 -comment {tcm sram clock0} [get_ports sram0_clk0]
+create_generated_clock -name sram0_clk1 -add -source [get_ports {core_clk}] -master_clock [get_clocks core_clk] -divide_by 1 -comment {tcm sram clock1} [get_ports sram0_clk1]
+
+create_generated_clock -name icache_mem_clk0 -add -source [get_ports {core_clk}] -master_clock [get_clocks core_clk] -divide_by 1 -comment {icache clock0} [get_ports icache_mem_clk0]
+create_generated_clock -name icache_mem_clk1 -add -source [get_ports {core_clk}] -master_clock [get_clocks core_clk] -divide_by 1 -comment {icache clock1} [get_ports icache_mem_clk1]
+
+create_generated_clock -name dcache_mem_clk0 -add -source [get_ports {core_clk}] -master_clock [get_clocks core_clk] -divide_by 1 -comment {dcache clock0} [get_ports dcache_mem_clk0]
+create_generated_clock -name dcache_mem_clk1 -add -source [get_ports {core_clk}] -master_clock [get_clocks core_clk] -divide_by 1 -comment {dcache clock1} [get_ports dcache_mem_clk1]
+
+set_clock_transition 0.1500 [all_clocks]
+set_clock_uncertainty -setup 0.2500 [all_clocks]
+set_clock_uncertainty -hold 0.2500 [all_clocks]
+
+set_propagated_clock [all_clocks]
+
+
+set ::env(SYNTH_TIMING_DERATE) 0.05
+puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %"
+set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
+set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}]
+
+set_clock_groups -name async_clock -asynchronous \
+ -group [get_clocks {core_clk sram0_clk0 sram0_clk1 icache_mem_clk0 icache_mem_clk1 dcache_mem_clk0 dcache_mem_clk1} ]\
+ -group [get_clocks {rtc_clk}]\
+ -group [get_clocks {wb_clk}] -comment {Async Clock group}
+
+### ClkSkew Adjust
+set_case_analysis 0 [get_ports {cfg_cska_riscv[0]}]
+set_case_analysis 0 [get_ports {cfg_cska_riscv[1]}]
+set_case_analysis 0 [get_ports {cfg_cska_riscv[2]}]
+set_case_analysis 0 [get_ports {cfg_cska_riscv[3]}]
+
+
+set_max_delay   3.5 -from [get_ports {wbd_clk_int}]
+set_max_delay   2 -to   [get_ports {wbd_clk_riscv}]
+set_max_delay 3.5 -from wbd_clk_int -to wbd_clk_riscv
+
+#TCM Memory
+set_input_delay -max 6.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_dout0[*]}]
+set_input_delay -min 3.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_dout0[*]}]
+
+set_input_delay -max 6.0000 -clock [get_clocks {sram0_clk1}] -add_delay [get_ports {sram0_dout1[*]}]
+set_input_delay -min 3.0000 -clock [get_clocks {sram0_clk1}] -add_delay [get_ports {sram0_dout1[*]}]
+
+set_output_delay -max 4.5000 -clock [get_clocks {sram0_clk1}] -add_delay [get_ports {sram0_addr1[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {sram0_clk1}] -add_delay [get_ports {sram0_csb1}]
+
+set_output_delay -min 2.0000 -clock [get_clocks {sram0_clk1}] -add_delay [get_ports {sram0_addr1[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {sram0_clk1}] -add_delay [get_ports {sram0_csb1}]
+
+set_output_delay -max 4.5000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_addr0[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_csb0}]
+set_output_delay -max 4.5000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_din0[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_web0}]
+set_output_delay -max 4.5000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_wmask0[*]}]
+
+set_output_delay -min 2.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_addr0[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_csb0}]
+set_output_delay -min 2.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_din0[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_web0}]
+set_output_delay -min 2.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_wmask0[*]}]
+
+#icache memory
+set_input_delay -max 6.0000 -clock [get_clocks {icache_mem_clk1}] -add_delay [get_ports {icache_mem_dout1[*]}]
+set_input_delay -min 3.0000 -clock [get_clocks {icache_mem_clk1}] -add_delay [get_ports {icache_mem_dout1[*]}]
+
+set_output_delay -max 4.5000 -clock [get_clocks {icache_mem_clk1}] -add_delay [get_ports {icache_mem_addr1[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {icache_mem_clk1}] -add_delay [get_ports {icache_mem_csb1}]
+
+set_output_delay -min -0.5000 -clock [get_clocks {icache_mem_clk1}] -add_delay [get_ports {icache_mem_addr1[*]}]
+set_output_delay -min -0.5000 -clock [get_clocks {icache_mem_clk1}] -add_delay [get_ports {icache_mem_csb1}]
+
+set_output_delay -max 4.5000 -clock [get_clocks {icache_mem_clk0}] -add_delay [get_ports {icache_mem_addr0[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {icache_mem_clk0}] -add_delay [get_ports {icache_mem_csb0}]
+set_output_delay -max 4.5000 -clock [get_clocks {icache_mem_clk0}] -add_delay [get_ports {icache_mem_din0[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {icache_mem_clk0}] -add_delay [get_ports {icache_mem_web0}]
+set_output_delay -max 4.5000 -clock [get_clocks {icache_mem_clk0}] -add_delay [get_ports {icache_mem_wmask0[*]}]
+
+set_output_delay -min -0.5000 -clock [get_clocks {icache_mem_clk0}] -add_delay [get_ports {icache_mem_addr0[*]}]
+set_output_delay -min -0.5000 -clock [get_clocks {icache_mem_clk0}] -add_delay [get_ports {icache_mem_csb0}]
+set_output_delay -min -0.5000 -clock [get_clocks {icache_mem_clk0}] -add_delay [get_ports {icache_mem_din0[*]}]
+set_output_delay -min -0.5000 -clock [get_clocks {icache_mem_clk0}] -add_delay [get_ports {icache_mem_web0}]
+set_output_delay -min -0.5000 -clock [get_clocks {icache_mem_clk0}] -add_delay [get_ports {icache_mem_wmask0[*]}]
+
+#dcache memory
+set_input_delay -max 6.0000 -clock [get_clocks {dcache_mem_clk0}] -add_delay [get_ports {dcache_mem_dout0[*]}]
+set_input_delay -min 3.0000 -clock [get_clocks {dcache_mem_clk0}] -add_delay [get_ports {dcache_mem_dout0[*]}]
+
+set_input_delay -max 6.0000 -clock [get_clocks {dcache_mem_clk1}] -add_delay [get_ports {dcache_mem_dout1[*]}]
+set_input_delay -min 3.0000 -clock [get_clocks {dcache_mem_clk1}] -add_delay [get_ports {dcache_mem_dout1[*]}]
+
+set_output_delay -max 4.5000 -clock [get_clocks {dcache_mem_clk1}] -add_delay [get_ports {dcache_mem_addr1[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {dcache_mem_clk1}] -add_delay [get_ports {dcache_mem_csb1}]
+
+set_output_delay -min -0.500 -clock [get_clocks {dcache_mem_clk1}] -add_delay [get_ports {dcache_mem_addr1[*]}]
+set_output_delay -min -0.500 -clock [get_clocks {dcache_mem_clk1}] -add_delay [get_ports {dcache_mem_csb1}]
+
+set_output_delay -max 4.5000 -clock [get_clocks {dcache_mem_clk0}] -add_delay [get_ports {dcache_mem_addr0[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {dcache_mem_clk0}] -add_delay [get_ports {dcache_mem_csb0}]
+set_output_delay -max 4.5000 -clock [get_clocks {dcache_mem_clk0}] -add_delay [get_ports {dcache_mem_din0[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {dcache_mem_clk0}] -add_delay [get_ports {dcache_mem_web0}]
+set_output_delay -max 4.5000 -clock [get_clocks {dcache_mem_clk0}] -add_delay [get_ports {dcache_mem_wmask0[*]}]
+
+set_output_delay -min -0.500 -clock [get_clocks {dcache_mem_clk0}] -add_delay [get_ports {dcache_mem_addr0[*]}]
+set_output_delay -min -0.500 -clock [get_clocks {dcache_mem_clk0}] -add_delay [get_ports {dcache_mem_csb0}]
+set_output_delay -min -0.500 -clock [get_clocks {dcache_mem_clk0}] -add_delay [get_ports {dcache_mem_din0[*]}]
+set_output_delay -min -0.500 -clock [get_clocks {dcache_mem_clk0}] -add_delay [get_ports {dcache_mem_web0}]
+set_output_delay -min -0.500 -clock [get_clocks {dcache_mem_clk0}] -add_delay [get_ports {dcache_mem_wmask0[*]}]
+
+set_input_delay -max 5.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wb_rst_n}]
+
+#Wishbone DMEM
+set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_ack_i}]
+set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_dat_i[*]}]
+set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_err_i}]
+
+set_input_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_ack_i}]
+set_input_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_dat_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_dat_i[*]}]
+
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_adr_o[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_dat_o[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_sel_o[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_stb_o}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_we_o}]
+
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_adr_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_dat_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_sel_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_stb_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dmem_we_o}]
+
+#Wishbone icache
+set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_lack_i}]
+set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_ack_i}]
+set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_dat_i[*]}]
+set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_err_i}]
+
+set_input_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_lack_i}]
+set_input_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_ack_i}]
+set_input_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_dat_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_dat_i[*]}]
+
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_adr_o[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_sel_o[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_bl_o[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_bry_o}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_stb_o}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_we_o}]
+
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_adr_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_sel_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_bl_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_bry_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_stb_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_icache_we_o}]
+
+#Wishbone dcache
+set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_lack_i}]
+set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_ack_i}]
+set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_dat_i[*]}]
+set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_err_i}]
+
+set_input_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_lack_i}]
+set_input_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_ack_i}]
+set_input_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_dat_i[*]}]
+set_input_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_dat_i[*]}]
+
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_adr_o[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_dat_o[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_sel_o[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_bl_o[*]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_bry_o}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_stb_o}]
+set_output_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_we_o}]
+
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_adr_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_dat_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_sel_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_bl_o[*]}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_bry_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_stb_o}]
+set_output_delay -min 2.0000 -clock [get_clocks {wb_clk}] -add_delay [get_ports {wbd_dcache_we_o}]
+
+set_false_path\
+    -from [get_ports {soft_irq}]
+set_false_path\
+    -to [list [get_ports {riscv_debug[0]}]\
+           [get_ports {riscv_debug[10]}]\
+           [get_ports {riscv_debug[11]}]\
+           [get_ports {riscv_debug[12]}]\
+           [get_ports {riscv_debug[13]}]\
+           [get_ports {riscv_debug[14]}]\
+           [get_ports {riscv_debug[15]}]\
+           [get_ports {riscv_debug[16]}]\
+           [get_ports {riscv_debug[17]}]\
+           [get_ports {riscv_debug[18]}]\
+           [get_ports {riscv_debug[19]}]\
+           [get_ports {riscv_debug[1]}]\
+           [get_ports {riscv_debug[20]}]\
+           [get_ports {riscv_debug[21]}]\
+           [get_ports {riscv_debug[22]}]\
+           [get_ports {riscv_debug[23]}]\
+           [get_ports {riscv_debug[24]}]\
+           [get_ports {riscv_debug[25]}]\
+           [get_ports {riscv_debug[26]}]\
+           [get_ports {riscv_debug[27]}]\
+           [get_ports {riscv_debug[28]}]\
+           [get_ports {riscv_debug[29]}]\
+           [get_ports {riscv_debug[2]}]\
+           [get_ports {riscv_debug[30]}]\
+           [get_ports {riscv_debug[31]}]\
+           [get_ports {riscv_debug[32]}]\
+           [get_ports {riscv_debug[33]}]\
+           [get_ports {riscv_debug[34]}]\
+           [get_ports {riscv_debug[35]}]\
+           [get_ports {riscv_debug[36]}]\
+           [get_ports {riscv_debug[37]}]\
+           [get_ports {riscv_debug[38]}]\
+           [get_ports {riscv_debug[39]}]\
+           [get_ports {riscv_debug[3]}]\
+           [get_ports {riscv_debug[40]}]\
+           [get_ports {riscv_debug[41]}]\
+           [get_ports {riscv_debug[42]}]\
+           [get_ports {riscv_debug[43]}]\
+           [get_ports {riscv_debug[44]}]\
+           [get_ports {riscv_debug[45]}]\
+           [get_ports {riscv_debug[46]}]\
+           [get_ports {riscv_debug[47]}]\
+           [get_ports {riscv_debug[48]}]\
+           [get_ports {riscv_debug[49]}]\
+           [get_ports {riscv_debug[4]}]\
+           [get_ports {riscv_debug[50]}]\
+           [get_ports {riscv_debug[51]}]\
+           [get_ports {riscv_debug[52]}]\
+           [get_ports {riscv_debug[53]}]\
+           [get_ports {riscv_debug[54]}]\
+           [get_ports {riscv_debug[55]}]\
+           [get_ports {riscv_debug[56]}]\
+           [get_ports {riscv_debug[57]}]\
+           [get_ports {riscv_debug[58]}]\
+           [get_ports {riscv_debug[59]}]\
+           [get_ports {riscv_debug[5]}]\
+           [get_ports {riscv_debug[60]}]\
+           [get_ports {riscv_debug[61]}]\
+           [get_ports {riscv_debug[62]}]\
+           [get_ports {riscv_debug[63]}]\
+           [get_ports {riscv_debug[6]}]\
+           [get_ports {riscv_debug[7]}]\
+           [get_ports {riscv_debug[8]}]\
+           [get_ports {riscv_debug[9]}]]
+
+set_false_path -from [get_ports {fuse_mhartid[0]}]
+set_false_path -from [get_ports {fuse_mhartid[10]}]
+set_false_path -from [get_ports {fuse_mhartid[11]}]
+set_false_path -from [get_ports {fuse_mhartid[12]}]
+set_false_path -from [get_ports {fuse_mhartid[13]}]
+set_false_path -from [get_ports {fuse_mhartid[14]}]
+set_false_path -from [get_ports {fuse_mhartid[15]}]
+set_false_path -from [get_ports {fuse_mhartid[16]}]
+set_false_path -from [get_ports {fuse_mhartid[17]}]
+set_false_path -from [get_ports {fuse_mhartid[18]}]
+set_false_path -from [get_ports {fuse_mhartid[19]}]
+set_false_path -from [get_ports {fuse_mhartid[1]}]
+set_false_path -from [get_ports {fuse_mhartid[20]}]
+set_false_path -from [get_ports {fuse_mhartid[21]}]
+set_false_path -from [get_ports {fuse_mhartid[22]}]
+set_false_path -from [get_ports {fuse_mhartid[23]}]
+set_false_path -from [get_ports {fuse_mhartid[24]}]
+set_false_path -from [get_ports {fuse_mhartid[25]}]
+set_false_path -from [get_ports {fuse_mhartid[26]}]
+set_false_path -from [get_ports {fuse_mhartid[27]}]
+set_false_path -from [get_ports {fuse_mhartid[28]}]
+set_false_path -from [get_ports {fuse_mhartid[29]}]
+set_false_path -from [get_ports {fuse_mhartid[2]}]
+set_false_path -from [get_ports {fuse_mhartid[30]}]
+set_false_path -from [get_ports {fuse_mhartid[31]}]
+set_false_path -from [get_ports {fuse_mhartid[3]}]
+set_false_path -from [get_ports {fuse_mhartid[4]}]
+set_false_path -from [get_ports {fuse_mhartid[5]}]
+set_false_path -from [get_ports {fuse_mhartid[6]}]
+set_false_path -from [get_ports {fuse_mhartid[7]}]
+set_false_path -from [get_ports {fuse_mhartid[8]}]
+set_false_path -from [get_ports {fuse_mhartid[9]}]
+set_false_path -from [get_ports {irq_lines[0]}]
+set_false_path -from [get_ports {irq_lines[10]}]
+set_false_path -from [get_ports {irq_lines[11]}]
+set_false_path -from [get_ports {irq_lines[12]}]
+set_false_path -from [get_ports {irq_lines[13]}]
+set_false_path -from [get_ports {irq_lines[14]}]
+set_false_path -from [get_ports {irq_lines[15]}]
+set_false_path -from [get_ports {irq_lines[1]}]
+set_false_path -from [get_ports {irq_lines[2]}]
+set_false_path -from [get_ports {irq_lines[3]}]
+set_false_path -from [get_ports {irq_lines[4]}]
+set_false_path -from [get_ports {irq_lines[5]}]
+set_false_path -from [get_ports {irq_lines[6]}]
+set_false_path -from [get_ports {irq_lines[7]}]
+set_false_path -from [get_ports {irq_lines[8]}]
+set_false_path -from [get_ports {irq_lines[9]}]
+set_false_path -from [get_ports {pwrup_rst_n}]
+set_false_path -from [get_ports {rst_n}]
+set_false_path -from [get_ports {soft_irq}]
+###############################################################################
+# Environment
+###############################################################################
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin $::env(SYNTH_DRIVING_CELL_PIN) [all_inputs]
+set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0]
+puts "\[INFO\]: Setting load to: $cap_load"
+set_load  $cap_load [all_outputs]
+
+###############################################################################
+# Design Rules
+###############################################################################
diff --git a/openlane/yifive/config.tcl b/openlane/yifive/config.tcl
new file mode 100755
index 0000000..1f117a8
--- /dev/null
+++ b/openlane/yifive/config.tcl
@@ -0,0 +1,145 @@
+# 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>
+
+# Global
+# ------
+
+set script_dir [file dirname [file normalize [info script]]]
+# Name
+set ::env(DESIGN_NAME) ycr1_top_wb
+
+set ::env(DESIGN_IS_CORE) "0"
+set ::env(FP_PDN_CORE_RING) "0"
+
+# Timing configuration
+set ::env(CLOCK_PERIOD) "10"
+set ::env(CLOCK_PORT) "wb_clk core_clk"
+
+set ::env(SYNTH_MAX_FANOUT) 4
+
+## CTS BUFFER
+set ::env(CTS_CLK_BUFFER_LIST) "sky130_fd_sc_hd__clkbuf_4 sky130_fd_sc_hd__clkbuf_8"
+set ::env(CTS_SINK_CLUSTERING_SIZE) "16"
+set ::env(CLOCK_BUFFER_FANOUT) "8"
+
+# Sources
+# -------
+
+# Local sources + no2usb sources
+set ::env(VERILOG_FILES) "\
+        $script_dir/../../verilog/rtl/clk_skew_adjust/src/clk_skew_adjust.gv \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/pipeline/ycr1_pipe_top.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/ycr1_core_top.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/ycr1_dm.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/ycr1_tapc_synchronizer.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/ycr1_clk_ctrl.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/ycr1_scu.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/ycr1_tapc.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/ycr1_tapc_shift_reg.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/ycr1_dmi.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/primitives/ycr1_reset_cells.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/pipeline/ycr1_pipe_ifu.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/pipeline/ycr1_pipe_idu.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/pipeline/ycr1_pipe_exu.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/pipeline/ycr1_pipe_mprf.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/pipeline/ycr1_pipe_csr.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/pipeline/ycr1_pipe_ialu.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/pipeline/ycr1_pipe_mul.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/pipeline/ycr1_pipe_div.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/pipeline/ycr1_pipe_lsu.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/pipeline/ycr1_pipe_hdu.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/pipeline/ycr1_pipe_tdu.sv  \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/core/pipeline/ycr1_ipic.sv   \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/top/ycr1_dmem_router.sv   \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/top/ycr1_imem_router.sv   \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/top/ycr1_icache_router.sv \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/top/ycr1_dcache_router.sv \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/top/ycr1_tcm.sv   \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/top/ycr1_timer.sv   \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/top/ycr1_top_wb.sv   \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/top/ycr1_dmem_wb.sv   \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/top/ycr1_imem_wb.sv   \
+	$script_dir/../../verilog/rtl/yifive/ycr1c/src/top/ycr1_intf.sv   \
+        $script_dir/../../verilog/rtl/yifive/ycr1c/src/cache/src/core/icache_top.sv             \
+        $script_dir/../../verilog/rtl/yifive/ycr1c/src/cache/src/core/icache_app_fsm.sv         \
+        $script_dir/../../verilog/rtl/yifive/ycr1c/src/cache/src/core/icache_tag_fifo.sv        \
+        $script_dir/../../verilog/rtl/yifive/ycr1c/src/cache/src/core/dcache_tag_fifo.sv        \
+        $script_dir/../../verilog/rtl/yifive/ycr1c/src/cache/src/core/dcache_top.sv             \
+        $script_dir/../../verilog/rtl/yifive/ycr1c/src/lib/ycr1_async_wbb.sv                    \
+        $script_dir/../../verilog/rtl/yifive/ycr1c/src/lib/ycr1_arb.sv                          \
+        $script_dir/../../verilog/rtl/yifive/ycr1c/src/lib/sync_fifo.sv                         \
+        $script_dir/../../verilog/rtl/yifive/ycr1c/src/lib/async_fifo.sv                        \
+        $script_dir/../../verilog/rtl/yifive/ycr1c/src/lib/ctech_cells.sv                       \
+	"
+
+set ::env(VERILOG_INCLUDE_DIRS) [glob $script_dir/../../verilog/rtl/yifive/ycr1c/src/includes ]
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+set ::env(SYNTH_DEFINES) [list SYNTHESIS ]
+
+set ::env(SDC_FILE) "$script_dir/base.sdc"
+set ::env(BASE_SDC_FILE) "$script_dir/base.sdc"
+#set ::env(SYNTH_DEFINES) [list SCR1_DBG_EN ]
+
+set ::env(LEC_ENABLE) 0
+
+set ::env(VDD_PIN) [list {vccd1}]
+set ::env(GND_PIN) [list {vssd1}]
+
+
+# --------
+# Floorplanning
+# -------------
+
+set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+
+set ::env(FP_SIZING) absolute
+set ::env(DIE_AREA) [list 0.0 0.0 725.0 1550.0]
+
+
+# If you're going to use multiple power domains, then keep this disabled.
+set ::env(RUN_CVC) 0
+
+#set ::env(PDN_CFG) $script_dir/pdn.tcl
+
+
+set ::env(PL_TIME_DRIVEN) 1
+set ::env(PL_TARGET_DENSITY) "0.35"
+set ::env(FP_CORE_UTIL) "50"
+
+# helps in anteena fix
+set ::env(USE_ARC_ANTENNA_CHECK) "0"
+
+set ::env(FP_IO_VEXTEND) 4
+set ::env(FP_IO_HEXTEND) 4
+
+set ::env(FP_PDN_VPITCH) 100
+set ::env(FP_PDN_HPITCH) 100
+set ::env(FP_PDN_VWIDTH) 3
+set ::env(FP_PDN_HWIDTH) 3
+
+set ::env(GLB_RT_MAXLAYER) 6
+set ::env(GLB_RT_MAX_DIODE_INS_ITERS) 10
+set ::env(DIODE_INSERTION_STRATEGY) 4
+
+
+set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
+set ::env(QUIT_ON_MAGIC_DRC) "1"
+set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
+
+#Need to cross-check why global timing opimization creating setup vio with hugh hold fix
+set ::env(GLB_RESIZER_TIMING_OPTIMIZATIONS) "0"
+
diff --git a/openlane/yifive/interactive.tcl b/openlane/yifive/interactive.tcl
new file mode 100644
index 0000000..b44b517
--- /dev/null
+++ b/openlane/yifive/interactive.tcl
@@ -0,0 +1,219 @@
+#!/usr/bin/tclsh
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+# Copyright 2020 Efabless Corporation
+# Copyright 2020 Sylvain Munaut
+#
+# 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
+
+package require openlane;
+
+
+proc run_placement_step {args} {
+    # set pdndef_dirname [file dirname $::env(pdn_tmp_file_tag).def]
+    # set pdndef [lindex [glob $pdndef_dirname/*pdn*] 0]
+    # set_def $pdndef
+    if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
+        set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
+    }
+
+    run_placement
+}
+
+proc run_cts_step {args} {
+    # set_def $::env(opendp_result_file_tag).def
+    if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
+        set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
+    }
+
+    run_cts
+    run_resizer_timing
+}
+
+proc run_routing_step {args} {
+    # set resizerdef_dirname [file dirname $::env(resizer_tmp_file_tag)_timing.def]
+    # set resizerdef [lindex [glob $resizerdef_dirname/*resizer*] 0]
+    # set_def $resizerdef
+    if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
+        set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
+    }
+    run_routing
+}
+
+proc run_diode_insertion_2_5_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
+        set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
+    }
+	if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+		run_antenna_check
+		heal_antenna_violators; # modifies the routed DEF
+	}
+
+}
+
+proc run_power_pins_insertion_step {args} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(POWER_PINS_INSERTION_CURRENT_DEF) ] } {
+        set ::env(POWER_PINS_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(POWER_PINS_INSERTION_CURRENT_DEF)
+    }
+    if { $::env(LVS_INSERT_POWER_PINS) } {
+		write_powered_verilog
+		set_netlist $::env(lvs_result_file_tag).powered.v
+    }
+
+}
+
+proc run_lvs_step {{ lvs_enabled 1 }} {
+    # set_def $::env(tritonRoute_result_file_tag).def
+    if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
+        set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
+    }
+	if { $lvs_enabled } {
+		run_magic_spice_export
+		run_lvs; # requires run_magic_spice_export
+	}
+
+}
+
+proc run_drc_step {{ drc_enabled 1 }} {
+    if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
+        set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
+    }
+	if { $drc_enabled } {
+		run_magic_drc
+		run_klayout_drc
+	}
+}
+
+proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
+    if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
+        set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
+    }
+	if { $antenna_check_enabled } {
+		run_antenna_check
+	}
+}
+
+proc run_flow {args} {
+       set script_dir [file dirname [file normalize [info script]]]
+
+		set options {
+		{-design required}
+		{-save_path optional}
+		{-no_lvs optional}
+	    {-no_drc optional}
+	    {-no_antennacheck optional}
+	}
+	set flags {-save}
+	parse_key_args "run_flow" args arg_values $options flags_map $flags -no_consume
+
+	prep {*}$args
+
+        set LVS_ENABLED 1
+        set DRC_ENABLED 0
+        set ANTENNACHECK_ENABLED 1
+
+        set steps [dict create "synthesis" {run_synthesis "" } \
+                "floorplan" {run_floorplan ""} \
+                "placement" {run_placement_step ""} \
+                "cts" {run_cts_step ""} \
+                "routing" {run_routing_step ""}\
+                "diode_insertion" {run_diode_insertion_2_5_step ""} \
+                "power_pins_insertion" {run_power_pins_insertion_step ""} \
+                "gds_magic" {run_magic ""} \
+                "gds_drc_klayout" {run_klayout ""} \
+                "gds_xor_klayout" {run_klayout_gds_xor ""} \
+                "lvs" "run_lvs_step $LVS_ENABLED" \
+                "drc" "run_drc_step $DRC_ENABLED" \
+                "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED" \
+                "cvc" {run_lef_cvc}
+        ]
+
+       set_if_unset arg_values(-to) "cvc";
+
+       if {  [info exists ::env(CURRENT_STEP) ] } {
+           puts "\[INFO\]:Picking up where last execution left off"
+           puts [format "\[INFO\]:Current stage is %s " $::env(CURRENT_STEP)]
+       } else {
+           set ::env(CURRENT_STEP) "synthesis";
+       }
+       set_if_unset arg_values(-from) $::env(CURRENT_STEP);
+       set exe 0;
+       dict for {step_name step_exe} $steps {
+           if { [ string equal $arg_values(-from) $step_name ] } {
+               set exe 1;
+           }
+
+           if { $exe } {
+               # For when it fails
+               set ::env(CURRENT_STEP) $step_name
+               [lindex $step_exe 0] [lindex $step_exe 1] ;
+           }
+
+           if { [ string equal $arg_values(-to) $step_name ] } {
+               set exe 0:
+               break;
+           }
+
+       }
+
+       # for when it resumes
+       set steps_as_list [dict keys $steps]
+       set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
+       set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
+
+	if {  [info exists flags_map(-save) ] } {
+		if { ! [info exists arg_values(-save_path)] } {
+			set arg_values(-save_path) ""
+		}
+		save_views 	-lef_path $::env(magic_result_file_tag).lef \
+			-def_path $::env(CURRENT_DEF) \
+			-gds_path $::env(magic_result_file_tag).gds \
+			-mag_path $::env(magic_result_file_tag).mag \
+			-maglef_path $::env(magic_result_file_tag).lef.mag \
+			-spice_path $::env(magic_result_file_tag).spice \
+			-spef_path $::env(CURRENT_SPEF) \
+			-verilog_path $::env(CURRENT_NETLIST) \
+			-save_path $arg_values(-save_path) \
+			-tag $::env(RUN_TAG)
+	}
+
+
+	calc_total_runtime
+	save_state
+	generate_final_summary_report
+	
+	check_timing_violations
+
+	puts_success "Flow Completed Without Fatal Errors."
+
+}
+
+run_flow {*}$argv
diff --git a/openlane/yifive/pdn.tcl b/openlane/yifive/pdn.tcl
new file mode 100644
index 0000000..1fe689b
--- /dev/null
+++ b/openlane/yifive/pdn.tcl
@@ -0,0 +1,49 @@
+# 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
+
+# Power nets
+set ::power_nets $::env(VDD_PIN)
+set ::ground_nets $::env(GND_PIN)
+
+set ::macro_blockage_layer_list "li1 met1 met2 met3 met4 met5"
+
+pdngen::specify_grid stdcell {
+    name grid
+    rails {
+	    met1 {width 0.48 pitch $::env(PLACE_SITE_HEIGHT) offset 0}
+    }
+    straps {
+	    met4 {width 1.6 pitch $::env(FP_PDN_VPITCH) offset $::env(FP_PDN_VOFFSET)}
+	    met5 {width 1.6 pitch $::env(FP_PDN_HPITCH) offset $::env(FP_PDN_HOFFSET)}
+    }
+    connect {{met1 met4} {met4 met5}}
+}
+
+pdngen::specify_grid macro {
+    power_pins "VPWR"
+    ground_pins "VGND"
+    blockages "li1 met1 met2 met3 met4"
+    straps { 
+    } 
+    connect {{met4_PIN_ver met5}}
+}
+
+set ::halo 5
+
+# POWER or GROUND #Std. cell rails starting with power or ground rails at the bottom of the core area
+set ::rails_start_with "POWER" ;
+
+# POWER or GROUND #Upper metal stripes starting with power or ground rails at the left/bottom of the core area
+set ::stripes_start_with "POWER" ;
diff --git a/openlane/yifive/pin_order.cfg b/openlane/yifive/pin_order.cfg
new file mode 100644
index 0000000..e168c5f
--- /dev/null
+++ b/openlane/yifive/pin_order.cfg
@@ -0,0 +1,796 @@
+#BUS_SORT
+
+#MANUAL_PLACE
+
+
+#E
+soft_irq            0500 0 2
+irq_lines\[15\]     
+irq_lines\[14\]     
+irq_lines\[13\]     
+irq_lines\[12\]     
+irq_lines\[11\]     
+irq_lines\[10\]     
+irq_lines\[9\]     
+irq_lines\[8\]     
+irq_lines\[7\]     
+irq_lines\[6\]     
+irq_lines\[5\]     
+irq_lines\[4\]     
+irq_lines\[3\]     
+irq_lines\[2\]     
+irq_lines\[1\]     
+irq_lines\[0\]     
+fuse_mhartid\[31\] 
+fuse_mhartid\[30\] 
+fuse_mhartid\[29\] 
+fuse_mhartid\[28\] 
+fuse_mhartid\[27\] 
+fuse_mhartid\[26\] 
+fuse_mhartid\[25\] 
+fuse_mhartid\[24\] 
+fuse_mhartid\[23\] 
+fuse_mhartid\[22\] 
+fuse_mhartid\[21\] 
+fuse_mhartid\[20\] 
+fuse_mhartid\[19\] 
+fuse_mhartid\[18\] 
+fuse_mhartid\[17\] 
+fuse_mhartid\[16\] 
+fuse_mhartid\[15\] 
+fuse_mhartid\[14\] 
+fuse_mhartid\[13\] 
+fuse_mhartid\[12\] 
+fuse_mhartid\[11\] 
+fuse_mhartid\[10\] 
+fuse_mhartid\[9\] 
+fuse_mhartid\[8\] 
+fuse_mhartid\[7\] 
+fuse_mhartid\[6\] 
+fuse_mhartid\[5\] 
+fuse_mhartid\[4\] 
+fuse_mhartid\[3\] 
+fuse_mhartid\[2\] 
+fuse_mhartid\[1\] 
+fuse_mhartid\[0\] 
+
+cfg_cska_riscv\[3\]    
+cfg_cska_riscv\[2\]
+cfg_cska_riscv\[1\]
+cfg_cska_riscv\[0\]
+wbd_clk_int
+wbd_clk_riscv
+wb_clk            
+
+
+wbd_dmem_stb_o          0700 0
+wbd_dmem_we_o           
+wbd_dmem_adr_o\[31\]    
+wbd_dmem_adr_o\[30\]    
+wbd_dmem_adr_o\[29\]    
+wbd_dmem_adr_o\[28\]    
+wbd_dmem_adr_o\[27\]    
+wbd_dmem_adr_o\[26\]    
+wbd_dmem_adr_o\[25\]    
+wbd_dmem_adr_o\[24\]    
+wbd_dmem_adr_o\[23\]    
+wbd_dmem_adr_o\[22\]    
+wbd_dmem_adr_o\[21\]    
+wbd_dmem_adr_o\[20\]    
+wbd_dmem_adr_o\[19\]    
+wbd_dmem_adr_o\[18\]    
+wbd_dmem_adr_o\[17\]    
+wbd_dmem_adr_o\[16\]    
+wbd_dmem_adr_o\[15\]    
+wbd_dmem_adr_o\[14\]    
+wbd_dmem_adr_o\[13\]    
+wbd_dmem_adr_o\[12\]    
+wbd_dmem_adr_o\[11\]    
+wbd_dmem_adr_o\[10\]   
+wbd_dmem_adr_o\[9\]    
+wbd_dmem_adr_o\[8\]    
+wbd_dmem_adr_o\[7\]    
+wbd_dmem_adr_o\[6\]    
+wbd_dmem_adr_o\[5\]    
+wbd_dmem_adr_o\[4\]    
+wbd_dmem_adr_o\[3\]    
+wbd_dmem_adr_o\[2\]    
+wbd_dmem_adr_o\[1\]    
+wbd_dmem_adr_o\[0\]    
+wbd_dmem_sel_o\[3\]    
+wbd_dmem_sel_o\[2\]    
+wbd_dmem_sel_o\[1\]    
+wbd_dmem_sel_o\[0\]    
+wbd_dmem_dat_o\[31\]   
+wbd_dmem_dat_o\[30\]   
+wbd_dmem_dat_o\[29\]   
+wbd_dmem_dat_o\[28\]   
+wbd_dmem_dat_o\[27\]   
+wbd_dmem_dat_o\[26\]   
+wbd_dmem_dat_o\[25\]   
+wbd_dmem_dat_o\[24\]   
+wbd_dmem_dat_o\[23\]   
+wbd_dmem_dat_o\[22\]   
+wbd_dmem_dat_o\[21\]   
+wbd_dmem_dat_o\[20\]   
+wbd_dmem_dat_o\[19\]   
+wbd_dmem_dat_o\[18\]   
+wbd_dmem_dat_o\[17\]   
+wbd_dmem_dat_o\[16\]   
+wbd_dmem_dat_o\[15\]   
+wbd_dmem_dat_o\[14\]   
+wbd_dmem_dat_o\[13\]   
+wbd_dmem_dat_o\[12\]  
+wbd_dmem_dat_o\[11\]  
+wbd_dmem_dat_o\[10\]  
+wbd_dmem_dat_o\[9\]   
+wbd_dmem_dat_o\[8\]   
+wbd_dmem_dat_o\[7\]   
+wbd_dmem_dat_o\[6\]   
+wbd_dmem_dat_o\[5\]   
+wbd_dmem_dat_o\[4\]   
+wbd_dmem_dat_o\[3\]   
+wbd_dmem_dat_o\[2\]   
+wbd_dmem_dat_o\[1\]   
+wbd_dmem_dat_o\[0\]   
+wbd_dmem_dat_i\[31\]  
+wbd_dmem_dat_i\[30\]  
+wbd_dmem_dat_i\[29\]  
+wbd_dmem_dat_i\[28\]  
+wbd_dmem_dat_i\[27\]  
+wbd_dmem_dat_i\[26\]  
+wbd_dmem_dat_i\[25\]  
+wbd_dmem_dat_i\[24\]  
+wbd_dmem_dat_i\[23\]  
+wbd_dmem_dat_i\[22\]  
+wbd_dmem_dat_i\[21\]  
+wbd_dmem_dat_i\[20\]  
+wbd_dmem_dat_i\[19\]  
+wbd_dmem_dat_i\[18\]  
+wbd_dmem_dat_i\[17\]  
+wbd_dmem_dat_i\[16\]  
+wbd_dmem_dat_i\[15\]  
+wbd_dmem_dat_i\[14\]  
+wbd_dmem_dat_i\[13\]  
+wbd_dmem_dat_i\[12\]  
+wbd_dmem_dat_i\[11\]  
+wbd_dmem_dat_i\[10\]  
+wbd_dmem_dat_i\[9\]  
+wbd_dmem_dat_i\[8\]  
+wbd_dmem_dat_i\[7\]  
+wbd_dmem_dat_i\[6\]  
+wbd_dmem_dat_i\[5\]  
+wbd_dmem_dat_i\[4\]  
+wbd_dmem_dat_i\[3\]  
+wbd_dmem_dat_i\[2\]  
+wbd_dmem_dat_i\[1\]  
+wbd_dmem_dat_i\[0\]  
+wbd_dmem_ack_i       
+wbd_dmem_err_i       
+
+wb_dcache_stb_o       0900 0  2
+wb_dcache_we_o        
+wb_dcache_adr_o\[31\] 
+wb_dcache_adr_o\[30\] 
+wb_dcache_adr_o\[29\] 
+wb_dcache_adr_o\[28\] 
+wb_dcache_adr_o\[27\] 
+wb_dcache_adr_o\[26\] 
+wb_dcache_adr_o\[25\] 
+wb_dcache_adr_o\[24\] 
+wb_dcache_adr_o\[23\] 
+wb_dcache_adr_o\[22\] 
+wb_dcache_adr_o\[21\] 
+wb_dcache_adr_o\[20\] 
+wb_dcache_adr_o\[19\] 
+wb_dcache_adr_o\[18\] 
+wb_dcache_adr_o\[17\] 
+wb_dcache_adr_o\[16\] 
+wb_dcache_adr_o\[15\] 
+wb_dcache_adr_o\[14\] 
+wb_dcache_adr_o\[13\] 
+wb_dcache_adr_o\[12\] 
+wb_dcache_adr_o\[11\] 
+wb_dcache_adr_o\[10\] 
+wb_dcache_adr_o\[9\] 
+wb_dcache_adr_o\[8\] 
+wb_dcache_adr_o\[7\] 
+wb_dcache_adr_o\[6\] 
+wb_dcache_adr_o\[5\] 
+wb_dcache_adr_o\[4\] 
+wb_dcache_adr_o\[3\] 
+wb_dcache_adr_o\[2\] 
+wb_dcache_adr_o\[1\] 
+wb_dcache_adr_o\[0\] 
+wb_dcache_sel_o\[3\]  
+wb_dcache_sel_o\[2\]  
+wb_dcache_sel_o\[1\]  
+wb_dcache_sel_o\[0\]  
+wb_dcache_bl_o\[9\]  
+wb_dcache_bl_o\[8\]  
+wb_dcache_bl_o\[7\]  
+wb_dcache_bl_o\[6\]  
+wb_dcache_bl_o\[5\]  
+wb_dcache_bl_o\[4\]  
+wb_dcache_bl_o\[3\]  
+wb_dcache_bl_o\[2\]  
+wb_dcache_bl_o\[1\]  
+wb_dcache_bl_o\[0\]  
+wb_dcache_bry_o
+wb_dcache_dat_o\[31\] 
+wb_dcache_dat_o\[30\] 
+wb_dcache_dat_o\[29\] 
+wb_dcache_dat_o\[28\] 
+wb_dcache_dat_o\[27\] 
+wb_dcache_dat_o\[26\] 
+wb_dcache_dat_o\[25\] 
+wb_dcache_dat_o\[24\] 
+wb_dcache_dat_o\[23\] 
+wb_dcache_dat_o\[22\] 
+wb_dcache_dat_o\[21\] 
+wb_dcache_dat_o\[20\] 
+wb_dcache_dat_o\[19\] 
+wb_dcache_dat_o\[18\] 
+wb_dcache_dat_o\[17\] 
+wb_dcache_dat_o\[16\] 
+wb_dcache_dat_o\[15\] 
+wb_dcache_dat_o\[14\] 
+wb_dcache_dat_o\[13\] 
+wb_dcache_dat_o\[12\] 
+wb_dcache_dat_o\[11\] 
+wb_dcache_dat_o\[10\] 
+wb_dcache_dat_o\[9\]  
+wb_dcache_dat_o\[8\]  
+wb_dcache_dat_o\[7\]  
+wb_dcache_dat_o\[6\]  
+wb_dcache_dat_o\[5\]  
+wb_dcache_dat_o\[4\]  
+wb_dcache_dat_o\[3\]  
+wb_dcache_dat_o\[2\]  
+wb_dcache_dat_o\[1\]  
+wb_dcache_dat_o\[0\]  
+wb_dcache_dat_i\[31\] 
+wb_dcache_dat_i\[30\] 
+wb_dcache_dat_i\[29\] 
+wb_dcache_dat_i\[28\] 
+wb_dcache_dat_i\[27\] 
+wb_dcache_dat_i\[26\] 
+wb_dcache_dat_i\[25\] 
+wb_dcache_dat_i\[24\] 
+wb_dcache_dat_i\[23\] 
+wb_dcache_dat_i\[22\] 
+wb_dcache_dat_i\[21\] 
+wb_dcache_dat_i\[20\] 
+wb_dcache_dat_i\[19\] 
+wb_dcache_dat_i\[18\] 
+wb_dcache_dat_i\[17\] 
+wb_dcache_dat_i\[16\] 
+wb_dcache_dat_i\[15\] 
+wb_dcache_dat_i\[14\] 
+wb_dcache_dat_i\[13\] 
+wb_dcache_dat_i\[12\] 
+wb_dcache_dat_i\[11\] 
+wb_dcache_dat_i\[10\] 
+wb_dcache_dat_i\[9\] 
+wb_dcache_dat_i\[8\] 
+wb_dcache_dat_i\[7\] 
+wb_dcache_dat_i\[6\] 
+wb_dcache_dat_i\[5\] 
+wb_dcache_dat_i\[4\] 
+wb_dcache_dat_i\[3\] 
+wb_dcache_dat_i\[2\] 
+wb_dcache_dat_i\[1\] 
+wb_dcache_dat_i\[0\] 
+wb_dcache_ack_i      
+wb_dcache_lack_i      
+wb_dcache_err_i      
+
+wb_icache_stb_o       1100 0  2
+wb_icache_we_o        
+wb_icache_adr_o\[31\] 
+wb_icache_adr_o\[30\] 
+wb_icache_adr_o\[29\] 
+wb_icache_adr_o\[28\] 
+wb_icache_adr_o\[27\] 
+wb_icache_adr_o\[26\] 
+wb_icache_adr_o\[25\] 
+wb_icache_adr_o\[24\] 
+wb_icache_adr_o\[23\] 
+wb_icache_adr_o\[22\] 
+wb_icache_adr_o\[21\] 
+wb_icache_adr_o\[20\] 
+wb_icache_adr_o\[19\] 
+wb_icache_adr_o\[18\] 
+wb_icache_adr_o\[17\] 
+wb_icache_adr_o\[16\] 
+wb_icache_adr_o\[15\] 
+wb_icache_adr_o\[14\] 
+wb_icache_adr_o\[13\] 
+wb_icache_adr_o\[12\] 
+wb_icache_adr_o\[11\] 
+wb_icache_adr_o\[10\] 
+wb_icache_adr_o\[9\] 
+wb_icache_adr_o\[8\] 
+wb_icache_adr_o\[7\] 
+wb_icache_adr_o\[6\] 
+wb_icache_adr_o\[5\] 
+wb_icache_adr_o\[4\] 
+wb_icache_adr_o\[3\] 
+wb_icache_adr_o\[2\] 
+wb_icache_adr_o\[1\] 
+wb_icache_adr_o\[0\] 
+wb_icache_sel_o\[3\]  
+wb_icache_sel_o\[2\]  
+wb_icache_sel_o\[1\]  
+wb_icache_sel_o\[0\]  
+wb_icache_bl_o\[9\]  
+wb_icache_bl_o\[8\]  
+wb_icache_bl_o\[7\]  
+wb_icache_bl_o\[6\]  
+wb_icache_bl_o\[5\]  
+wb_icache_bl_o\[4\]  
+wb_icache_bl_o\[3\]  
+wb_icache_bl_o\[2\]  
+wb_icache_bl_o\[1\]  
+wb_icache_bl_o\[0\]  
+wb_icache_bry_o
+wb_icache_dat_i\[31\] 
+wb_icache_dat_i\[30\] 
+wb_icache_dat_i\[29\] 
+wb_icache_dat_i\[28\] 
+wb_icache_dat_i\[27\] 
+wb_icache_dat_i\[26\] 
+wb_icache_dat_i\[25\] 
+wb_icache_dat_i\[24\] 
+wb_icache_dat_i\[23\] 
+wb_icache_dat_i\[22\] 
+wb_icache_dat_i\[21\] 
+wb_icache_dat_i\[20\] 
+wb_icache_dat_i\[19\] 
+wb_icache_dat_i\[18\] 
+wb_icache_dat_i\[17\] 
+wb_icache_dat_i\[16\] 
+wb_icache_dat_i\[15\] 
+wb_icache_dat_i\[14\] 
+wb_icache_dat_i\[13\] 
+wb_icache_dat_i\[12\] 
+wb_icache_dat_i\[11\] 
+wb_icache_dat_i\[10\] 
+wb_icache_dat_i\[9\] 
+wb_icache_dat_i\[8\] 
+wb_icache_dat_i\[7\] 
+wb_icache_dat_i\[6\] 
+wb_icache_dat_i\[5\] 
+wb_icache_dat_i\[4\] 
+wb_icache_dat_i\[3\] 
+wb_icache_dat_i\[2\] 
+wb_icache_dat_i\[1\] 
+wb_icache_dat_i\[0\] 
+wb_icache_ack_i      
+wb_icache_lack_i      
+wb_icache_err_i      
+
+#W
+sram0_clk1          0000 0 2
+sram0_csb1
+sram0_addr1\[8\]
+sram0_addr1\[7\]
+sram0_addr1\[6\]
+sram0_addr1\[5\]
+sram0_addr1\[4\]
+sram0_addr1\[3\]
+sram0_addr1\[2\]
+sram0_addr1\[1\]
+sram0_addr1\[0\]
+
+sram0_dout1\[0\]     0200 0 2
+sram0_dout1\[1\]
+sram0_dout1\[2\]
+sram0_dout1\[3\]
+sram0_dout1\[4\]
+sram0_dout1\[5\]
+sram0_dout1\[6\]
+sram0_dout1\[7\]
+sram0_dout1\[8\]
+sram0_dout1\[9\]
+sram0_dout1\[10\]
+sram0_dout1\[11\]
+sram0_dout1\[12\]
+sram0_dout1\[13\]
+sram0_dout1\[14\]
+sram0_dout1\[15\]
+sram0_dout1\[16\]
+sram0_dout1\[17\]
+sram0_dout1\[18\]
+sram0_dout1\[19\]
+sram0_dout1\[20\]
+sram0_dout1\[21\]
+sram0_dout1\[22\]
+sram0_dout1\[23\]
+sram0_dout1\[24\]
+sram0_dout1\[25\]
+sram0_dout1\[26\]
+sram0_dout1\[27\]
+sram0_dout1\[28\]
+sram0_dout1\[29\]
+sram0_dout1\[30\]
+sram0_dout1\[31\]
+
+icache_mem_clk0          300 0 2
+icache_mem_csb0
+icache_mem_web0
+icache_mem_addr0\[0\]
+icache_mem_addr0\[1\]
+icache_mem_addr0\[2\]
+icache_mem_addr0\[3\]
+icache_mem_addr0\[4\]
+icache_mem_addr0\[5\]
+icache_mem_addr0\[6\]
+icache_mem_addr0\[7\]
+icache_mem_addr0\[8\]
+icache_mem_wmask0\[0\]
+icache_mem_wmask0\[1\]
+icache_mem_wmask0\[2\]
+icache_mem_wmask0\[3\]
+icache_mem_din0\[0\]
+icache_mem_din0\[1\]
+icache_mem_din0\[2\]
+icache_mem_din0\[3\]
+icache_mem_din0\[4\]
+icache_mem_din0\[5\]
+icache_mem_din0\[6\]
+icache_mem_din0\[7\]
+icache_mem_din0\[8\]
+icache_mem_din0\[9\]
+icache_mem_din0\[10\]
+icache_mem_din0\[11\]
+icache_mem_din0\[12\]
+icache_mem_din0\[13\]
+icache_mem_din0\[14\]
+icache_mem_din0\[15\]
+icache_mem_din0\[16\]
+icache_mem_din0\[17\]
+icache_mem_din0\[18\]
+icache_mem_din0\[19\]
+icache_mem_din0\[20\]
+icache_mem_din0\[21\]
+icache_mem_din0\[22\]
+icache_mem_din0\[23\]
+icache_mem_din0\[24\]
+icache_mem_din0\[25\]
+icache_mem_din0\[26\]
+icache_mem_din0\[27\]
+icache_mem_din0\[28\]
+icache_mem_din0\[29\]
+icache_mem_din0\[30\]
+icache_mem_din0\[31\]
+
+icache_mem_clk1          0400 0 2
+icache_mem_csb1
+icache_mem_addr1\[8\]
+icache_mem_addr1\[7\]
+icache_mem_addr1\[6\]
+icache_mem_addr1\[5\]
+icache_mem_addr1\[4\]
+icache_mem_addr1\[3\]
+icache_mem_addr1\[2\]
+icache_mem_addr1\[1\]
+icache_mem_addr1\[0\]
+
+icache_mem_dout1\[0\]     0450 0 2
+icache_mem_dout1\[1\]
+icache_mem_dout1\[2\]
+icache_mem_dout1\[3\]
+icache_mem_dout1\[4\]
+icache_mem_dout1\[5\]
+icache_mem_dout1\[6\]
+icache_mem_dout1\[7\]
+icache_mem_dout1\[8\]
+icache_mem_dout1\[9\]
+icache_mem_dout1\[10\]
+icache_mem_dout1\[11\]
+icache_mem_dout1\[12\]
+icache_mem_dout1\[13\]
+icache_mem_dout1\[14\]
+icache_mem_dout1\[15\]
+icache_mem_dout1\[16\]
+icache_mem_dout1\[17\]
+icache_mem_dout1\[18\]
+icache_mem_dout1\[19\]
+icache_mem_dout1\[20\]
+icache_mem_dout1\[21\]
+icache_mem_dout1\[22\]
+icache_mem_dout1\[23\]
+icache_mem_dout1\[24\]
+icache_mem_dout1\[25\]
+icache_mem_dout1\[26\]
+icache_mem_dout1\[27\]
+icache_mem_dout1\[28\]
+icache_mem_dout1\[29\]
+icache_mem_dout1\[30\]
+icache_mem_dout1\[31\]
+
+dcache_mem_clk0            850 0 2
+dcache_mem_csb0
+dcache_mem_web0
+dcache_mem_addr0\[0\]
+dcache_mem_addr0\[1\]
+dcache_mem_addr0\[2\]
+dcache_mem_addr0\[3\]
+dcache_mem_addr0\[4\]
+dcache_mem_addr0\[5\]
+dcache_mem_addr0\[6\]
+dcache_mem_addr0\[7\]
+dcache_mem_addr0\[8\]
+dcache_mem_wmask0\[0\]
+dcache_mem_wmask0\[1\]
+dcache_mem_wmask0\[2\]
+dcache_mem_wmask0\[3\]
+dcache_mem_din0\[0\]
+dcache_mem_din0\[1\]
+dcache_mem_din0\[2\]
+dcache_mem_din0\[3\]
+dcache_mem_din0\[4\]
+dcache_mem_din0\[5\]
+dcache_mem_din0\[6\]
+dcache_mem_din0\[7\]
+dcache_mem_din0\[8\]
+dcache_mem_din0\[9\]
+dcache_mem_din0\[10\]
+dcache_mem_din0\[11\]
+dcache_mem_din0\[12\]
+dcache_mem_din0\[13\]
+dcache_mem_din0\[14\]
+dcache_mem_din0\[15\]
+dcache_mem_din0\[16\]
+dcache_mem_din0\[17\]
+dcache_mem_din0\[18\]
+dcache_mem_din0\[19\]
+dcache_mem_din0\[20\]
+dcache_mem_din0\[21\]
+dcache_mem_din0\[22\]
+dcache_mem_din0\[23\]
+dcache_mem_din0\[24\]
+dcache_mem_din0\[25\]
+dcache_mem_din0\[26\]
+dcache_mem_din0\[27\]
+dcache_mem_din0\[28\]
+dcache_mem_din0\[29\]
+dcache_mem_din0\[30\]
+dcache_mem_din0\[31\]
+
+
+dcache_mem_dout0\[0\]   950 0 2
+dcache_mem_dout0\[1\]
+dcache_mem_dout0\[2\]
+dcache_mem_dout0\[3\]
+dcache_mem_dout0\[4\]
+dcache_mem_dout0\[5\]
+dcache_mem_dout0\[6\]
+dcache_mem_dout0\[7\]
+dcache_mem_dout0\[8\]
+dcache_mem_dout0\[9\]
+dcache_mem_dout0\[10\]
+dcache_mem_dout0\[11\]
+dcache_mem_dout0\[12\]
+dcache_mem_dout0\[13\]
+dcache_mem_dout0\[14\]
+dcache_mem_dout0\[15\]
+dcache_mem_dout0\[16\]
+dcache_mem_dout0\[17\]
+dcache_mem_dout0\[18\]
+dcache_mem_dout0\[19\]
+dcache_mem_dout0\[20\]
+dcache_mem_dout0\[21\]
+dcache_mem_dout0\[22\]
+dcache_mem_dout0\[23\]
+dcache_mem_dout0\[24\]
+dcache_mem_dout0\[25\]
+dcache_mem_dout0\[26\]
+dcache_mem_dout0\[27\]
+dcache_mem_dout0\[28\]
+dcache_mem_dout0\[29\]
+dcache_mem_dout0\[30\]
+dcache_mem_dout0\[31\]
+
+dcache_mem_clk1         1000 0 2
+dcache_mem_csb1
+dcache_mem_addr1\[8\]
+dcache_mem_addr1\[7\]
+dcache_mem_addr1\[6\]
+dcache_mem_addr1\[5\]
+dcache_mem_addr1\[4\]
+dcache_mem_addr1\[3\]
+dcache_mem_addr1\[2\]
+dcache_mem_addr1\[1\]
+dcache_mem_addr1\[0\]
+
+dcache_mem_dout1\[0\]   1050 0 2
+dcache_mem_dout1\[1\]
+dcache_mem_dout1\[2\]
+dcache_mem_dout1\[3\]
+dcache_mem_dout1\[4\]
+dcache_mem_dout1\[5\]
+dcache_mem_dout1\[6\]
+dcache_mem_dout1\[7\]
+dcache_mem_dout1\[8\]
+dcache_mem_dout1\[9\]
+dcache_mem_dout1\[10\]
+dcache_mem_dout1\[11\]
+dcache_mem_dout1\[12\]
+dcache_mem_dout1\[13\]
+dcache_mem_dout1\[14\]
+dcache_mem_dout1\[15\]
+dcache_mem_dout1\[16\]
+dcache_mem_dout1\[17\]
+dcache_mem_dout1\[18\]
+dcache_mem_dout1\[19\]
+dcache_mem_dout1\[20\]
+dcache_mem_dout1\[21\]
+dcache_mem_dout1\[22\]
+dcache_mem_dout1\[23\]
+dcache_mem_dout1\[24\]
+dcache_mem_dout1\[25\]
+dcache_mem_dout1\[26\]
+dcache_mem_dout1\[27\]
+dcache_mem_dout1\[28\]
+dcache_mem_dout1\[29\]
+dcache_mem_dout1\[30\]
+dcache_mem_dout1\[31\]
+
+#S
+sram0_clk0              0 0 2
+sram0_csb0
+sram0_web0
+sram0_addr0\[0\]
+sram0_addr0\[1\]
+sram0_addr0\[2\]
+sram0_addr0\[3\]
+sram0_addr0\[4\]
+sram0_addr0\[5\]
+sram0_addr0\[6\]
+sram0_addr0\[7\]
+sram0_addr0\[8\]
+sram0_wmask0\[0\]
+sram0_wmask0\[1\]
+sram0_wmask0\[2\]
+sram0_wmask0\[3\]
+sram0_din0\[0\]
+sram0_din0\[1\]
+sram0_din0\[2\]
+sram0_din0\[3\]
+sram0_din0\[4\]
+sram0_din0\[5\]
+sram0_din0\[6\]
+sram0_din0\[7\]
+sram0_din0\[8\]
+sram0_din0\[9\]
+sram0_din0\[10\]
+sram0_din0\[11\]
+sram0_din0\[12\]
+sram0_din0\[13\]
+sram0_din0\[14\]
+sram0_din0\[15\]
+sram0_din0\[16\]
+sram0_din0\[17\]
+sram0_din0\[18\]
+sram0_din0\[19\]
+sram0_din0\[20\]
+sram0_din0\[21\]
+sram0_din0\[22\]
+sram0_din0\[23\]
+sram0_din0\[24\]
+sram0_din0\[25\]
+sram0_din0\[26\]
+sram0_din0\[27\]
+sram0_din0\[28\]
+sram0_din0\[29\]
+sram0_din0\[30\]
+sram0_din0\[31\]
+
+
+sram0_dout0\[0\]  0100 0 2
+sram0_dout0\[1\]
+sram0_dout0\[2\]
+sram0_dout0\[3\]
+sram0_dout0\[4\]
+sram0_dout0\[5\]
+sram0_dout0\[6\]
+sram0_dout0\[7\]
+sram0_dout0\[8\]
+sram0_dout0\[9\]
+sram0_dout0\[10\]
+sram0_dout0\[11\]
+sram0_dout0\[12\]
+sram0_dout0\[13\]
+sram0_dout0\[14\]
+sram0_dout0\[15\]
+sram0_dout0\[16\]
+sram0_dout0\[17\]
+sram0_dout0\[18\]
+sram0_dout0\[19\]
+sram0_dout0\[20\]
+sram0_dout0\[21\]
+sram0_dout0\[22\]
+sram0_dout0\[23\]
+sram0_dout0\[24\]
+sram0_dout0\[25\]
+sram0_dout0\[26\]
+sram0_dout0\[27\]
+sram0_dout0\[28\]
+sram0_dout0\[29\]
+sram0_dout0\[30\]
+sram0_dout0\[31\]
+
+riscv_debug\[0\]      300  0 2
+riscv_debug\[1\]
+riscv_debug\[2\]
+riscv_debug\[3\]
+riscv_debug\[4\]
+riscv_debug\[5\]
+riscv_debug\[6\]
+riscv_debug\[7\]
+riscv_debug\[8\]
+riscv_debug\[9\]
+riscv_debug\[10\]
+riscv_debug\[11\]
+riscv_debug\[12\]
+riscv_debug\[13\]
+riscv_debug\[14\]
+riscv_debug\[15\]
+riscv_debug\[16\]
+riscv_debug\[17\]
+riscv_debug\[18\]
+riscv_debug\[19\]
+riscv_debug\[20\]
+riscv_debug\[21\]
+riscv_debug\[22\]
+riscv_debug\[23\]
+riscv_debug\[24\]
+riscv_debug\[25\]
+riscv_debug\[26\]
+riscv_debug\[27\]
+riscv_debug\[28\]
+riscv_debug\[29\]
+riscv_debug\[30\]
+riscv_debug\[31\]
+riscv_debug\[32\]
+riscv_debug\[33\]
+riscv_debug\[34\]
+riscv_debug\[35\]
+riscv_debug\[36\]
+riscv_debug\[37\]
+riscv_debug\[38\]
+riscv_debug\[39\]
+riscv_debug\[40\]
+riscv_debug\[41\]
+riscv_debug\[42\]
+riscv_debug\[43\]
+riscv_debug\[44\]
+riscv_debug\[45\]
+riscv_debug\[46\]
+riscv_debug\[47\]
+riscv_debug\[48\]
+riscv_debug\[49\]
+riscv_debug\[50\]
+riscv_debug\[51\]
+riscv_debug\[52\]
+riscv_debug\[53\]
+riscv_debug\[54\]
+riscv_debug\[55\]
+riscv_debug\[56\]
+riscv_debug\[57\]
+riscv_debug\[58\]
+riscv_debug\[59\]
+riscv_debug\[60\]
+riscv_debug\[61\]
+riscv_debug\[62\]
+riscv_debug\[63\]
+
+
+wb_rst_n          500 0 2
+pwrup_rst_n       
+rst_n        
+core_clk              
+rtc_clk             
+cpu_rst_n           
diff --git a/openlane/yifive/sta.tcl b/openlane/yifive/sta.tcl
new file mode 100644
index 0000000..8168d16
--- /dev/null
+++ b/openlane/yifive/sta.tcl
@@ -0,0 +1,95 @@
+# 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>
+
+set ::env(LIB_FASTEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ff_n40C_1v95.lib"
+set ::env(LIB_TYPICAL) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib"
+set ::env(LIB_SLOWEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ss_100C_1v60.lib"
+set ::env(CURRENT_NETLIST) ../user_project_wrapper/netlist/syntacore.v
+set ::env(DESIGN_NAME) "scr1_top_wb"
+set ::env(CURRENT_SPEF) ../../spef/scr1_top_wb.spef
+set ::env(BASE_SDC_FILE) "base.sdc"
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8"
+set ::env(SYNTH_DRIVING_CELL_PIN) "Y"
+set ::env(SYNTH_CAP_LOAD) "17.65"
+set ::env(WIRE_RC_LAYER) "met1"
+
+
+set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um
+define_corners wc bc tt
+read_liberty -corner bc $::env(LIB_FASTEST)
+read_liberty -corner wc $::env(LIB_SLOWEST)
+read_liberty -corner tt $::env(LIB_TYPICAL)
+
+read_verilog $::env(CURRENT_NETLIST)
+link_design  $::env(DESIGN_NAME)
+
+read_spef  $::env(CURRENT_SPEF)
+
+read_sdc -echo $::env(BASE_SDC_FILE)
+
+# check for missing constraints
+check_setup  -verbose > unconstraints.rpt
+
+set_operating_conditions -analysis_type single
+# Propgate the clock
+set_propagated_clock [all_clocks]
+
+report_tns
+report_wns
+#report_power 
+
+echo "################ CORNER : WC (SLOW) TIMING Report ###################" > timing_ss_max.rpt
+report_checks -unique -path_delay max -slack_max -0.0 -group_count 100   -corner wc  -format full_clock_expanded >> timing_ss_max.rpt
+report_checks -group_count 100 -path_delay max  -path_group  wbm_clk_i   -corner wc  -format full_clock_expanded >> timing_ss_max.rpt
+report_checks -group_count 100 -path_delay max  -path_group  wbs_clk_i   -corner wc  -format full_clock_expanded >> timing_ss_max.rpt
+report_checks -group_count 100 -path_delay max  -path_group  cpu_clk     -corner wc  -format full_clock_expanded >> timing_ss_max.rpt
+report_checks -group_count 100 -path_delay max  -path_group  rtc_clk     -corner wc  -format full_clock_expanded >> timing_ss_max.rpt
+report_checks -group_count 100 -path_delay max  -path_group  line_clk    -corner wc  -format full_clock_expanded >> timing_ss_max.rpt
+report_checks -path_delay max   -corner wc >> timing_ff_max.rpt
+
+echo "################ CORNER : BC (SLOW) TIMING Report ###################" > timing_ff_min.rpt
+report_checks -unique -path_delay min -slack_min -0.0 -group_count 100   -corner bc  -format full_clock_expanded >> timing_ff_min.rpt
+report_checks -group_count 100  -path_delay min -path_group  wbm_clk_i   -corner bc  -format full_clock_expanded >> timing_ff_min.rpt
+report_checks -group_count 100  -path_delay min -path_group  wbs_clk_i   -corner bc  -format full_clock_expanded >> timing_ff_min.rpt
+report_checks -group_count 100  -path_delay min -path_group  cpu_clk     -corner bc  -format full_clock_expanded >> timing_ff_min.rpt
+report_checks -group_count 100  -path_delay min -path_group  rtc_clk     -corner bc  -format full_clock_expanded >> timing_ff_min.rpt
+report_checks -group_count 100  -path_delay min -path_group  line_clk    -corner bc  -format full_clock_expanded >> timing_ff_min.rpt
+report_checks -path_delay min  -corner bc >> timing_min.rpt
+
+echo "################ CORNER : TT (MAX) TIMING Report ###################" > timing_tt_max.rpt 
+report_checks -unique -path_delay max -slack_min -0.0 -group_count 100 -corner tt  -format full_clock_expanded >> timing_tt_max.rpt
+report_checks -group_count 100  -path_delay max -path_group wbm_clk_i  -corner tt  -format full_clock_expanded >> timing_tt_max.rpt
+report_checks -group_count 100  -path_delay max -path_group wbs_clk_i  -corner tt  -format full_clock_expanded >> timing_tt_max.rpt
+report_checks -group_count 100  -path_delay max -path_group cpu_clk    -corner tt  -format full_clock_expanded >> timing_tt_max.rpt
+report_checks -group_count 100  -path_delay max -path_group rtc_clk    -corner tt  -format full_clock_expanded >> timing_tt_max.rpt
+report_checks -group_count 100  -path_delay max -path_group line_clk   -corner tt  -format full_clock_expanded >> timing_tt_max.rpt
+report_checks -path_delay max  -corner tt >> timing_tt_max.rpt
+
+echo "################ CORNER : TT (MIN) TIMING Report ###################" > timing_tt_min.rpt
+report_checks -unique -path_delay min -slack_min -0.0 -group_count 100   -corner tt  -format full_clock_expanded >> timing_tt_min.rpt
+report_checks -group_count 100  -path_delay min -path_group  wbm_clk_i   -corner tt  -format full_clock_expanded >> timing_tt_min.rpt
+report_checks -group_count 100  -path_delay min -path_group  wbs_clk_i   -corner tt  -format full_clock_expanded >> timing_tt_min.rpt
+report_checks -group_count 100  -path_delay min -path_group  cpu_clk     -corner tt  -format full_clock_expanded >> timing_tt_min.rpt
+report_checks -group_count 100  -path_delay min -path_group  rtc_clk     -corner tt  -format full_clock_expanded >> timing_tt_min.rpt
+report_checks -group_count 100  -path_delay min -path_group  line_clk    -corner tt  -format full_clock_expanded >> timing_tt_min.rpt
+report_checks -path_delay min  -corner tt >> timing_tt_min.rpt
+
+
+
+
+report_checks -path_delay min_max 
+
+#exit
diff --git a/run_regress b/run_regress
new file mode 100644
index 0000000..a18199a
--- /dev/null
+++ b/run_regress
@@ -0,0 +1,6 @@
+make verify-wb_port
+make verify-user_spi
+make verify-user_i2cm 
+make verify-user_uart 
+make verify-user_risc_boot
+make verify-risc_boot
diff --git a/signoff/clk_buf/OPENLANE_VERSION b/signoff/clk_buf/OPENLANE_VERSION
new file mode 100644
index 0000000..a2633b1
--- /dev/null
+++ b/signoff/clk_buf/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane rc7
diff --git a/signoff/clk_buf/PDK_SOURCES b/signoff/clk_buf/PDK_SOURCES
new file mode 100644
index 0000000..8b58bd5
--- /dev/null
+++ b/signoff/clk_buf/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+a68c95289612a361870acedb7f6478fcfae32e49
+-ne skywater-pdk 
+f6f76f3dc99526c6fc2cfede19b5b1227d4ebde7
+-ne open_pdks 
+522a373441a865fee9d6e3783015b4445f11afe6
diff --git a/signoff/clk_buf/final_summary_report.csv b/signoff/clk_buf/final_summary_report.csv
new file mode 100644
index 0000000..f6ee716
--- /dev/null
+++ b/signoff/clk_buf/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/clk_buf,clk_buf,clk_buf,Flow_completed,0h1m2s,0h0m26s,925.925925925926,0.0018,555.5555555555555,3,382.24,1,0,0,0,0,0,0,0,0,0,0,0,45,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,49267,0.0,0.58,0.26,0.0,-1,-1,2,2,2,2,0,0,0,1,0,0,0,0,0,0,0,0,-1,-1,-1,14,13,0,27,90.9090909090909,11,10,AREA 0,5,60,1,30,30,0.55,0,sky130_fd_sc_hd,4,3
diff --git a/signoff/clk_skew_adjust/OPENLANE_VERSION b/signoff/clk_skew_adjust/OPENLANE_VERSION
new file mode 100644
index 0000000..ad796aa
--- /dev/null
+++ b/signoff/clk_skew_adjust/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane v0.21-6-gbc3b032
diff --git a/signoff/clk_skew_adjust/PDK_SOURCES b/signoff/clk_skew_adjust/PDK_SOURCES
new file mode 100644
index 0000000..8b58bd5
--- /dev/null
+++ b/signoff/clk_skew_adjust/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+a68c95289612a361870acedb7f6478fcfae32e49
+-ne skywater-pdk 
+f6f76f3dc99526c6fc2cfede19b5b1227d4ebde7
+-ne open_pdks 
+522a373441a865fee9d6e3783015b4445f11afe6
diff --git a/signoff/clk_skew_adjust/final_summary_report.csv b/signoff/clk_skew_adjust/final_summary_report.csv
new file mode 100644
index 0000000..6c84744
--- /dev/null
+++ b/signoff/clk_skew_adjust/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/clk_skew_adjust,clk_skew_adjust,clk_skew_adjust,Flow_completed,0h1m15s,0h0m36s,7500.0,0.01,3000.0,5,391.95,30,0,0,0,0,0,0,0,0,0,0,0,2812,197,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0.0,6.42,6.62,0.0,-1,-1,32,35,32,35,0,0,0,30,0,0,0,0,0,0,0,0,-1,-1,-1,64,102,0,166,90.9090909090909,11,10,AREA 0,5,40,1,20,20,0.55,0,sky130_fd_sc_hd,4,3
diff --git a/signoff/glbl_cfg/OPENLANE_VERSION b/signoff/glbl_cfg/OPENLANE_VERSION
new file mode 100644
index 0000000..ad796aa
--- /dev/null
+++ b/signoff/glbl_cfg/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane v0.21-6-gbc3b032
diff --git a/signoff/glbl_cfg/PDK_SOURCES b/signoff/glbl_cfg/PDK_SOURCES
new file mode 100644
index 0000000..8b58bd5
--- /dev/null
+++ b/signoff/glbl_cfg/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+a68c95289612a361870acedb7f6478fcfae32e49
+-ne skywater-pdk 
+f6f76f3dc99526c6fc2cfede19b5b1227d4ebde7
+-ne open_pdks 
+522a373441a865fee9d6e3783015b4445f11afe6
diff --git a/signoff/glbl_cfg/final_summary_report.csv b/signoff/glbl_cfg/final_summary_report.csv
new file mode 100644
index 0000000..68bccb3
--- /dev/null
+++ b/signoff/glbl_cfg/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/glbl_cfg,glbl_cfg,glbl_cfg,Flow_completed,0h15m36s,0h9m28s,45883.33333333334,0.12,22941.66666666667,40,569.11,2753,0,0,0,0,0,0,0,0,0,-1,0,131923,23407,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,98939272,0.0,25.3,27.26,0.31,-1,-1,2637,2802,459,624,0,0,0,2753,1,0,3,0,471,0,0,562,577,533,10,278,1410,0,1688,100.0,10.0,10,AREA 0,4,50,1,100,100,0.55,0,sky130_fd_sc_hd,4,5
diff --git a/signoff/mbist/OPENLANE_VERSION b/signoff/mbist/OPENLANE_VERSION
new file mode 100644
index 0000000..80c7664
--- /dev/null
+++ b/signoff/mbist/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane N/A
diff --git a/signoff/mbist/PDK_SOURCES b/signoff/mbist/PDK_SOURCES
new file mode 100644
index 0000000..ca3684a
--- /dev/null
+++ b/signoff/mbist/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+8d686c081c2c9aefa16dbbd8ccf5bc8f4dcabc4b
+-ne skywater-pdk 
+c094b6e83a4f9298e47f696ec5a7fd53535ec5eb
+-ne open_pdks 
+14db32aa8ba330e88632ff3ad2ff52f4f4dae1ad
diff --git a/signoff/mbist/final_summary_report.csv b/signoff/mbist/final_summary_report.csv
new file mode 100644
index 0000000..78824ce
--- /dev/null
+++ b/signoff/mbist/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/mbist,mbist_top,mbist,flow_completed,0h11m2s,-1,20833.333333333336,0.3,10416.666666666668,13.1,663.13,3125,0,0,0,0,0,0,0,10,0,0,-1,458568,43437,-0.67,-6.26,-1,-1.39,-1,-0.67,-3033.14,-1,-1.39,-1,372704250.0,1.47,48.85,12.24,20.92,0.0,-1,2382,6613,753,4936,0,0,0,2339,0,0,0,0,0,0,0,4,849,672,17,130,3852,0,3982,90.9090909090909,11,10,AREA 0,4,50,1,140,140,0.3,0.0,sky130_fd_sc_hd,4,4
diff --git a/signoff/mbist_wrapper/OPENLANE_VERSION b/signoff/mbist_wrapper/OPENLANE_VERSION
new file mode 100644
index 0000000..80c7664
--- /dev/null
+++ b/signoff/mbist_wrapper/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane N/A
diff --git a/signoff/mbist_wrapper/PDK_SOURCES b/signoff/mbist_wrapper/PDK_SOURCES
new file mode 100644
index 0000000..ca3684a
--- /dev/null
+++ b/signoff/mbist_wrapper/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+8d686c081c2c9aefa16dbbd8ccf5bc8f4dcabc4b
+-ne skywater-pdk 
+c094b6e83a4f9298e47f696ec5a7fd53535ec5eb
+-ne open_pdks 
+14db32aa8ba330e88632ff3ad2ff52f4f4dae1ad
diff --git a/signoff/mbist_wrapper/final_summary_report.csv b/signoff/mbist_wrapper/final_summary_report.csv
new file mode 100644
index 0000000..b6c97f9
--- /dev/null
+++ b/signoff/mbist_wrapper/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/mbist_wrapper,mbist_wrapper,mbist_wrapper,flow_completed,0h14m13s,-1,26073.260073260073,0.273,13036.630036630037,16.48,695.21,3559,0,0,0,0,0,0,-1,16,0,0,-1,445806,47865,-0.67,-5.91,-1,-1.78,-1,-0.67,-2737.45,-1,-1.78,-1,357342288.0,5.91,47.85,15.03,24.02,0.01,-1,2596,7282,753,5382,0,0,0,2664,0,0,0,0,0,0,0,4,1049,798,17,138,3514,0,3652,90.9090909090909,11,10,AREA 0,4,50,1,140,140,0.35,0.0,sky130_fd_sc_hd,4,4
diff --git a/signoff/pinmux/OPENLANE_VERSION b/signoff/pinmux/OPENLANE_VERSION
new file mode 100644
index 0000000..80c7664
--- /dev/null
+++ b/signoff/pinmux/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane N/A
diff --git a/signoff/pinmux/PDK_SOURCES b/signoff/pinmux/PDK_SOURCES
new file mode 100644
index 0000000..ca3684a
--- /dev/null
+++ b/signoff/pinmux/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+8d686c081c2c9aefa16dbbd8ccf5bc8f4dcabc4b
+-ne skywater-pdk 
+c094b6e83a4f9298e47f696ec5a7fd53535ec5eb
+-ne open_pdks 
+14db32aa8ba330e88632ff3ad2ff52f4f4dae1ad
diff --git a/signoff/pinmux/final_summary_report.csv b/signoff/pinmux/final_summary_report.csv
new file mode 100644
index 0000000..7337820
--- /dev/null
+++ b/signoff/pinmux/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/pinmux,pinmux,pinmux,flow_completed,0h16m12s,-1,46109.09090909091,0.2475,23054.545454545456,27.07,714.13,5706,0,0,0,0,0,0,-1,1,0,-1,-1,434666,61807,0.0,-0.01,-1,0.0,-1,0.0,-0.03,-1,0.0,-1,320204079.0,5.99,43.88,33.8,11.89,0.3,-1,3574,8564,543,5532,0,0,0,4202,0,0,0,0,0,0,0,4,1343,1339,16,314,3259,0,3573,90.9090909090909,11,10,AREA 0,4,50,1,100,100,0.3,0.0,sky130_fd_sc_hd,4,4
diff --git a/signoff/qspim/OPENLANE_VERSION b/signoff/qspim/OPENLANE_VERSION
new file mode 100644
index 0000000..80c7664
--- /dev/null
+++ b/signoff/qspim/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane N/A
diff --git a/signoff/qspim/PDK_SOURCES b/signoff/qspim/PDK_SOURCES
new file mode 100644
index 0000000..ca3684a
--- /dev/null
+++ b/signoff/qspim/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+8d686c081c2c9aefa16dbbd8ccf5bc8f4dcabc4b
+-ne skywater-pdk 
+c094b6e83a4f9298e47f696ec5a7fd53535ec5eb
+-ne open_pdks 
+14db32aa8ba330e88632ff3ad2ff52f4f4dae1ad
diff --git a/signoff/qspim/final_summary_report.csv b/signoff/qspim/final_summary_report.csv
new file mode 100644
index 0000000..eafe299
--- /dev/null
+++ b/signoff/qspim/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/qspim,qspim_top,qspim,flow_completed,0h18m13s,-1,69139.39393939394,0.2475,34569.69696969697,39.57,778.62,8556,0,0,0,0,0,0,-1,1,0,-1,-1,423083,80674,-0.2,-5.37,-1,0.0,-1,-6.1,-2269.63,-1,0.0,-1,266384048.0,0.0,40.72,38.22,6.38,1.41,-1,7371,11035,803,4466,0,0,0,8344,0,0,0,0,0,0,0,4,2003,2524,22,388,3234,0,3622,90.9090909090909,11,10,AREA 0,4,50,1,100,100,0.42,0.0,sky130_fd_sc_hd,4,4
diff --git a/signoff/sar_adc/OPENLANE_VERSION b/signoff/sar_adc/OPENLANE_VERSION
new file mode 100644
index 0000000..bab6e84
--- /dev/null
+++ b/signoff/sar_adc/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane v0.21-9-g94fe743
diff --git a/signoff/sar_adc/PDK_SOURCES b/signoff/sar_adc/PDK_SOURCES
new file mode 100644
index 0000000..8b58bd5
--- /dev/null
+++ b/signoff/sar_adc/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+a68c95289612a361870acedb7f6478fcfae32e49
+-ne skywater-pdk 
+f6f76f3dc99526c6fc2cfede19b5b1227d4ebde7
+-ne open_pdks 
+522a373441a865fee9d6e3783015b4445f11afe6
diff --git a/signoff/sar_adc/final_summary_report.csv b/signoff/sar_adc/final_summary_report.csv
new file mode 100644
index 0000000..17383a9
--- /dev/null
+++ b/signoff/sar_adc/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/sar_adc,sar_adc,sar_adc,Flow_completed,0h1m45s,0h0m56s,1653.3333333333335,0.15,826.6666666666667,1,440.52,124,0,0,0,0,0,0,0,0,13,-1,0,14549,1000,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,12946929,0.0,3.68,1.92,0.36,0.0,-1,102,186,48,132,0,0,0,124,0,0,0,1,12,0,0,32,19,26,5,204,1768,0,1972,10.0,100.0,100,AREA 0,5,50,1,45,40,0.01,0.15,sky130_fd_sc_hd,4,4
diff --git a/signoff/sdram/OPENLANE_VERSION b/signoff/sdram/OPENLANE_VERSION
new file mode 100644
index 0000000..bab6e84
--- /dev/null
+++ b/signoff/sdram/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane v0.21-9-g94fe743
diff --git a/signoff/sdram/PDK_SOURCES b/signoff/sdram/PDK_SOURCES
new file mode 100644
index 0000000..8b58bd5
--- /dev/null
+++ b/signoff/sdram/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+a68c95289612a361870acedb7f6478fcfae32e49
+-ne skywater-pdk 
+f6f76f3dc99526c6fc2cfede19b5b1227d4ebde7
+-ne open_pdks 
+522a373441a865fee9d6e3783015b4445f11afe6
diff --git a/signoff/sdram/final_summary_report.csv b/signoff/sdram/final_summary_report.csv
new file mode 100644
index 0000000..24acce0
--- /dev/null
+++ b/signoff/sdram/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/sdram,sdrc_top,sdram,Flow_completed,0h17m16s,0h6m17s,40708.57142857143,0.35,20354.285714285714,30,662.62,7124,0,0,0,0,0,0,0,0,0,-1,0,316920,56671,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,242866426,0.0,25.86,16.86,2.54,-1,-1,7028,7287,1219,1478,0,0,0,7124,196,107,83,98,352,210,34,2240,1267,1186,23,350,4248,0,4598,100.0,10.0,10,AREA 0,4,50,1,100,100,0.55,0,sky130_fd_sc_hd,4,5
diff --git a/signoff/spi_master/OPENLANE_VERSION b/signoff/spi_master/OPENLANE_VERSION
new file mode 100644
index 0000000..bab6e84
--- /dev/null
+++ b/signoff/spi_master/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane v0.21-9-g94fe743
diff --git a/signoff/spi_master/PDK_SOURCES b/signoff/spi_master/PDK_SOURCES
new file mode 100644
index 0000000..8b58bd5
--- /dev/null
+++ b/signoff/spi_master/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+a68c95289612a361870acedb7f6478fcfae32e49
+-ne skywater-pdk 
+f6f76f3dc99526c6fc2cfede19b5b1227d4ebde7
+-ne open_pdks 
+522a373441a865fee9d6e3783015b4445f11afe6
diff --git a/signoff/spi_master/final_summary_report.csv b/signoff/spi_master/final_summary_report.csv
new file mode 100644
index 0000000..8e28748
--- /dev/null
+++ b/signoff/spi_master/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/spi_master,spim_top,spi_master,Flow_completed,0h20m39s,0h10m39s,58438.46153846153,0.26,29219.230769230766,47,664.71,7597,0,0,0,0,0,0,0,0,3,-1,0,384228,67124,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,294776771,0.0,31.33,39.79,0.04,-1,-1,7537,7673,1268,1404,0,0,0,7597,245,0,169,100,1051,210,32,2443,1353,1292,24,460,3132,0,3592,100.0,10.0,10,AREA 0,4,50,1,100,100,0.45,0,sky130_fd_sc_hd,4,5
diff --git a/signoff/syntacore/OPENLANE_VERSION b/signoff/syntacore/OPENLANE_VERSION
new file mode 100644
index 0000000..80c7664
--- /dev/null
+++ b/signoff/syntacore/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane N/A
diff --git a/signoff/syntacore/PDK_SOURCES b/signoff/syntacore/PDK_SOURCES
new file mode 100644
index 0000000..ca3684a
--- /dev/null
+++ b/signoff/syntacore/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+8d686c081c2c9aefa16dbbd8ccf5bc8f4dcabc4b
+-ne skywater-pdk 
+c094b6e83a4f9298e47f696ec5a7fd53535ec5eb
+-ne open_pdks 
+14db32aa8ba330e88632ff3ad2ff52f4f4dae1ad
diff --git a/signoff/syntacore/final_summary_report.csv b/signoff/syntacore/final_summary_report.csv
new file mode 100644
index 0000000..04c97bd
--- /dev/null
+++ b/signoff/syntacore/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/syntacore,scr1_top_wb,syntacore,flow_completed,0h41m48s,-1,53830.971659919036,0.7904,26915.485829959518,30.93,1195.5,21274,0,-1,-1,-1,-1,0,-1,1,0,-1,-1,1674760,240681,-2.04,-17.8,-1,0.0,-1,-2459.49,-21655.63,-1,0.0,-1,1322263875.0,0.0,62.03,24.69,26.16,0.01,-1,18597,30067,1067,12430,0,0,0,21980,0,0,0,0,0,0,0,4,5240,5924,49,366,10822,0,11188,90.9090909090909,11,10,AREA 0,4,50,1,100,100,0.32,0.0,sky130_fd_sc_hd,4,4
diff --git a/signoff/uart/OPENLANE_VERSION b/signoff/uart/OPENLANE_VERSION
new file mode 100644
index 0000000..a2633b1
--- /dev/null
+++ b/signoff/uart/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane rc7
diff --git a/signoff/uart/PDK_SOURCES b/signoff/uart/PDK_SOURCES
new file mode 100644
index 0000000..8b58bd5
--- /dev/null
+++ b/signoff/uart/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+a68c95289612a361870acedb7f6478fcfae32e49
+-ne skywater-pdk 
+f6f76f3dc99526c6fc2cfede19b5b1227d4ebde7
+-ne open_pdks 
+522a373441a865fee9d6e3783015b4445f11afe6
diff --git a/signoff/uart/final_summary_report.csv b/signoff/uart/final_summary_report.csv
new file mode 100644
index 0000000..5d02b7b
--- /dev/null
+++ b/signoff/uart/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/uart,uart_core,uart,Flow_completed,0h6m24s,0h4m13s,46166.66666666667,0.12,23083.333333333336,35,545.14,2770,0,0,0,0,0,0,0,0,0,-1,0,93784,20982,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,62462955,0.0,19.71,19.11,0.0,-1,-1,2769,2789,456,476,0,0,0,2770,56,0,29,41,182,125,26,685,435,396,18,278,1410,0,1688,100.0,10.0,10,AREA 0,4,50,1,100,100,0.55,0,sky130_fd_sc_hd,4,4
diff --git a/signoff/uart_i2cm/OPENLANE_VERSION b/signoff/uart_i2cm/OPENLANE_VERSION
new file mode 100644
index 0000000..a2633b1
--- /dev/null
+++ b/signoff/uart_i2cm/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane rc7
diff --git a/signoff/uart_i2cm/PDK_SOURCES b/signoff/uart_i2cm/PDK_SOURCES
new file mode 100644
index 0000000..8b58bd5
--- /dev/null
+++ b/signoff/uart_i2cm/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+a68c95289612a361870acedb7f6478fcfae32e49
+-ne skywater-pdk 
+f6f76f3dc99526c6fc2cfede19b5b1227d4ebde7
+-ne open_pdks 
+522a373441a865fee9d6e3783015b4445f11afe6
diff --git a/signoff/uart_i2cm/final_summary_report.csv b/signoff/uart_i2cm/final_summary_report.csv
new file mode 100644
index 0000000..6a4c74e
--- /dev/null
+++ b/signoff/uart_i2cm/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/uart_i2cm,uart_i2c_top,uart_i2cm,Flow_completed,0h5m42s,0h3m37s,59350.0,0.12,29675.0,47,561.56,3561,0,0,0,0,0,0,0,0,0,-1,0,124117,27523,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,81974377,0.0,25.57,25.46,0.33,-1,-1,3562,3582,623,643,0,0,0,3561,98,10,58,70,423,155,27,836,589,556,17,278,1410,0,1688,100.0,10.0,10,AREA 0,4,50,1,100,100,0.55,0,sky130_fd_sc_hd,4,4
diff --git a/signoff/uart_i2cm_usb/OPENLANE_VERSION b/signoff/uart_i2cm_usb/OPENLANE_VERSION
new file mode 100644
index 0000000..bab6e84
--- /dev/null
+++ b/signoff/uart_i2cm_usb/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane v0.21-9-g94fe743
diff --git a/signoff/uart_i2cm_usb/PDK_SOURCES b/signoff/uart_i2cm_usb/PDK_SOURCES
new file mode 100644
index 0000000..8b58bd5
--- /dev/null
+++ b/signoff/uart_i2cm_usb/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+a68c95289612a361870acedb7f6478fcfae32e49
+-ne skywater-pdk 
+f6f76f3dc99526c6fc2cfede19b5b1227d4ebde7
+-ne open_pdks 
+522a373441a865fee9d6e3783015b4445f11afe6
diff --git a/signoff/uart_i2cm_usb/final_summary_report.csv b/signoff/uart_i2cm_usb/final_summary_report.csv
new file mode 100644
index 0000000..2c0683d
--- /dev/null
+++ b/signoff/uart_i2cm_usb/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/uart_i2cm_usb,uart_i2c_usb_top,uart_i2cm_usb,Flow_completed,0h25m24s,0h9m59s,59157.14285714286,0.42,29578.57142857143,45,758.68,12423,0,0,0,0,0,0,0,0,0,-1,0,522443,99881,-3.16,-3.16,-3.07,-3.07,-3.11,-91.08,-91.08,-91.67,-91.67,-91.56,390283627,0.0,31.24,29.46,0.31,-1,-1,12407,12476,2262,2331,0,0,0,12423,364,10,202,244,2118,325,79,2692,2224,2170,26,498,5146,0,5644,76.27765064836004,13.11,10,AREA 0,4,50,1,100,100,0.45,0,sky130_fd_sc_hd,4,5
diff --git a/signoff/uart_i2cm_usb_spi/OPENLANE_VERSION b/signoff/uart_i2cm_usb_spi/OPENLANE_VERSION
new file mode 100644
index 0000000..80c7664
--- /dev/null
+++ b/signoff/uart_i2cm_usb_spi/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane N/A
diff --git a/signoff/uart_i2cm_usb_spi/PDK_SOURCES b/signoff/uart_i2cm_usb_spi/PDK_SOURCES
new file mode 100644
index 0000000..ca3684a
--- /dev/null
+++ b/signoff/uart_i2cm_usb_spi/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+8d686c081c2c9aefa16dbbd8ccf5bc8f4dcabc4b
+-ne skywater-pdk 
+c094b6e83a4f9298e47f696ec5a7fd53535ec5eb
+-ne open_pdks 
+14db32aa8ba330e88632ff3ad2ff52f4f4dae1ad
diff --git a/signoff/uart_i2cm_usb_spi/final_summary_report.csv b/signoff/uart_i2cm_usb_spi/final_summary_report.csv
new file mode 100644
index 0000000..82f2b7b
--- /dev/null
+++ b/signoff/uart_i2cm_usb_spi/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/uart_i2cm_usb_spi,uart_i2c_usb_spi_top,uart_i2cm_usb_spi,flow_completed,0h13m36s,-1,63977.14285714286,0.35,31988.57142857143,37.54,836.07,11196,0,0,0,0,0,0,-1,1,0,-1,-1,434083,97891,-4.52,-4.86,-1,-4.69,-1,-141.37,-151.91,-1,-139.26,-1,264395920.0,0.39,30.63,28.98,0.99,0.4,-1,8563,12970,1541,5891,0,0,0,9737,0,0,0,0,0,0,0,4,2730,2694,26,498,4643,0,5141,90.9090909090909,11,10,AREA 0,4,50,1,100,100,0.45,0.0,sky130_fd_sc_hd,4,4
diff --git a/signoff/user_project_wrapper/OPENLANE_VERSION b/signoff/user_project_wrapper/OPENLANE_VERSION
new file mode 100644
index 0000000..80c7664
--- /dev/null
+++ b/signoff/user_project_wrapper/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane N/A
diff --git a/signoff/user_project_wrapper/PDK_SOURCES b/signoff/user_project_wrapper/PDK_SOURCES
new file mode 100644
index 0000000..22e7dc1
--- /dev/null
+++ b/signoff/user_project_wrapper/PDK_SOURCES
@@ -0,0 +1,3 @@
+openlane 70923d7fbd8998c8da87d905cf9e69bffc13709f
+skywater-pdk c094b6e83a4f9298e47f696ec5a7fd53535ec5eb
+open_pdks 476f7428f7f686de51a5164c702629a9b9f2da46
diff --git a/signoff/user_project_wrapper/final_summary_report.csv b/signoff/user_project_wrapper/final_summary_report.csv
new file mode 100644
index 0000000..a731e6b
--- /dev/null
+++ b/signoff/user_project_wrapper/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,flow completed,0h49m56s0ms,0h3m54s0ms,-2.0,-1,-1,-1,556.96,14,0,0,0,0,0,0,-1,0,1,-1,-1,1417872,9018,0.0,-1,-1,0.0,0.0,0.0,-1,-1,0.0,0.0,-1,0.0,6.67,6.71,1.05,1.33,-1,313,2877,313,2877,0,0,0,14,0,0,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,100.0,10.0,10,AREA 0,5,50,1,80,120,0.55,0.3,sky130_fd_sc_hd,4,0
diff --git a/signoff/wb_host/OPENLANE_VERSION b/signoff/wb_host/OPENLANE_VERSION
new file mode 100644
index 0000000..80c7664
--- /dev/null
+++ b/signoff/wb_host/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane N/A
diff --git a/signoff/wb_host/PDK_SOURCES b/signoff/wb_host/PDK_SOURCES
new file mode 100644
index 0000000..ca3684a
--- /dev/null
+++ b/signoff/wb_host/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+8d686c081c2c9aefa16dbbd8ccf5bc8f4dcabc4b
+-ne skywater-pdk 
+c094b6e83a4f9298e47f696ec5a7fd53535ec5eb
+-ne open_pdks 
+14db32aa8ba330e88632ff3ad2ff52f4f4dae1ad
diff --git a/signoff/wb_host/final_summary_report.csv b/signoff/wb_host/final_summary_report.csv
new file mode 100644
index 0000000..7be1787
--- /dev/null
+++ b/signoff/wb_host/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/wb_host,wb_host,wb_host,flow_completed,0h10m23s,-1,51962.5,0.16,25981.25,34.69,645.3,4157,0,0,0,0,0,0,0,5,0,0,-1,329531,47752,0.0,-0.23,-1,0.0,-1,0.0,-26.36,-1,0.0,-1,265017619.0,4.63,61.49,19.26,29.21,0.09,-1,3490,6163,1024,3553,0,0,0,3793,0,0,0,0,0,0,0,4,1233,1205,17,130,2043,0,2173,90.9090909090909,11,10,AREA 0,4,50,1,100,100,0.35,0.0,sky130_fd_sc_hd,4,4
diff --git a/signoff/wb_interconnect/OPENLANE_VERSION b/signoff/wb_interconnect/OPENLANE_VERSION
new file mode 100644
index 0000000..80c7664
--- /dev/null
+++ b/signoff/wb_interconnect/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane N/A
diff --git a/signoff/wb_interconnect/PDK_SOURCES b/signoff/wb_interconnect/PDK_SOURCES
new file mode 100644
index 0000000..ca3684a
--- /dev/null
+++ b/signoff/wb_interconnect/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+8d686c081c2c9aefa16dbbd8ccf5bc8f4dcabc4b
+-ne skywater-pdk 
+c094b6e83a4f9298e47f696ec5a7fd53535ec5eb
+-ne open_pdks 
+14db32aa8ba330e88632ff3ad2ff52f4f4dae1ad
diff --git a/signoff/wb_interconnect/final_summary_report.csv b/signoff/wb_interconnect/final_summary_report.csv
new file mode 100644
index 0000000..5f2f6ea
--- /dev/null
+++ b/signoff/wb_interconnect/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/wb_interconnect,wb_interconnect,wb_interconnect,flow_completed,0h18m24s,-1,19852.173913043476,0.46,9926.086956521738,9.27,726.88,4566,0,-1,-1,-1,-1,0,-1,1,0,-1,-1,848196,51567,-0.9,-9.3,-1,-1.34,-1,-99.69,-2508.48,-1,-173.72,-1,745063608.0,0.0,15.97,52.54,2.07,42.24,0.0,1776,5292,252,3767,0,0,0,2682,0,0,0,0,0,0,0,4,1192,1079,18,1674,5873,0,7547,90.9090909090909,11,10,AREA 0,2,50,1,153.6,153.18,0.3,0,sky130_fd_sc_hd,4,4
diff --git a/signoff/yifive/OPENLANE_VERSION b/signoff/yifive/OPENLANE_VERSION
new file mode 100644
index 0000000..80c7664
--- /dev/null
+++ b/signoff/yifive/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane N/A
diff --git a/signoff/yifive/PDK_SOURCES b/signoff/yifive/PDK_SOURCES
new file mode 100644
index 0000000..ca3684a
--- /dev/null
+++ b/signoff/yifive/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+8d686c081c2c9aefa16dbbd8ccf5bc8f4dcabc4b
+-ne skywater-pdk 
+c094b6e83a4f9298e47f696ec5a7fd53535ec5eb
+-ne open_pdks 
+14db32aa8ba330e88632ff3ad2ff52f4f4dae1ad
diff --git a/signoff/yifive/final_summary_report.csv b/signoff/yifive/final_summary_report.csv
new file mode 100644
index 0000000..1468984
--- /dev/null
+++ b/signoff/yifive/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/yifive,ycr1_top_wb,yifive,flow_completed,1h15m29s,-1,60431.59065628477,1.12375,30215.795328142383,34.22,1576.42,33955,0,-1,-1,-1,-1,0,-1,1,0,-1,-1,2627806,392238,-14.85,-43.3,-1,-1.42,-1,-32507.17,-16836.69,-1,-10.35,-1,1924632372.0,11.2,42.7,59.54,6.88,11.31,0.0,28631,47773,1744,20479,0,0,0,34029,0,0,0,0,0,0,0,4,8317,8690,56,1122,15482,0,16604,90.9090909090909,11,10,AREA 0,4,50,1,100,100,0.35,0.0,sky130_fd_sc_hd,4,4
diff --git a/sta/Makefile b/sta/Makefile
new file mode 100644
index 0000000..535228e
--- /dev/null
+++ b/sta/Makefile
@@ -0,0 +1,51 @@
+# 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
+
+BLOCKS = sar_adc wb_interconnect syntacore qspim uart_i2cm_usb_spi pinmux wb_host
+DEF = $(foreach block,$(BLOCKS), ../def/$(block).def)
+CLEAN = $(foreach block,$(BLOCKS), clean-$(block))
+
+OPENLANE_TAG = mpw3
+OPENLANE_IMAGE_NAME = dineshannayya/openlane:$(OPENLANE_TAG)
+OPENLANE_NETLIST_COMMAND = "cd /project/sta && openroad -exit scripts/or_write_verilog.tcl | tee logs/$@.log"
+OPENLANE_STA_COMMAND = "cd /project/sta && sta scripts/sta.tcl | tee logs/sta.log"
+
+all: $(BLOCKS) run_sta
+
+$(DEF) :
+	@echo "Missing $@. Please create a def for that design"
+	@exit 1
+
+$(BLOCKS) : % : ../def/%.def  create 
+	docker run -it  -v $(PWD)/..:/project -e DESIGN_NAME=$@ -u $(shell id -u $(USER)):$(shell id -g $(USER)) $(OPENLANE_IMAGE_NAME) sh -c $(OPENLANE_NETLIST_COMMAND)
+
+run_sta: $(BLOCKS)
+	#sta inside the docker is crashing with segmentation fault, so are running sta outside the docker
+	#docker run -it  -v $(PWD)/..:/project -e DESIGN_NAME=$@ -u $(shell id -u $(USER)):$(shell id -g $(USER)) $(OPENLANE_IMAGE_NAME) sh -c $(OPENLANE_STA_COMMAND)
+	sta scripts/sta.tcl | tee logs/sta.log
+
+create: clean
+	@echo "create temp directory :)"
+	mkdir -p netlist
+	mkdir -p logs
+	mkdir -p reports
+
+clean:
+	@echo "clean everything :)"
+	rm -rf netlist
+	rm -rf logs
+	rm -rf reports
+
diff --git a/sta/base.sdc b/sta/base.sdc
new file mode 100644
index 0000000..725da1b
--- /dev/null
+++ b/sta/base.sdc
@@ -0,0 +1,1022 @@
+###############################################################################
+# Created by write_sdc
+# Thu Nov 11 07:50:51 2021
+###############################################################################
+current_design user_project_wrapper
+###############################################################################
+# Timing Constraints
+###############################################################################
+create_clock -name user_clock2 -period 100.0000 [get_ports {user_clock2}]
+create_clock -name wbm_clk_i -period 10.0000 [get_ports {wb_clk_i}]
+set_propagated_clock [get_clocks {wbm_clk_i}]
+create_clock -name wbs_clk_i -period 10.0000  [get_pins {u_wb_host/wbs_clk_out}]
+create_clock -name cpu_clk -period 20.0000    [get_pins {u_wb_host/cpu_clk}]
+create_clock -name rtc_clk -period 50.0000    [get_pins {u_wb_host/rtc_clk}]
+create_clock -name usb_clk -period 20.0000    [get_pins {u_wb_host/usb_clk}]
+create_clock -name line_clk -period 100.0000  [get_pins {u_uart_i2c_usb_spi/u_uart_core.u_lineclk_buf/X}]
+
+set_clock_uncertainty -rise_from [get_clocks {user_clock2}] -rise_to [get_clocks {user_clock2}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {user_clock2}] -rise_to [get_clocks {user_clock2}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {user_clock2}] -fall_to [get_clocks {user_clock2}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {user_clock2}] -fall_to [get_clocks {user_clock2}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {user_clock2}] -rise_to [get_clocks {user_clock2}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {user_clock2}] -rise_to [get_clocks {user_clock2}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {user_clock2}] -fall_to [get_clocks {user_clock2}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {user_clock2}] -fall_to [get_clocks {user_clock2}]  -setup 0.2000
+
+set_clock_uncertainty -rise_from [get_clocks {wbm_clk_i}] -rise_to [get_clocks {wbm_clk_i}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {wbm_clk_i}] -rise_to [get_clocks {wbm_clk_i}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {wbm_clk_i}] -fall_to [get_clocks {wbm_clk_i}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {wbm_clk_i}] -fall_to [get_clocks {wbm_clk_i}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {wbm_clk_i}] -rise_to [get_clocks {wbm_clk_i}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {wbm_clk_i}] -rise_to [get_clocks {wbm_clk_i}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {wbm_clk_i}] -fall_to [get_clocks {wbm_clk_i}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {wbm_clk_i}] -fall_to [get_clocks {wbm_clk_i}]  -setup 0.2000
+
+set_clock_uncertainty -rise_from [get_clocks {wbs_clk_i}] -rise_to [get_clocks {wbs_clk_i}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {wbs_clk_i}] -rise_to [get_clocks {wbs_clk_i}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {wbs_clk_i}] -fall_to [get_clocks {wbs_clk_i}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {wbs_clk_i}] -fall_to [get_clocks {wbs_clk_i}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {wbs_clk_i}] -rise_to [get_clocks {wbs_clk_i}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {wbs_clk_i}] -rise_to [get_clocks {wbs_clk_i}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {wbs_clk_i}] -fall_to [get_clocks {wbs_clk_i}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {wbs_clk_i}] -fall_to [get_clocks {wbs_clk_i}]  -setup 0.2000
+
+set_clock_uncertainty -rise_from [get_clocks {cpu_clk}] -rise_to [get_clocks {cpu_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {cpu_clk}] -rise_to [get_clocks {cpu_clk}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {cpu_clk}] -fall_to [get_clocks {cpu_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {cpu_clk}] -fall_to [get_clocks {cpu_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {cpu_clk}] -rise_to [get_clocks {cpu_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {cpu_clk}] -rise_to [get_clocks {cpu_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {cpu_clk}] -fall_to [get_clocks {cpu_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {cpu_clk}] -fall_to [get_clocks {cpu_clk}]  -setup 0.2000
+
+set_clock_uncertainty -rise_from [get_clocks {usb_clk}] -rise_to [get_clocks {usb_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {usb_clk}] -rise_to [get_clocks {usb_clk}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {usb_clk}] -fall_to [get_clocks {usb_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {usb_clk}] -fall_to [get_clocks {usb_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {usb_clk}] -rise_to [get_clocks {usb_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {usb_clk}] -rise_to [get_clocks {usb_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {usb_clk}] -fall_to [get_clocks {usb_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {usb_clk}] -fall_to [get_clocks {usb_clk}]  -setup 0.2000
+
+set_clock_uncertainty -rise_from [get_clocks {rtc_clk}] -rise_to [get_clocks {rtc_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {rtc_clk}] -rise_to [get_clocks {rtc_clk}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {rtc_clk}] -fall_to [get_clocks {rtc_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {rtc_clk}] -fall_to [get_clocks {rtc_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {rtc_clk}] -rise_to [get_clocks {rtc_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {rtc_clk}] -rise_to [get_clocks {rtc_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {rtc_clk}] -fall_to [get_clocks {rtc_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {rtc_clk}] -fall_to [get_clocks {rtc_clk}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {line_clk}] -rise_to [get_clocks {line_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {line_clk}] -rise_to [get_clocks {line_clk}]  -setup 0.2000
+set_clock_uncertainty -rise_from [get_clocks {line_clk}] -fall_to [get_clocks {line_clk}]  -hold 0.1000
+set_clock_uncertainty -rise_from [get_clocks {line_clk}] -fall_to [get_clocks {line_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {line_clk}] -rise_to [get_clocks {line_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {line_clk}] -rise_to [get_clocks {line_clk}]  -setup 0.2000
+set_clock_uncertainty -fall_from [get_clocks {line_clk}] -fall_to [get_clocks {line_clk}]  -hold 0.1000
+set_clock_uncertainty -fall_from [get_clocks {line_clk}] -fall_to [get_clocks {line_clk}]  -setup 0.2000
+set_clock_groups -name async_clock -asynchronous \
+ -group [get_clocks {cpu_clk}]\
+ -group [get_clocks {line_clk}]\
+ -group [get_clocks {usb_clk}]\
+ -group [get_clocks {rtc_clk}]\
+ -group [get_clocks {wbm_clk_i}]\
+ -group [get_clocks {wbs_clk_i}] -comment {Async Clock group}
+
+set_input_delay 2.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wb_rst_i}]
+
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[0]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[10]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[11]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[12]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[13]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[14]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[15]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[16]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[17]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[18]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[19]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[1]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[20]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[21]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[22]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[23]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[24]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[25]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[26]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[27]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[28]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[29]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[2]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[30]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[31]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[3]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[4]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[5]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[6]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[7]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[8]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[9]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_cyc_i}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[0]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[10]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[11]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[12]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[13]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[14]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[15]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[16]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[17]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[18]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[19]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[1]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[20]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[21]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[22]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[23]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[24]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[25]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[26]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[27]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[28]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[29]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[2]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[30]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[31]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[3]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[4]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[5]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[6]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[7]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[8]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[9]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[0]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[1]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[2]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[3]}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_stb_i}]
+set_input_delay -max 5.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_we_i}]
+
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[0]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[10]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[11]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[12]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[13]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[14]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[15]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[16]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[17]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[18]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[19]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[1]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[20]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[21]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[22]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[23]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[24]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[25]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[26]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[27]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[28]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[29]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[2]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[30]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[31]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[3]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[4]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[5]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[6]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[7]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[8]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_adr_i[9]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_cyc_i}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[0]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[10]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[11]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[12]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[13]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[14]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[15]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[16]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[17]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[18]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[19]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[1]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[20]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[21]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[22]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[23]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[24]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[25]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[26]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[27]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[28]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[29]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[2]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[30]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[31]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[3]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[4]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[5]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[6]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[7]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[8]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_i[9]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[0]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[1]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[2]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_sel_i[3]}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_stb_i}]
+set_input_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_we_i}]
+
+
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_ack_o}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[0]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[10]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[11]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[12]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[13]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[14]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[15]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[16]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[17]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[18]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[19]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[1]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[20]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[21]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[22]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[23]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[24]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[25]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[26]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[27]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[28]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[29]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[2]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[30]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[31]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[3]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[4]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[5]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[6]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[7]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[8]}]
+set_output_delay -max 4.5000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[9]}]
+
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_ack_o}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[0]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[10]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[11]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[12]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[13]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[14]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[15]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[16]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[17]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[18]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[19]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[1]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[20]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[21]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[22]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[23]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[24]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[25]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[26]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[27]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[28]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[29]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[2]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[30]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[31]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[3]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[4]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[5]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[6]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[7]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[8]}]
+set_output_delay -min 1.0000 -clock [get_clocks {wbm_clk_i}] -add_delay [get_ports {wbs_dat_o[9]}]
+###############################################################################
+# Environment
+###############################################################################
+set_load -pin_load 0.0334 [get_ports {wbs_ack_o}]
+set_load -pin_load 0.0334 [get_ports {analog_io[28]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[27]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[26]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[25]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[24]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[23]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[22]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[21]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[20]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[19]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[18]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[17]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[16]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[15]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[14]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[13]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[12]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[11]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[10]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[9]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[8]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[7]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[6]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[5]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[4]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[3]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[2]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[1]}]
+set_load -pin_load 0.0334 [get_ports {analog_io[0]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[37]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[36]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[35]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[34]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[33]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[32]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[31]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[30]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[29]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[28]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[27]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[26]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[25]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[24]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[23]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[22]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[21]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[20]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[19]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[18]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[17]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[16]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[15]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[14]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[13]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[12]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[11]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[10]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[9]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[8]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[7]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[6]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[5]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[4]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[3]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[2]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[1]}]
+set_load -pin_load 0.0334 [get_ports {io_oeb[0]}]
+set_load -pin_load 0.0334 [get_ports {io_out[37]}]
+set_load -pin_load 0.0334 [get_ports {io_out[36]}]
+set_load -pin_load 0.0334 [get_ports {io_out[35]}]
+set_load -pin_load 0.0334 [get_ports {io_out[34]}]
+set_load -pin_load 0.0334 [get_ports {io_out[33]}]
+set_load -pin_load 0.0334 [get_ports {io_out[32]}]
+set_load -pin_load 0.0334 [get_ports {io_out[31]}]
+set_load -pin_load 0.0334 [get_ports {io_out[30]}]
+set_load -pin_load 0.0334 [get_ports {io_out[29]}]
+set_load -pin_load 0.0334 [get_ports {io_out[28]}]
+set_load -pin_load 0.0334 [get_ports {io_out[27]}]
+set_load -pin_load 0.0334 [get_ports {io_out[26]}]
+set_load -pin_load 0.0334 [get_ports {io_out[25]}]
+set_load -pin_load 0.0334 [get_ports {io_out[24]}]
+set_load -pin_load 0.0334 [get_ports {io_out[23]}]
+set_load -pin_load 0.0334 [get_ports {io_out[22]}]
+set_load -pin_load 0.0334 [get_ports {io_out[21]}]
+set_load -pin_load 0.0334 [get_ports {io_out[20]}]
+set_load -pin_load 0.0334 [get_ports {io_out[19]}]
+set_load -pin_load 0.0334 [get_ports {io_out[18]}]
+set_load -pin_load 0.0334 [get_ports {io_out[17]}]
+set_load -pin_load 0.0334 [get_ports {io_out[16]}]
+set_load -pin_load 0.0334 [get_ports {io_out[15]}]
+set_load -pin_load 0.0334 [get_ports {io_out[14]}]
+set_load -pin_load 0.0334 [get_ports {io_out[13]}]
+set_load -pin_load 0.0334 [get_ports {io_out[12]}]
+set_load -pin_load 0.0334 [get_ports {io_out[11]}]
+set_load -pin_load 0.0334 [get_ports {io_out[10]}]
+set_load -pin_load 0.0334 [get_ports {io_out[9]}]
+set_load -pin_load 0.0334 [get_ports {io_out[8]}]
+set_load -pin_load 0.0334 [get_ports {io_out[7]}]
+set_load -pin_load 0.0334 [get_ports {io_out[6]}]
+set_load -pin_load 0.0334 [get_ports {io_out[5]}]
+set_load -pin_load 0.0334 [get_ports {io_out[4]}]
+set_load -pin_load 0.0334 [get_ports {io_out[3]}]
+set_load -pin_load 0.0334 [get_ports {io_out[2]}]
+set_load -pin_load 0.0334 [get_ports {io_out[1]}]
+set_load -pin_load 0.0334 [get_ports {io_out[0]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[127]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[126]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[125]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[124]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[123]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[122]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[121]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[120]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[119]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[118]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[117]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[116]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[115]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[114]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[113]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[112]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[111]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[110]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[109]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[108]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[107]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[106]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[105]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[104]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[103]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[102]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[101]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[100]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[99]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[98]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[97]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[96]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[95]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[94]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[93]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[92]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[91]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[90]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[89]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[88]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[87]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[86]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[85]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[84]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[83]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[82]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[81]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[80]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[79]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[78]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[77]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[76]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[75]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[74]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[73]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[72]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[71]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[70]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[69]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[68]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[67]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[66]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[65]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[64]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[63]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[62]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[61]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[60]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[59]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[58]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[57]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[56]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[55]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[54]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[53]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[52]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[51]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[50]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[49]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[48]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[47]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[46]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[45]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[44]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[43]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[42]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[41]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[40]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[39]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[38]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[37]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[36]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[35]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[34]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[33]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[32]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[31]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[30]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[29]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[28]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[27]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[26]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[25]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[24]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[23]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[22]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[21]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[20]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[19]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[18]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[17]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[16]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[15]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[14]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[13]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[12]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[11]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[10]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[9]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[8]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[7]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[6]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[5]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[4]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[3]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[2]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[1]}]
+set_load -pin_load 0.0334 [get_ports {la_data_out[0]}]
+set_load -pin_load 0.0334 [get_ports {user_irq[2]}]
+set_load -pin_load 0.0334 [get_ports {user_irq[1]}]
+set_load -pin_load 0.0334 [get_ports {user_irq[0]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[31]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[30]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[29]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[28]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[27]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[26]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[25]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[24]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[23]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[22]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[21]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[20]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[19]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[18]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[17]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[16]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[15]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[14]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[13]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[12]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[11]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[10]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[9]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[8]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[7]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[6]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[5]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[4]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[3]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[2]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[1]}]
+set_load -pin_load 0.0334 [get_ports {wbs_dat_o[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {user_clock2}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wb_clk_i}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wb_rst_i}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_cyc_i}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_stb_i}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_we_i}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[28]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[27]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[26]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[25]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[24]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[23]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[22]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[21]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[20]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[19]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[18]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[17]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[16]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[15]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[14]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[13]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[12]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[11]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[10]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[9]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[8]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[7]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {analog_io[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[37]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[36]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[35]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[34]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[33]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[32]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[31]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[30]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[29]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[28]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[27]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[26]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[25]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[24]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[23]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[22]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[21]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[20]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[19]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[18]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[17]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[16]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[15]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[14]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[13]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[12]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[11]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[10]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[9]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[8]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[7]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {io_in[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[127]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[126]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[125]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[124]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[123]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[122]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[121]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[120]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[119]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[118]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[117]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[116]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[115]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[114]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[113]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[112]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[111]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[110]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[109]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[108]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[107]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[106]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[105]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[104]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[103]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[102]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[101]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[100]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[99]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[98]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[97]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[96]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[95]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[94]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[93]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[92]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[91]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[90]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[89]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[88]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[87]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[86]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[85]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[84]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[83]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[82]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[81]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[80]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[79]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[78]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[77]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[76]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[75]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[74]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[73]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[72]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[71]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[70]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[69]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[68]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[67]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[66]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[65]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[64]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[63]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[62]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[61]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[60]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[59]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[58]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[57]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[56]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[55]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[54]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[53]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[52]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[51]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[50]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[49]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[48]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[47]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[46]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[45]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[44]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[43]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[42]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[41]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[40]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[39]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[38]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[37]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[36]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[35]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[34]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[33]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[32]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[31]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[30]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[29]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[28]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[27]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[26]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[25]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[24]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[23]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[22]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[21]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[20]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[19]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[18]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[17]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[16]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[15]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[14]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[13]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[12]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[11]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[10]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[9]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[8]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[7]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_data_in[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[127]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[126]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[125]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[124]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[123]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[122]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[121]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[120]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[119]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[118]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[117]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[116]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[115]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[114]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[113]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[112]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[111]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[110]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[109]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[108]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[107]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[106]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[105]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[104]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[103]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[102]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[101]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[100]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[99]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[98]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[97]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[96]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[95]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[94]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[93]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[92]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[91]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[90]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[89]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[88]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[87]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[86]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[85]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[84]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[83]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[82]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[81]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[80]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[79]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[78]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[77]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[76]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[75]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[74]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[73]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[72]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[71]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[70]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[69]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[68]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[67]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[66]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[65]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[64]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[63]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[62]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[61]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[60]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[59]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[58]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[57]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[56]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[55]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[54]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[53]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[52]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[51]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[50]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[49]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[48]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[47]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[46]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[45]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[44]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[43]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[42]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[41]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[40]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[39]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[38]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[37]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[36]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[35]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[34]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[33]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[32]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[31]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[30]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[29]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[28]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[27]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[26]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[25]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[24]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[23]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[22]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[21]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[20]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[19]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[18]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[17]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[16]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[15]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[14]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[13]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[12]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[11]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[10]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[9]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[8]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[7]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {la_oenb[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[31]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[30]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[29]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[28]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[27]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[26]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[25]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[24]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[23]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[22]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[21]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[20]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[19]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[18]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[17]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[16]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[15]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[14]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[13]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[12]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[11]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[10]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[9]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[8]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[7]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_adr_i[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[31]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[30]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[29]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[28]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[27]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[26]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[25]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[24]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[23]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[22]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[21]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[20]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[19]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[18]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[17]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[16]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[15]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[14]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[13]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[12]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[11]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[10]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[9]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[8]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[7]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_dat_i[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_sel_i[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_sel_i[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_sel_i[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbs_sel_i[0]}]
+set_case_analysis 0 [get_pins {u_intercon/cfg_cska_wi[0]}]
+set_case_analysis 0 [get_pins {u_intercon/cfg_cska_wi[1]}]
+set_case_analysis 0 [get_pins {u_intercon/cfg_cska_wi[2]}]
+set_case_analysis 1 [get_pins {u_intercon/cfg_cska_wi[3]}]
+set_case_analysis 0 [get_pins {u_pinmux/cfg_cska_pinmux[0]}]
+set_case_analysis 1 [get_pins {u_pinmux/cfg_cska_pinmux[1]}]
+set_case_analysis 1 [get_pins {u_pinmux/cfg_cska_pinmux[2]}]
+set_case_analysis 0 [get_pins {u_pinmux/cfg_cska_pinmux[3]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_sp_co[0]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_sp_co[1]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_sp_co[2]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_sp_co[3]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_spi[0]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_spi[1]}]
+set_case_analysis 0 [get_pins {u_qspi_master/cfg_cska_spi[2]}]
+set_case_analysis 1 [get_pins {u_qspi_master/cfg_cska_spi[3]}]
+set_case_analysis 1 [get_pins {u_riscv_top/cfg_cska_riscv[0]}]
+set_case_analysis 1 [get_pins {u_riscv_top/cfg_cska_riscv[1]}]
+set_case_analysis 1 [get_pins {u_riscv_top/cfg_cska_riscv[2]}]
+set_case_analysis 0 [get_pins {u_riscv_top/cfg_cska_riscv[3]}]
+set_case_analysis 0 [get_pins {u_wb_host/cfg_cska_wh[0]}]
+set_case_analysis 0 [get_pins {u_wb_host/cfg_cska_wh[1]}]
+set_case_analysis 0 [get_pins {u_wb_host/cfg_cska_wh[2]}]
+set_case_analysis 1 [get_pins {u_wb_host/cfg_cska_wh[3]}]
+
+set_case_analysis 1 [get_pins {u_uart_i2c_usb_spi/cfg_cska_uart[3]}]
+set_case_analysis 0 [get_pins {u_uart_i2c_usb_spi/cfg_cska_uart[2]}]
+set_case_analysis 0 [get_pins {u_uart_i2c_usb_spi/cfg_cska_uart[1]}]
+set_case_analysis 0 [get_pins {u_uart_i2c_usb_spi/cfg_cska_uart[0]}]
+###############################################################################
+# Design Rules
+###############################################################################
+
+#disable clock gating check at static clock select pins
+set_false_path -through [get_pins u_wb_host/u_cpu_ref_sel.u_mux/S]
+set_false_path -through [get_pins u_wb_host/u_cpu_clk_sel.u_mux/S]
+set_false_path -through [get_pins u_wb_host/u_wbs_clk_sel.u_mux/S]
+set_false_path -through [get_pins u_wb_host/u_usb_clk_sel.u_mux/S]
+
+#Strobe is registered inside the wb_host before generating chip select
+# So wbm_adr_i  wbm_we_i wbm_sel_i wbm_dat_i are having 2 cycle setup
+
+set_multicycle_path -setup -from [get_ports {wbs_adr_i[*]}] 2
+set_multicycle_path -setup -from [get_ports {wbs_cyc_i}]  2
+set_multicycle_path -setup -from [get_ports {wbs_dat_i[*]}] 2
+set_multicycle_path -setup -from [get_ports {wbs_sel_i[*]}] 2
+set_multicycle_path -setup -from [get_ports {wbs_we_i}] 2
+
+set_multicycle_path -hold -from [get_ports {wbs_adr_i[*]}] 2
+set_multicycle_path -hold -from [get_ports {wbs_cyc_i}]  2
+set_multicycle_path -hold -from [get_ports {wbs_dat_i[*]}] 2
+set_multicycle_path -hold -from [get_ports {wbs_sel_i[*]}] 2
+set_multicycle_path -hold -from [get_ports {wbs_we_i}] 2
diff --git a/sta/run_sta b/sta/run_sta
new file mode 100755
index 0000000..744d864
--- /dev/null
+++ b/sta/run_sta
@@ -0,0 +1,35 @@
+
+\rm -rf netlist
+\rm -rf logs
+\rm -rf reports
+mkdir  netlist
+mkdir  logs
+mkdir  reports
+
+echo "#################################################"
+echo "Genenerating Netlist winout power ports"
+echo "#################################################"
+export MERGED_LEF_UNPADDED=../lef/merged_unpadded.lef
+
+export DESIGN_NAME=sar_adc
+openroad -exit scripts/or_write_verilog.tcl 
+
+export DESIGN_NAME=wb_interconnect
+openroad -exit scripts/or_write_verilog.tcl 
+
+export DESIGN_NAME=syntacore
+openroad -exit scripts/or_write_verilog.tcl 
+
+export DESIGN_NAME=qspim
+openroad -exit scripts/or_write_verilog.tcl 
+
+export DESIGN_NAME=uart_i2cm_usb_spi
+openroad -exit scripts/or_write_verilog.tcl 
+
+export DESIGN_NAME=pinmux
+openroad -exit scripts/or_write_verilog.tcl 
+
+export DESIGN_NAME=wb_host
+openroad -exit scripts/or_write_verilog.tcl 
+
+sta scripts/sta.tcl | tee logs/sta.log
diff --git a/sta/scripts/caravel_timing.tcl b/sta/scripts/caravel_timing.tcl
new file mode 100644
index 0000000..f78d21e
--- /dev/null
+++ b/sta/scripts/caravel_timing.tcl
@@ -0,0 +1,185 @@
+
+        set ::env(USER_ROOT)    "/home/dinesha/workarea/opencore/git/riscduino"
+        set ::env(CARAVEL_ROOT) "/home/dinesha/workarea/efabless/MPW-4/caravel_openframe"
+        set ::env(CARAVEL_PDK_ROOT)     "/opt/pdk_mpw4"
+
+        read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/lib/sky130_sram_2kbyte_1rw1r_32x512_8_TT_1p8V_25C.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_sram_macros/lib/sky130_sram_1kbyte_1rw1r_32x256_8_TT_1p8V_25C.lib
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hvl/lib/sky130_fd_sc_hvl__tt_025C_3v30.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hvl/lib/sky130_fd_sc_hvl__tt_025C_3v30_lv1v80.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_gpiov2_tt_tt_025C_1v80_3v30.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_ground_hvc_wpad_tt_025C_1v80_3v30_3v30.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_ground_lvc_wpad_tt_025C_1v80_3v30.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_ground_lvc_wpad_tt_100C_1v80_3v30.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_power_lvc_wpad_tt_025C_1v80_3v30_3v30.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_xres4v2_tt_tt_025C_1v80_3v30.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lib/sky130_ef_io__gpiov2_pad_tt_tt_025C_1v80_3v30.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lib/sky130_ef_io__vdda_hvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssa_hvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped3_pad_tt_025C_1v80_3v30.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped3_pad_tt_025C_1v80_3v30_3v30.lib	
+	read_liberty $::env(CARAVEL_PDK_ROOT)/sky130A/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped_pad_tt_025C_1v80_3v30.lib	
+	read_verilog $::env(CARAVEL_ROOT)/mgmt_core_wrapper/verilog/gl/mgmt_core.v	
+	read_verilog $::env(CARAVEL_ROOT)/mgmt_core_wrapper/verilog/gl/DFFRAM.v	
+	read_verilog $::env(CARAVEL_ROOT)/mgmt_core_wrapper/verilog/gl/mgmt_core_wrapper.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/caravel_clocking.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/digital_pll.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/housekeeping.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/gpio_logic_high.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/gpio_control_block.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/gpio_defaults_block.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/gpio_defaults_block_0403.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/gpio_defaults_block_1803.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/mgmt_protect_hv.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/mprj_logic_high.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/mprj2_logic_high.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/mgmt_protect.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/user_id_programming.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/xres_buf.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/spare_logic_block.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/chip_io.v	
+	read_verilog $::env(CARAVEL_ROOT)/verilog/gl/caravel.v	
+
+	# User project netlist
+        read_verilog $::env(USER_ROOT)/verilog/gl/qspim.v
+        read_verilog $::env(USER_ROOT)/verilog/gl/yifive.v  
+        read_verilog $::env(USER_ROOT)/verilog/gl/uart_i2cm_usb_spi.v
+        read_verilog $::env(USER_ROOT)/verilog/gl/wb_host.v  
+        read_verilog $::env(USER_ROOT)/verilog/gl/wb_interconnect.v
+        read_verilog $::env(USER_ROOT)/verilog/gl/pinmux.v
+        read_verilog $::env(USER_ROOT)/verilog/gl/mbist_wrapper.v
+        read_verilog $::env(USER_ROOT)/verilog/gl/user_project_wrapper.v  
+
+
+	link_design caravel	
+
+	read_spef -path soc/DFFRAM_0                        $::env(CARAVEL_ROOT)/mgmt_core_wrapper/spef/DFFRAM.spef	
+	read_spef -path soc/core                            $::env(CARAVEL_ROOT)/mgmt_core_wrapper/spef/mgmt_core.spef	
+	read_spef -path soc                                 $::env(CARAVEL_ROOT)/mgmt_core_wrapper/spef/mgmt_core_wrapper.spef	
+	read_spef -path padframe                            $::env(CARAVEL_ROOT)/spef/chip_io.spef	
+	read_spef -path rstb_level                          $::env(CARAVEL_ROOT)/spef/xres_buf.spef	
+	read_spef -path pll                                 $::env(CARAVEL_ROOT)/spef/digital_pll.spef	
+	read_spef -path housekeeping                        $::env(CARAVEL_ROOT)/spef/housekeeping.spef	
+	read_spef -path mgmt_buffers/powergood_check        $::env(CARAVEL_ROOT)/spef/mgmt_protect_hv.spef	
+	read_spef -path mgmt_buffers/mprj_logic_high_inst   $::env(CARAVEL_ROOT)/spef/mprj_logic_high.spef	
+	read_spef -path mgmt_buffers/mprj2_logic_high_inst  $::env(CARAVEL_ROOT)/spef/mprj2_logic_high.spef	
+	read_spef -path clocking                            $::env(CARAVEL_ROOT)/spef/caravel_clocking.spef
+	read_spef -path mgmt_buffers                        $::env(CARAVEL_ROOT)/spef/mgmt_protect.spef	
+	read_spef -path \gpio_control_bidir_1[0]            $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_bidir_1[1]            $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_bidir_2[1]            $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_bidir_2[2]            $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1[0]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1[10]              $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1[1]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1[2]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1[3]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1[4]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1[5]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1[6]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1[7]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1[8]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1[9]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1a[0]              $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1a[1]              $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1a[2]              $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1a[3]              $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1a[4]              $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_1a[5]              $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[0]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[10]              $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[11]              $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[12]              $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[13]              $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[14]              $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[15]              $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[1]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[2]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[3]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[4]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[5]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[6]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[7]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[8]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path \gpio_control_in_2[9]               $::env(CARAVEL_ROOT)/spef/gpio_control_block.spef	
+	read_spef -path gpio_defaults_block_0               $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_1803.spef	
+	read_spef -path gpio_defaults_block_1               $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_1803.spef	
+	read_spef -path gpio_defaults_block_2               $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef	
+	read_spef -path gpio_defaults_block_3               $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef	
+	read_spef -path gpio_defaults_block_4               $::env(CARAVEL_ROOT)/spef/gpio_defaults_block_0403.spef	
+	read_spef -path gpio_defaults_block_5               $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_6               $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_7               $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_8               $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_9               $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_10              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_11              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_12              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_13              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_14              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_15              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_16              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_17              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_18              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_19              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_20              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_21              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_22              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_23              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_24              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_25              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_26              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_27              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_28              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_29              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_30              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_31              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_32              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_33              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_34              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_35              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_36              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+	read_spef -path gpio_defaults_block_37              $::env(CARAVEL_ROOT)/spef/gpio_defaults_block.spef	
+
+	## User Project Spef
+        read_spef -path mprj/u_mbist                       $::env(USER_ROOT)/spef/mbist_wrapper.spef
+
+        read_spef -path mprj/u_riscv_top         $::env(USER_ROOT)/spef/ycr1_top_wb.spef
+        read_spef -path mprj/u_pinmux            $::env(USER_ROOT)/spef/pinmux.spef
+        read_spef -path mprj/u_qspi_master       $::env(USER_ROOT)/spef/qspim_top.spef
+        read_spef -path mprj/u_uart_i2c_usb_spi  $::env(USER_ROOT)/spef/uart_i2c_usb_spi_top.spef
+        read_spef -path mprj/u_wb_host           $::env(USER_ROOT)/spef/wb_host.spef
+        read_spef -path mprj/u_intercon          $::env(USER_ROOT)/spef/wb_interconnect.spef
+        read_spef -path mprj                     $::env(USER_ROOT)/spef/user_project_wrapper.spef  
+
+
+	read_sdc -echo ./sdc/caravel.sdc	
+	check_setup  -verbose >  unconstraints.rpt
+	report_checks -path_delay min -fields {slew cap input nets fanout} -format full_clock_expanded -group_count 50	
+	report_checks -path_delay max -fields {slew cap input nets fanout} -format full_clock_expanded -group_count 50	
+	report_worst_slack -max 	
+	report_worst_slack -min 	
+	report_checks -path_delay min -fields {slew cap input nets fanout} -format full_clock_expanded -slack_max 0.18 -group_count 10	
+	report_check_types -max_slew -max_capacitance -max_fanout -violators  > slew.cap.fanout.vio.rpt
+
+	echo "Wishbone Interface Timing.................." > wb.max.rpt
+	echo "Wishbone Interface Timing.................." > wb.min.rpt
+	set wb_port [get_pins {mprj/wbs_adr_i[*]}]
+	set wb_port [concat $wb_port [get_pins {mprj/wbs_cyc_i}]]
+	set wb_port [concat $wb_port [get_pins {mprj/wbs_dat_i[*]}]]
+	set wb_port [concat $wb_port [get_pins {mprj/wbs_sel_i[*]}]]
+	set wb_port [concat $wb_port [get_pins {mprj/wbs_stb_i}]]
+	set wb_port [concat $wb_port [get_pins {mprj/wbs_we_i}]]
+	set wb_port [concat $wb_port [get_pins {mprj/wbs_ack_o}]]
+	set wb_port [concat $wb_port [get_pins {mprj/wbs_dat_o[*]}]]
+	foreach pin $wb_port {
+	   echo "Wishbone Interface Timing for : [get_full_name $pin]"  >> wb.max.rpt
+           report_checks -path_delay max -fields {slew cap input nets fanout} -through $pin  >> wb.max.rpt 
+        }
+	foreach pin $wb_port {
+	   echo "Wishbone Interface Timing for [get_full_name $pin]" >> wb.min.rpt
+           report_checks -path_delay min -fields {slew cap input nets fanout} -through $pin  >> wb.min.rpt
+        }
+        
diff --git a/sta/scripts/or_write_verilog.tcl b/sta/scripts/or_write_verilog.tcl
new file mode 100644
index 0000000..e24c97e
--- /dev/null
+++ b/sta/scripts/or_write_verilog.tcl
@@ -0,0 +1,30 @@
+# 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.
+
+set ::env(MERGED_LEF_UNPADDED) "../lef/merged_unpadded.lef"
+set ::env(INPUT_DEF) "../def/$::env(DESIGN_NAME).def"
+set ::env(SAVE_NETLIST) "netlist/$::env(DESIGN_NAME).v"
+
+
+if {[catch {read_lef $::env(MERGED_LEF_UNPADDED)} errmsg]} {
+    puts stderr $errmsg
+    exit 1
+}
+
+if {[catch {read_def $::env(INPUT_DEF)} errmsg]} {
+    puts stderr $errmsg
+    exit 1
+}
+
+#write_verilog -include_pwr_gnd $::env(SAVE_POWER_NETLIST)
+write_verilog $::env(SAVE_NETLIST)
+
diff --git a/sta/scripts/sta.tcl b/sta/scripts/sta.tcl
new file mode 100644
index 0000000..acfab88
--- /dev/null
+++ b/sta/scripts/sta.tcl
@@ -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: Modified by Dinesh Annayya <dinesha@opencores.org>
+
+set ::env(LIB_FASTEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ff_n40C_1v95.lib"
+set ::env(LIB_TYPICAL) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib"
+set ::env(LIB_SLOWEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ss_100C_1v60.lib"
+set ::env(DESIGN_NAME) "user_project_wrapper"
+set ::env(BASE_SDC_FILE) "base.sdc"
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8"
+set ::env(SYNTH_DRIVING_CELL_PIN) "Y"
+set ::env(SYNTH_CAP_LOAD) "17.65"
+set ::env(WIRE_RC_LAYER) "met1"
+
+#To disable empty filler cell black box get created
+#set link_make_black_boxes 0
+
+
+set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um
+define_corners wc bc tt
+read_liberty -corner bc $::env(LIB_FASTEST)
+read_liberty -corner wc $::env(LIB_SLOWEST)
+read_liberty -corner tt $::env(LIB_TYPICAL)
+
+read_lib  -corner tt   ../lib/sky130_sram_2kbyte_1rw1r_32x512_8_TT_1p8V_25C.lib
+
+read_verilog netlist/qspim.v
+read_verilog netlist/syntacore.v  
+read_verilog netlist/uart_i2cm_usb_spi.v
+read_verilog netlist/wb_host.v  
+read_verilog netlist/wb_interconnect.v
+read_verilog netlist/pinmux.v
+read_verilog netlist/sar_adc.v
+read_verilog ../verilog/gl/user_project_wrapper.v  
+
+link_design  $::env(DESIGN_NAME)
+
+
+read_spef -path u_riscv_top         ../spef/scr1_top_wb.spef
+read_spef -path u_pinmux            ../spef/pinmux.spef
+read_spef -path u_qspi_master       ../spef/qspim_top.spef
+read_spef -path u_uart_i2c_usb_spi  ../spef/uart_i2c_usb_spi_top.spef
+read_spef -path u_wb_host           ../spef/wb_host.spef
+read_spef -path u_intercon          ../spef/wb_interconnect.spef
+read_spef                           ../spef/user_project_wrapper.spef  
+
+
+read_sdc -echo $::env(BASE_SDC_FILE)
+
+# check for missing constraints
+check_setup  -verbose > reports/unconstraints.rpt
+
+set_operating_conditions -analysis_type single
+# Propgate the clock
+set_propagated_clock [all_clocks]
+
+report_tns
+report_wns
+#report_power 
+#
+echo "################ CORNER : WC (MAX) TIMING Report ###################"                                              > reports/timing_ss_max.rpt
+report_checks -unique -slack_max -0.0 -path_delay max -group_count 100          -corner wc  -format full_clock_expanded >> reports/timing_ss_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  wbm_clk_i   -corner wc  -format full_clock_expanded >> reports/timing_ss_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  wbs_clk_i   -corner wc  -format full_clock_expanded >> reports/timing_ss_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  cpu_clk     -corner wc  -format full_clock_expanded >> reports/timing_ss_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  rtc_clk     -corner wc  -format full_clock_expanded >> reports/timing_ss_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  line_clk    -corner wc  -format full_clock_expanded >> reports/timing_ss_max.rpt
+report_checks                         -path_delay max                           -corner wc                              >> reports/timing_ss_max.rpt
+
+echo "################ CORNER : WC (MIN) TIMING Report ###################"                                              > reports/timing_ss_min.rpt
+report_checks -unique -slack_max -0.0 -path_delay min -group_count 100          -corner wc  -format full_clock_expanded >> reports/timing_ss_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  wbm_clk_i   -corner wc  -format full_clock_expanded >> reports/timing_ss_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  wbs_clk_i   -corner wc  -format full_clock_expanded >> reports/timing_ss_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  cpu_clk     -corner wc  -format full_clock_expanded >> reports/timing_ss_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  rtc_clk     -corner wc  -format full_clock_expanded >> reports/timing_ss_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  line_clk    -corner wc  -format full_clock_expanded >> reports/timing_ss_min.rpt
+report_checks                         -path_delay min                           -corner wc                              >> reports/timing_ss_min.rpt
+
+echo "################ CORNER : BC (MAX) TIMING Report ###################"                                              > reports/timing_ff_max.rpt
+report_checks -unique -slack_max -0.0 -path_delay max -group_count 100          -corner bc  -format full_clock_expanded >> reports/timing_ff_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  wbm_clk_i   -corner bc  -format full_clock_expanded >> reports/timing_ff_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  wbs_clk_i   -corner bc  -format full_clock_expanded >> reports/timing_ff_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  cpu_clk     -corner bc  -format full_clock_expanded >> reports/timing_ff_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  rtc_clk     -corner bc  -format full_clock_expanded >> reports/timing_ff_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  line_clk    -corner bc  -format full_clock_expanded >> reports/timing_ff_max.rpt
+report_checks                         -path_delay max                           -corner bc                              >> reports/timing_ff_max.rpt
+
+echo "################ CORNER : BC (MIN) TIMING Report ###################"                                              > reports/timing_ff_min.rpt
+report_checks -unique -slack_max -0.0 -path_delay min -group_count 100          -corner bc  -format full_clock_expanded >> reports/timing_ff_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  wbm_clk_i   -corner bc  -format full_clock_expanded >> reports/timing_ff_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  wbs_clk_i   -corner bc  -format full_clock_expanded >> reports/timing_ff_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  cpu_clk     -corner bc  -format full_clock_expanded >> reports/timing_ff_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  rtc_clk     -corner bc  -format full_clock_expanded >> reports/timing_ff_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  line_clk    -corner bc  -format full_clock_expanded >> reports/timing_ff_min.rpt
+report_checks                         -path_delay min                           -corner bc                              >> reports/timing_ff_min.rpt
+
+
+echo "################ CORNER : TT (MAX) TIMING Report ###################"                                              > reports/timing_tt_max.rpt
+report_checks -unique -slack_max -0.0 -path_delay max -group_count 100          -corner tt  -format full_clock_expanded >> reports/timing_tt_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  wbm_clk_i   -corner tt  -format full_clock_expanded >> reports/timing_tt_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  wbs_clk_i   -corner tt  -format full_clock_expanded >> reports/timing_tt_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  cpu_clk     -corner tt  -format full_clock_expanded >> reports/timing_tt_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  rtc_clk     -corner tt  -format full_clock_expanded >> reports/timing_tt_max.rpt
+report_checks -group_count 100        -path_delay max  -path_group  line_clk    -corner tt  -format full_clock_expanded >> reports/timing_tt_max.rpt
+report_checks                         -path_delay max                           -corner tt                              >> reports/timing_tt_max.rpt
+
+echo "################ CORNER : TT (MIN) TIMING Report ###################"                                              > reports/timing_tt_min.rpt
+report_checks -unique -slack_max -0.0 -path_delay min -group_count 100          -corner tt  -format full_clock_expanded >> reports/timing_tt_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  wbm_clk_i   -corner tt  -format full_clock_expanded >> reports/timing_tt_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  wbs_clk_i   -corner tt  -format full_clock_expanded >> reports/timing_tt_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  cpu_clk     -corner tt  -format full_clock_expanded >> reports/timing_tt_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  rtc_clk     -corner tt  -format full_clock_expanded >> reports/timing_tt_min.rpt
+report_checks -group_count 100        -path_delay min  -path_group  line_clk    -corner tt  -format full_clock_expanded >> reports/timing_tt_min.rpt
+report_checks                         -path_delay min                           -corner tt                              >> reports/timing_tt_min.rpt
+
+
+report_checks -path_delay min_max 
+
+#exit
diff --git a/sta/sdc/caravel.sdc b/sta/sdc/caravel.sdc
new file mode 100644
index 0000000..711014a
--- /dev/null
+++ b/sta/sdc/caravel.sdc
@@ -0,0 +1,255 @@
+set ::env(IO_PCT) "0.2"
+set ::env(SYNTH_MAX_FANOUT) "5"
+set ::env(SYNTH_CAP_LOAD) "1"
+set ::env(SYNTH_TIMING_DERATE) 0.05
+set ::env(SYNTH_CLOCK_SETUP_UNCERTAINITY) 0.25
+set ::env(SYNTH_CLOCK_HOLD_UNCERTAINITY) 0.25
+set ::env(SYNTH_CLOCK_TRANSITION) 0.15
+
+## MASTER CLOCKS
+create_clock [get_ports {"clock"} ] -name "clock"  -period 25
+create_clock [get_pins clocking/user_clk ] -name "user_clk2"  -period 25
+#create_clock [get_pins  housekeeping/_8847_/X ] -name "csclk"  -period 25
+#create_clock [get_pins  clocking/pll_clk ] -name "pll_clk"  -period 25
+#create_clock [get_pins  clocking/pll_clk90 ] -name "pll_clk90"  -period 25
+
+create_generated_clock -name wb_clk -add -source [get_ports {clock}] -master_clock [get_clocks clock] -divide_by 1 -comment {Wishbone User Clock} [get_pins mprj/wb_clk_i]
+create_clock -name wbs_clk_i   -period 15.0000  [get_pins {mprj/u_wb_host/wbs_clk_out}]
+create_clock -name cpu_ref_clk -period 10.0000  [get_pins {mprj/u_wb_host/u_cpu_ref_sel.u_mux/X}]
+create_clock -name cpu_clk     -period 20.0000  [get_pins {mprj/u_wb_host/cpu_clk}]
+create_clock -name rtc_clk     -period 50.0000  [get_pins {mprj/u_wb_host/rtc_clk}]
+create_clock -name usb_clk     -period 20.0000  [get_pins {mprj/u_wb_host/usb_clk}]
+create_clock -name uarts_clk   -period 100.0000 [get_pins {mprj/u_uart_i2c_usb_spi/u_uart_core.u_lineclk_buf.u_mux/X}]
+create_clock -name uartm_clk   -period 100.0000 [get_pins {mprj/u_wb_host/u_uart2wb.u_core.u_uart_clk.u_mux/X}]
+
+create_generated_clock -name mem_clk0 -add -source [get_pins {mprj/u_wb_host/wbs_clk_out}] -master_clock [get_clocks wbs_clk_i] -divide_by 1 -comment {memory Clock} [get_pins mprj/u_mbist/u_mbist.mem_no[0].u_mem_sel.u_mem_clk_sel.u_mux/X]
+create_generated_clock -name mem_clk1 -add -source [get_pins {mprj/u_wb_host/wbs_clk_out}] -master_clock [get_clocks wbs_clk_i] -divide_by 1 -comment {memory Clock} [get_pins mprj/u_mbist/u_mbist.mem_no[1].u_mem_sel.u_mem_clk_sel.u_mux/X]
+create_generated_clock -name mem_clk2 -add -source [get_pins {mprj/u_wb_host/wbs_clk_out}] -master_clock [get_clocks wbs_clk_i] -divide_by 1 -comment {memory Clock} [get_pins mprj/u_mbist/u_mbist.mem_no[2].u_mem_sel.u_mem_clk_sel.u_mux/X]
+create_generated_clock -name mem_clk3 -add -source [get_pins {mprj/u_wb_host/wbs_clk_out}] -master_clock [get_clocks wbs_clk_i] -divide_by 1 -comment {memory Clock} [get_pins mprj/u_mbist/u_mbist.mem_no[3].u_mem_sel.u_mem_clk_sel.u_mux/X]
+
+## Case analysis
+
+set_case_analysis 0 [get_pins {mprj/u_intercon/cfg_cska_wi[0]}]
+set_case_analysis 0 [get_pins {mprj/u_intercon/cfg_cska_wi[1]}]
+set_case_analysis 0 [get_pins {mprj/u_intercon/cfg_cska_wi[2]}]
+set_case_analysis 1 [get_pins {mprj/u_intercon/cfg_cska_wi[3]}]
+
+set_case_analysis 0 [get_pins {mprj/u_pinmux/cfg_cska_pinmux[0]}]
+set_case_analysis 0 [get_pins {mprj/u_pinmux/cfg_cska_pinmux[1]}]
+set_case_analysis 0 [get_pins {mprj/u_pinmux/cfg_cska_pinmux[2]}]
+set_case_analysis 1 [get_pins {mprj/u_pinmux/cfg_cska_pinmux[3]}]
+
+set_case_analysis 0 [get_pins {mprj/u_qspi_master/cfg_cska_sp_co[0]}]
+set_case_analysis 0 [get_pins {mprj/u_qspi_master/cfg_cska_sp_co[1]}]
+set_case_analysis 0 [get_pins {mprj/u_qspi_master/cfg_cska_sp_co[2]}]
+set_case_analysis 0 [get_pins {mprj/u_qspi_master/cfg_cska_sp_co[3]}]
+
+set_case_analysis 0 [get_pins {mprj/u_qspi_master/cfg_cska_spi[0]}]
+set_case_analysis 0 [get_pins {mprj/u_qspi_master/cfg_cska_spi[1]}]
+set_case_analysis 0 [get_pins {mprj/u_qspi_master/cfg_cska_spi[2]}]
+set_case_analysis 1 [get_pins {mprj/u_qspi_master/cfg_cska_spi[3]}]
+
+set_case_analysis 0 [get_pins {mprj/u_riscv_top/cfg_cska_riscv[0]}]
+set_case_analysis 0 [get_pins {mprj/u_riscv_top/cfg_cska_riscv[1]}]
+set_case_analysis 0 [get_pins {mprj/u_riscv_top/cfg_cska_riscv[2]}]
+set_case_analysis 1 [get_pins {mprj/u_riscv_top/cfg_cska_riscv[3]}]
+
+set_case_analysis 1 [get_pins {mprj/u_wb_host/cfg_cska_wh[0]}]
+set_case_analysis 0 [get_pins {mprj/u_wb_host/cfg_cska_wh[1]}]
+set_case_analysis 0 [get_pins {mprj/u_wb_host/cfg_cska_wh[2]}]
+set_case_analysis 1 [get_pins {mprj/u_wb_host/cfg_cska_wh[3]}]
+
+set_case_analysis 1 [get_pins {mprj/u_uart_i2c_usb_spi/cfg_cska_uart[0]}]
+set_case_analysis 1 [get_pins {mprj/u_uart_i2c_usb_spi/cfg_cska_uart[1]}]
+set_case_analysis 1 [get_pins {mprj/u_uart_i2c_usb_spi/cfg_cska_uart[2]}]
+set_case_analysis 0 [get_pins {mprj/u_uart_i2c_usb_spi/cfg_cska_uart[3]}]
+
+set_case_analysis 0 [get_pins {mprj/u_mbist/cfg_cska_mbist[0]}]
+set_case_analysis 0 [get_pins {mprj/u_mbist/cfg_cska_mbist[1]}]
+set_case_analysis 0 [get_pins {mprj/u_mbist/cfg_cska_mbist[2]}]
+set_case_analysis 1 [get_pins {mprj/u_mbist/cfg_cska_mbist[3]}]
+
+
+#disable clock gating check at static clock select pins
+set_false_path -through [get_pins mprj/u_wb_host/u_wbs_clk_sel.u_mux/S]
+
+set_propagated_clock [all_clocks]
+
+set_clock_groups -name async_clock -asynchronous \
+ -group [get_clocks {clock wb_clk mem_clk0 mem_clk1 mem_clk2 mem_clk3}]\
+ -group [get_clocks {user_clk2}]\
+ -group [get_clocks {wbs_clk_i}]\
+ -group [get_clocks {cpu_clk}]\
+ -group [get_clocks {cpu_ref_clk}]\
+ -group [get_clocks {rtc_clk}]\
+ -group [get_clocks {usb_clk}]\
+ -group [get_clocks {uarts_clk}]\
+ -group [get_clocks {uartm_clk}]\
+ -comment {Async Clock group}
+
+## INPUT/OUTPUT DELAYS
+set input_delay_value 1
+set output_delay_value [expr 25 * $::env(IO_PCT)]
+puts "\[INFO\]: Setting output delay to: $output_delay_value"
+puts "\[INFO\]: Setting input delay to: $input_delay_value"
+
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {gpio}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[0]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[1]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[2]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[3]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[4]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[5]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[6]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[7]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[8]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[9]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[10]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[11]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[12]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[13]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[14]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[15]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[16]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[17]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[18]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[19]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[20]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[21]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[22]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[23]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[24]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[25]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[26]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[27]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[28]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[29]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[30]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[31]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[32]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[33]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[34]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[35]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[36]}]
+set_input_delay $input_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {mprj_io[37]}]
+
+set_output_delay $output_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {flash_csb}]
+set_output_delay $output_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {flash_clk}]
+set_output_delay $output_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {flash_io0}]
+set_output_delay $output_delay_value  -clock [get_clocks {clock}] -add_delay [get_ports {flash_io1}]
+
+set_max_fanout $::env(SYNTH_MAX_FANOUT) [current_design]
+
+## Set system monitoring mux select to zero so that the clock/user_clk monitoring is disabled 
+set_case_analysis 0 [get_pins housekeeping/_4449_/S]
+set_case_analysis 0 [get_pins housekeeping/_4450_/S]
+
+## FALSE PATHS (ASYNCHRONOUS INPUTS)
+set_false_path -from [get_ports {resetb}]
+set_false_path -from [get_ports mprj_io[*]]
+set_false_path -from [get_ports gpio]
+
+## User Project static signals
+set_false_path -through [get_pins mprj/u_pinmux/bist_en]
+
+# TODO set this as parameter
+set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0]
+puts "\[INFO\]: Setting load to: $cap_load"
+set_load  $cap_load [all_outputs]
+
+puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %"
+set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
+set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}]
+
+puts "\[INFO\]: Setting clock setup uncertainity to: $::env(SYNTH_CLOCK_SETUP_UNCERTAINITY)"
+puts "\[INFO\]: Setting clock hold uncertainity to: $::env(SYNTH_CLOCK_HOLD_UNCERTAINITY)"
+set_clock_uncertainty -setup $::env(SYNTH_CLOCK_SETUP_UNCERTAINITY) [all_clocks]
+set_clock_uncertainty -hold $::env(SYNTH_CLOCK_HOLD_UNCERTAINITY) [all_clocks]
+
+
+#set_output_delay -max 5.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_adr_i[*]}]
+#set_output_delay -max 5.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_cyc_i}]
+#set_output_delay -max 5.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_i[*]}]
+#set_output_delay -max 5.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_sel_i[*]}]
+#set_output_delay -max 5.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_stb_i}]
+#set_output_delay -max 5.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_we_i}]
+#
+#set_output_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_adr_i[*]}]
+#set_output_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_cyc_i}]
+#set_output_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_i[*]}]
+#set_output_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_sel_i[*]}]
+#set_output_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_stb_i}]
+#set_output_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_we_i}]
+#
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_ack_o}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[0]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[10]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[11]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[12]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[13]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[14]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[15]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[16]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[17]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[18]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[19]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[1]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[20]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[21]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[22]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[23]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[24]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[25]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[26]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[27]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[28]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[29]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[2]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[30]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[31]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[3]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[4]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[5]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[6]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[7]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[8]}]
+#set_input_delay -max 4.5000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[9]}]
+#
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_ack_o}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[0]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[10]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[11]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[12]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[13]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[14]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[15]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[16]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[17]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[18]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[19]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[1]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[20]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[21]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[22]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[23]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[24]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[25]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[26]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[27]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[28]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[29]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[2]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[30]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[31]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[3]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[4]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[5]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[6]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[7]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[8]}]
+#set_input_delay -min 1.0000 -clock [get_clocks {wb_clk}] -add_delay [get_pins {mprj/wbs_dat_o[9]}]
+
+
+
+puts "\[INFO\]: Setting clock transition to: $::env(SYNTH_CLOCK_TRANSITION)"
+set_clock_transition $::env(SYNTH_CLOCK_TRANSITION) [get_clocks {clock}]
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
+